파이썬/클래스와 객체 지향

[객체 지향 프로그래밍 4개의 기둥] 다형성

Data Jun 2025. 3. 18. 11:15

**다형성(Polymorphism)**은 같은 이름의 메서드가 여러 개의 다른 동작을 할 수 있도록 만드는 개념입니다.
즉, "같은 인터페이스(메서드명)"를 유지하면서, 서로 다른 방식으로 구현이 가능하게 하는 것입니다.

Python에서는 메서드 오버라이딩(Method Overriding)과 인터페이스(Abstract Class)를 활용하여 다형성을 구현할 수 있습니다.

 

다형성이 적용된 extract_email_info() 메서드의 의미

**"extract_email_info() 메서드를 다른 방식으로 확장 가능하게 함"**이라는 말은 이 메서드를 다양한 방식으로 구현할 수 있도록 만들었다는 의미입니다. 즉, extract_email_info()의 기본 구조를 유지하면서도 다른 클래스에서 새로운 방식으로 구현할 수 있도록 만들었다는 뜻입니다.

 

 

다형성을 적용한 예제

 

기존 extract_email_info() 메서드는 이메일 데이터에서 발신자, 수신자, 날짜, 제목 등을 추출하는 기능을 수행합니다.

하지만 이메일의 형식이 다를 수도 있기 때문에, 다양한 방식으로 정보를 추출할 수 있도록 유연하게 설계해야 합니다.
즉, 이 메서드를 다른 방식으로 확장할 수 있도록 만든 것이 다형성의 핵심입니다.

 

 

다형성 없이 단일 방식으로 구현된 경우

class MailProcessor:
    def extract_email_info(self, email_text: str):
        """이메일에서 보낸 사람, 받은 사람, 날짜, 제목을 추출"""
        lines = email_text.split("\n")
        sender = lines[0].split(":")[1].strip()
        recipient = lines[1].split(":")[1].strip()
        date = lines[2].split(":")[1].strip()
        subject = lines[3].split(":")[1].strip()
        return sender, recipient, date, subject

문제점:

  • 이 메서드는 특정한 이메일 형식에서만 동작함.
  • 이메일 형식이 바뀌면 이 메서드를 수정해야 함.
  • 다른 방식으로 이메일을 파싱할 수 있는 확장성이 없음.

 

다형성을 적용하여 다양한 방식으로 확장 가능하도록 개선

 

extract_email_info() 메서드를 부모 클래스에서 정의하고, 자식 클래스에서 **다른 방식으로 구현(오버라이딩)**할 수 있도록 만들어봅시다.

from abc import ABC, abstractmethod

class BaseMailProcessor(ABC):
    @abstractmethod
    def extract_email_info(self, email_text: str):
        """이메일에서 주요 정보(발신자, 수신자, 날짜, 제목) 추출"""
        pass

여기서 extract_email_info() 메서드를 abstractmethod로 선언
즉, 이 메서드는 반드시 구현해야 하지만, 구현 방식은 자유롭게 확장 가능

 

다양한 방식으로 extract_email_info()를 확장하는 자식 클래스

이제 이메일 형식이 다를 경우에도, 서로 다른 방식으로 정보를 추출할 수 있도록 각각 다른 클래스로 구현할 수 있습니다.

일반적인 텍스트 이메일에서 정보 추출하는 경우

class TextMailProcessor(BaseMailProcessor):
    def extract_email_info(self, email_text: str):
        """텍스트 기반 이메일을 파싱하는 방식"""
        lines = email_text.split("\n")
        sender = lines[0].split(":")[1].strip()
        recipient = lines[1].split(":")[1].strip()
        date = lines[2].split(":")[1].strip()
        subject = lines[3].split(":")[1].strip()
        return sender, recipient, date, subject

기본적인 텍스트 기반 이메일을 처리하는 방식

 

 

HTML 기반 이메일에서 정보를 추출하는 경우

from bs4 import BeautifulSoup

class HTMLMailProcessor(BaseMailProcessor):
    def extract_email_info(self, email_text: str):
        """HTML 이메일을 파싱하는 방식"""
        soup = BeautifulSoup(email_text, "html.parser")
        sender = soup.find("span", class_="sender").text.strip()
        recipient = soup.find("span", class_="recipient").text.strip()
        date = soup.find("span", class_="date").text.strip()
        subject = soup.find("span", class_="subject").text.strip()
        return sender, recipient, date, subject

HTML 기반의 이메일을 처리하는 방식
BeautifulSoup을 사용하여 이메일 정보를 추출하도록 구현

 

 

다형성의 핵심: 같은 메서드명(extract_email_info)을 유지하면서도 서로 다른 방식으로 구현

text_processor = TextMailProcessor()
html_processor = HTMLMailProcessor()

text_email = """From: John Doe\nTo: Alice\nDate: 2025-03-18\nSubject: Meeting Reminder"""
html_email = """<html><body><span class='sender'>John Doe</span><span class='recipient'>Alice</span>
                <span class='date'>2025-03-18</span><span class='subject'>Meeting Reminder</span></body></html>"""

print(text_processor.extract_email_info(text_email))  
# ('John Doe', 'Alice', '2025-03-18', 'Meeting Reminder')

print(html_processor.extract_email_info(html_email))  
# ('John Doe', 'Alice', '2025-03-18', 'Meeting Reminder')

같은 extract_email_info() 메서드를 호출하지만, 내부 동작은 다르게 구현됨!
이메일 형식이 달라도 같은 방식으로 호출 가능 → 다형성(Polymorphism) 적용!

 

 

결론: extract_email_info()를 다형성으로 확장 가능하게 만든 이유

  1. 같은 메서드명을 유지하면서도, 서로 다른 방식으로 구현할 수 있도록 만들었기 때문!
    • 이메일이 텍스트 기반인지, HTML 기반인지에 따라 다른 파싱 방법을 적용 가능
    • 이메일 형식이 추가될 경우 새로운 클래스를 만들어 오버라이딩할 수 있음
  2. 코드 수정 없이 새로운 방식으로 확장할 수 있음!
    • 기존 extract_email_info()를 수정할 필요 없이 새로운 방식으로 추가 가능
    • 텍스트 이메일 → HTML 이메일 → JSON 기반 이메일 등 다양한 포맷을 지원 가능
  3. 유지보수성과 확장성이 높아짐!
    • 새로운 방식으로 이메일을 파싱하고 싶다면, 기존 코드를 건드리지 않고 새로운 클래스를 만들기만 하면 됨
    • 기존 코드 수정 없이 기능 추가 가능 → 유지보수성이 좋아짐!