하지만
Design Pattern
- SOLID 를 지키기위해 만든 Pattern (아주 정확한 이유가 있음)
- 따라서 두루뭉실하게 아는 것 보다는 구체적으로 알아야 함
변경의 이유가 단 하나여야 함
함수가 변하는 이유는 하나여야 함
# process 는 순서대로 함수를 호출하는 것이 목적
# 따라서 함수를 여러 개를 사용한다고 해서 SRP 를 지키지 않는 것은 아니다
def process():
step1()
step2()
step3()
[풀이]
Actor
SRP 를 시키면
응집성 (coherence)
이 늘어남
+) Coupling
: A가 변할때 B도 변해야 논리적으로 맞을 때
+)
논리적 응집
: 코드 응집성물리적 응집
: file tree 같은 것개방 폐쇄 원칙
def a():
return 100; # 이걸 1000 으로 고치면?
[상황]
아키텍처가 훌륭하다면 변경되는 코드는 없어야 함
OCP 는 과연 지켜질 수 있는 걸까?
- Class 는 Class 끼리 서로 사용하고 있는데..?
- 우리는 라이브러리도 사용하고 있는데..?
의존성
을 가지면 변경할 수 밖에 없음모든 것에 적용하자는 것이 아님 -> 내가 지켜야 할 곳에 적용하자
Financial Repor Interactor
는 의존성이 없기 때문에 OCP 를 사용할 수 있음A.caculate()
를 쓰려면 B.calculate()
기능이 있어야 함대체
라고 했지 동일
하다고는 하지 않음다형성
[다형성 구현 방법]
interface
구현 class상속
: 자식 클래스도, 부모클래스도 동일한 함수가 있기 때문에 똑같은 메시지에 대해서 서로 다른 응답이 가능LSP
: interface 가 아닌 상속 으로 구현Type System
한정으로 추상화를 어떻게 할지 적어놓은 규칙class Person():
def eat():
print('eat')
class Student(Person):
def eat(): # Student 로 Person 의 Class 를 대체할 수 없음
pass
interface Warrier{
def attack(){}
def defense(){}
def run(){}
def walk(){}
}
class Student(Warrier){ # 학생인데 전쟁 하면 안대여..
def attack(){}
def defense(){}
def run(){} # 실제로 학생이 필요한 것
def walk(){} # 실제로 학생이 필요한 것
}
interface Warrier{
def attack(){}
def defense(){}
def run(){}
def walk(){}
}
interface Person{
def run(){}
def walk(){}
}
class Student(Person){
def run(){}
def walk(){}
}
의존성을 지키기 위한 도구
변화하기 쉬운 것에 의존하지 말아라
완벽하게 절대 지킬 수 없음
class NiceService():
Nice()
class TossService():
Toss()
class KakaoService():
Kakao()
class Nice()
class Toss()
class Kakao()
이렇게 하지 말고
class NiceService():
PGFactory().create('nice')
class PGFactory():
def create(pg_type):
if pg_type == 'nice':
return Nice()
class Nice()
class Toss()
class Kakao()
이렇게 하면 import 가 통일됨
객체 생성 방식을 강하게 제약