[파이썬] 객체 지향 설계와 SOLID 원칙

소개

객체 지향 프로그래밍은 현대 소프트웨어 개발에서 매우 중요한 개념입니다. 이러한 접근 방식은 코드의 재사용성, 유지 보수성, 확장성을 향상시키는 데 도움이 됩니다. 객체 지향 설계의 핵심 개념 중 하나는 SOLID 원칙입니다. 이 원칙은 유연하고 견고한 코드를 작성하는 데 도움이 되며, 좋은 객체 지향 설계의 지침을 제공합니다.

SOLID 원칙

SOLID 원칙은 다음과 같이 다섯 가지 원칙으로 구성됩니다.

1. 단일 책임 원칙 (Single Responsibility Principle)

class Customer:
    def __init__(self, name, email):
        self.name = name
        self.email = email

    def send_email(self, message):
        # 이메일 보내는 로직
        pass

class Order:
    def __init__(self, customer, product, quantity):
        self.customer = customer
        self.product = product
        self.quantity = quantity

    def calculate_total_price(self):
        # 가격 계산 로직
        pass

위의 예시에서 Customer 클래스는 소비자의 정보와 관련된 책임을 가지고 있고, Order 클래스는 주문과 관련된 책임을 가지고 있습니다. 따라서 각 클래스는 단일한 책임을 가지게 됩니다.

2. 개방-폐쇄 원칙 (Open-Closed Principle)

class AreaCalculator:
    def calculate(self, shapes):
        total_area = 0
        for shape in shapes:
            total_area += shape.area()
        return total_area

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Circle:
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius * self.radius

위의 예시에서 AreaCalculator 클래스는 다양한 도형의 면적을 계산하는 기능을 제공합니다. 새로운 도형이 추가될 때 기존 코드를 수정하지 않고 shape 클래스를 확장하여 면적을 계산하도록 할 수 있습니다.

3. 리스코프 치환 원칙 (Liskov Substitution Principle)

class Animal:
    def make_sound(self):
        pass

class Dog(Animal):
    def make_sound(self):
        print("Bark!")

class Cat(Animal):
    def make_sound(self):
        print("Meow!")

def make_animal_sound(animal):
    animal.make_sound()

위의 예시에서 make_animal_sound 함수는 Animal 클래스를 인자로 받아서 동물의 소리를 출력합니다. Dog 클래스와 Cat 클래스는 Animal 클래스를 상속받고 있으므로 make_animal_sound 함수에서 동일하게 사용할 수 있습니다.

4. 인터페이스 분리 원칙 (Interface Segregation Principle)

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2 * (self.width + self.height)

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius * self.radius

    def perimeter(self):
        return 2 * 3.14 * self.radius

위의 예시에서 Shape 인터페이스는 areaperimeter 메서드를 정의합니다. RectangleCircle 클래스는 Shape 인터페이스를 구현하여 필요한 기능을 제공합니다.

5. 의존성 역전 원칙 (Dependency Inversion Principle)

from abc import ABC, abstractmethod

class PaymentGateway(ABC):
    @abstractmethod
    def process_payment(self, amount):
        pass

class PaymentService:
    def __init__(self, payment_gateway):
        self.payment_gateway = payment_gateway

    def make_payment(self, amount):
        self.payment_gateway.process_payment(amount)

위의 예시에서 PaymentService 클래스는 PaymentGateway 인터페이스에 의존하여 결제를 처리합니다. 이를 통해 구체적인 결제 게이트웨이 구현에 종속되지 않고, 결제 로직을 유연하게 변경할 수 있습니다.

결론

SOLID 원칙은 객체 지향 설계를 향상시키기 위한 지침을 제공합니다. 이 원칙을 따르면 코드의 유지 보수성과 재사용성이 향상됩니다. SOLID 원칙을 이해하고 적용하는 것은 현대 소프트웨어 개발에서 필수적인 역량입니다.