ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Design Pattern] SOLID
    Software Development/Design Pattern 2021. 11. 20. 23:44

    이 원칙들을 지키면 유지보수가 쉬운 코드를 작성할 수 있다.

     

    Single responsibility(SRP)

    모든 함수나 클래스는 하나의 기능을 가져야 한다.

     

    Open-closed principle(OCP)

    확장에 대해서는 열려있고 수정에 대해서는 닫혀 있어야 한다.

    interface, abstract class를 사용하면 된다.

    즉 새로운 기능을 추가할 때는 interface를 써서 필요한 기능을 구현하면 된다.

    그리고 새로운 기능이 추가될 때 마다 클라이언트 코드에서는 수정이 필요없이 interface의 기능에 대해 알고 있으면 된다.

     

    Liskov Substitution(LSP)

    Type A가 있고 Sub Type B, C, D가 있다면 A를 B, C로 바꿔도 상관없다는 것이다.

     

    Interface segregation(LSP)

    인터페이스 분리 원칙이란 큰 인터페이스를 더 작게 나누는 것이 좋다는 것이다.

    제습기와 공기청정기 기능을 같이 가지고 있는 인터페이스를 작성하는 것이 아닌, 개별 인터페이스를 작성하고 필요한 인터페이스를 가져와서 구현하는 것이다.

     

    Dependency inversion(DIP)

    High Level 모듈이 Low Level 모듈에 대한 의존성이 증가하면 코드의 수정과 관리가 어렵기 때문에 이를 해결하는 방식이다.

    Low level class는 abstract class에 대해 의존성을 가지게 하고 High Level Class는 abstract class에 대해 의존성을 가지게 해서 나중에 Low level class가 추가되더라도 수정이 용이하다.

     

    OCP vs DIP

    둘 다 abstraction을 사용하기 때문에 비슷해 보이지만, 이루고자 하는 목적이 다르다.

    OCP: 새로운 기능 확장에 대해서 논의하는 것이다. A뿐만 아니라 B, C, D와 같은 새로운 기능을 추가할 때 interface를 써서 해결한다.

    DIP: 새로운 기능 확장이 아닌 High Level 모듈이 Low Level에 대한 의존성을 갖게 하는 것이 아니기 때문에 수정에 용이하게 된다. A를 B, C로 바꿀 때 편하다.

    OCP는 달성하지만 DIP를 달성하지 못할 수 있다.

    class Car:
    	def __init__(self):
    		self.speed = 0
    		self.velocity = 0
    	def break():
    		self.speed -= self.velocity  
    	def excel():
    		self.speed += self.velocity
    	
    class K3(Car):
    	def __init__(self):
        	self.speed = 0
            self.velocity = 3
    	def break():
    		self.speed -= self.velocity
    	def excel():
    		self.speed += self.velocity
        	
    class K9(Car):
    	def __init__(self):
    		self.speed = 0
    		self.velocity = 30
    	def break():
    		self.speed -= self.velocity
    	def excel():
    		self.speed += self.velocity
            
    class Driver:
    	def __init__(self, car: Car):
    		self.car = car
    
    	def start(self):
    		while True:
    			self.car.excel()
    			if car.__class__.__name__ == 'K9':
    				time.sleep(10)
    			elif car.__class__.__name__ == 'K3':
    				time.sleep(1)

    Driver 클래스는 High Level 클래스로 Low Level 클래스인 Car에 대해 의존성을 가지고 있다.

    K9, K5 Low Level 클래스는 abstact class인 Car에 의존성을 가지고 있다.

    이 코드에서 K3, K7가 와도 Driver 클래스는 Low Level 모듈에 대한 의존성은 없다.

     

    그런데 start의 while 안의 조건문을 보면 확장에 대해서 닫혀있다. 즉, 새로운 Car를 받을 때 마다 if 문을 계속 추가해야 하는 것이다.

    OCP에 만족하지 않는다.

    OCP에 만족하려면 self.velocity를 가지고 분기문 없이 처리할 수 있겠다.

    댓글

Designed by Tistory.