728x90

SRP (Single Responsibility Principle) : 단일 책임 원칙

하나의 클래스는 하나의 책임만 가져야 함

## 단일 책임 원칙을 준수하지 않은 예시
class User:
    def __init__(self, username, email):
        self.username = username
        self.email = email

    def save_to_database(self):
        # 데이터베이스에 저장하는 작업

    def send_email(self, message):
        # 이메일 보내는 작업

 

## 단일책임원칙을 준수하도록 수정
class User:
    def __init__(self, username, email):
        self.username = username
        self.email = email

class UserRepository:
    def save_to_database(self, user):
        # 데이터베이스에 저장하는 작업

class EmailService:
    def send_email(self, user, message):
        # 이메일 보내는 작업

OCP (Open-Closed Principle) : 개방 폐쇄 원칙

소프트웨어의 구성 요소(클래스, 모듈, 함수 등)는 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 함

## 개방/폐쇄 원칙을 위반한 예시
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

class AreaCalculator:
    def calculate_area(self, rectangle):
        return rectangle.width * rectangle.height

 

## 개방/폐쇄 원칙을 준수하도록 수정
# 추상 클래스를 이용한 확장 가능한 디자인
from abc import ABC, abstractmethod

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

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

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

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

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

LSP (Liskov Substitution Principle) : 리스 코프 치환 원칙

자식클래스는 언제나 부모클래스를 대체할 수 있어야 함

## 리스코프 치환 원칙을 위반한 예시
class Bird:
    def fly(self):
        pass

class Penguin(Bird):
    def fly(self):
        raise Exception("Penguins can't fly!")

def make_bird_fly(bird):
    bird.fly()

 

## 리스코프 치환 원칙을 준수하도록 수정
# 추상 클래스를 사용하여 공통된 인터페이스 정의
from abc import ABC, abstractmethod

class Bird(ABC):
    @abstractmethod
    def fly(self):
        pass

class Sparrow(Bird):
    def fly(self):
        print("Sparrow is flying")

class Penguin(Bird):
    def fly(self):
        print("Penguin can't fly")

def make_bird_fly(bird):
    bird.fly()

ISP (Interface Segragation Principle) : 인터페이스 분리 원칙

클라이언트는 자신이 사용하지 않는 메서드에 의존해서는 안됨

## 인터페이스 분리 원칙을 위반한 예시
class Worker:
    def work(self):
        pass

    def eat(self):
        pass

class SuperWorker(Worker):
    def work(self):
        pass

    def eat(self):
        pass

 

## 인터페이스 분리 원칙을 준수하도록 수정
# 인터페이스를 분리하여 클라이언트가 필요한 메서드만 사용
class Workable(ABC):
    @abstractmethod
    def work(self):
        pass

class Eatable(ABC):
    @abstractmethod
    def eat(self):
        pass

class Worker(Workable, Eatable):
    def work(self):
        pass

    def eat(self):
        pass

class SuperWorker(Workable, Eatable):
    def work(self):
        pass

    def eat(self):
        pass

DIP (Dependency Inversion Principle) : 의존 관계 역전 원칙

고수준 모듈은 저수준 모듈에 의존해서는 안되며, 둘 모두 추상화에 의존해야 함

추상화된 것에 의존하면 구체적인 구현 사항이 변경되어도 영향을 받지 않게 됨

## 의존 역전 원칙을 위반한 예시
class LightBulb:
    def turn_on(self):
        print("LightBulb: On")

    def turn_off(self):
        print("LightBulb: Off")

class Switch:
    def __init__(self, bulb):
        self.bulb = bulb

    def operate(self):
        self.bulb.turn_on()

bulb = LightBulb()
switch = Switch(bulb)
switch.operate()

 

## 의존 역전 원칙을 준수하도록 수정
# 추상화를 통해 의존성을 역전시킴
from abc import ABC, abstractmethod

class Switchable(ABC):
    @abstractmethod
    def turn_on(self):
        pass

    @abstractmethod
    def turn_off(self):
        pass

class LightBulb(Switchable):
    def turn_on(self):
        print("LightBulb: On")

    def turn_off(self):
        print("LightBulb: Off")

class Switch:
    def __init__(self, device):
        self.device = device

    def operate(self):
        self.device.turn_on()

bulb = LightBulb()
switch = Switch(bulb)
switch.operate()
728x90

+ Recent posts