챕터 2-4: 객체지향적 설계

언리얼 거토
|2025. 1. 3. 20:43

1. 객체지향 설계의 중요성

  • 오픈소스 이해를 돕고 학습 효율 증가
  • 구현 시간 단축 및 유지보수 용이
  • 기능 변경에 유연함

2. 응집도(Cohesion)

  • 정의: 클래스 내 모듈들이 얼마나 관련있는지
  • 높은 응집도: 관련된 기능만 포함
  • 낮은 응집도: 무관한 기능 섞임

예시: 높은 응집도

class PizzaDelivery:
    def calculate_route(self):
        # 배달 경로 계산
        pass

    def estimate_time(self):
        # 배달 예상 시간 측정
        pass

    def respond_to_customer(self):
        # 고객 문의 대응
        pass

3. 결합도(Coupling)

  • 정의: 모듈 간 의존성 정도
  • 낮은 결합도: 변경이 다른 모듈에 영향 없음
  • 높은 결합도: 변경 시 다수의 모듈 수정 필요

예시: 낮은 결합도

class PaymentProcessor:
    def process_payment(self, payment_method):
        # 결제 처리 (의존성 최소화)
        payment_method.pay()

class CreditCard:
    def pay(self):
        # 카드 결제
        print("Paying with Credit Card")

processor = PaymentProcessor()
processor.process_payment(CreditCard())

4. SOLID 원칙

  • SRP: 하나의 클래스는 하나의 책임만
  • OCP: 확장에는 열림, 변경에는 닫힘
  • LSP: 부모 클래스는 자식으로 대체 가능
  • ISP: 클라이언트에 맞는 인터페이스 분리
  • DIP: 추상화에 의존, 구체화 피하기

4.1 SRP (단일 책임 원칙)

  • 정의: 클래스는 하나의 책임만 가져야 함.
  • 이유: 변경 이유를 하나로 제한해 유지보수 용이.

예시:

class Order:
    def add_item(self, item):
        # 주문 항목 추가
        pass

class Invoice:
    def generate_invoice(self, order):
        # 송장 생성
        pass

2. OCP (개방-폐쇄 원칙)

  • 정의: 확장에는 열려 있고, 변경에는 닫혀 있어야 함.
  • 이유: 기존 코드를 수정하지 않고 새로운 기능 추가 가능.

예시:

class Discount:
    def apply(self, price):
        return price

class SeasonalDiscount(Discount):
    def apply(self, price):
        return price * 0.9  # 10% 할인

class Cart:
    def __init__(self, discount: Discount):
        self.discount = discount

    def calculate_total(self, price):
        return self.discount.apply(price)

cart = Cart(SeasonalDiscount())
print(cart.calculate_total(100))

3. LSP (리스코프 치환 원칙)

  • 정의: 자식 클래스는 부모 클래스를 대체할 수 있어야 함.
  • 이유: 상속 구조에서 일관성 유지.

예시:

class Bird:
    def fly(self):
        print("I can fly!")

class Sparrow(Bird):
    pass

def let_bird_fly(bird: Bird):
    bird.fly()

sparrow = Sparrow()
let_bird_fly(sparrow)  # Sparrow도 Bird처럼 행동

4. ISP (인터페이스 분리 원칙)

  • 정의: 클라이언트에 불필요한 인터페이스를 강요하지 말아야 함.
  • 이유: 특정 요구에 맞춘 인터페이스 분리로 코드 유연성 증가.

예시:

class Printer:
    def print_document(self):
        pass

class Scanner:
    def scan_document(self):
        pass

class MultiFunctionDevice(Printer, Scanner):
    def print_document(self):
        print("Printing document")

    def scan_document(self):
        print("Scanning document")

5. DIP (의존성 역전 원칙)

  • 정의: 고수준 모듈은 저수준 모듈에 의존하지 않고, 둘 다 추상화에 의존해야 함.
  • 이유: 변경에 강한 구조 설계 가능.

예시:

class NotificationService:
    def send(self, message):
        pass

class EmailService(NotificationService):
    def send(self, message):
        print(f"Email sent: {message}")

class NotificationManager:
    def __init__(self, service: NotificationService):
        self.service = service

    def notify(self, message):
        self.service.send(message)

email_service = EmailService()
manager = NotificationManager(email_service)
manager.notify("Hello, Dependency Inversion!")

'TIL > C++' 카테고리의 다른 글

챕터 3-2: Unreal Engine 기본 개념  (2) 2025.01.07
챕터 3-1: 디자인 패턴  (0) 2025.01.06
챕터 2-3 : STL 기초  (1) 2025.01.02
챕터 2-2 : 템플릿  (1) 2024.12.31
챕터 2-1 : 자원 관리하기  (0) 2024.12.30