(작성중)[object_oriented_programming 0.5편] solid란?(단일 책임 원칙, 개방 - 폐쇄 원칙, 리스코프 치환 법칙, 인터페이스 분리 원칙, 의존성 역전 법칙) 그리고 의존성 주입이란?
27 Jan 2019
Reading time ~2 minutes
단일책임원칙
- 모든 클래스는 단 하나의 역할만 가진다.
개방 폐쇄 법칙
- 객체는 확장 가능성은 열어 두고, 수정 가능성은 닫는다.
- 실제로 하기는 너무나 어렵다.
- 심지어 로버트 마틴 조차 완벽한 닫힘은 쉽지 않으며 오랜 경험에서 비롯된 통찰력이 필요하다고 했다.
리스코프 치환 원칙
- 자식 클래스는 언제나 자신의 부모클래스를 교체할 수 있다는 원칙이다.
- 언제나 업 캐스팅 가능
- 한 객체를 다른 객체가 파생하더라도 그 기본 로직은 변경 되서는 안된다.
- 작성 중인 class가 하는 일과 서브 class가 다르면 안된다는 것.
- 서로 파생 관계가 아니면 적용 x
- 덕 타이핑 역시 파생과 조금 다르지만 이 원칙과 잘 맞는다.
인터페이스 분리 법칙
- 클라이언트가 자신이 이용하지 않는 메서드에 의존하지 않아야 한다는 원칙.
- 자신이 사용하지 않는 기능(인터페이스)에는 영향을 받지 말아야 한다.
- 기능이 많은 인터페이스는 더 작고 응축시켜야 한다는 발상
- 인터페이스 사용부(consumer)를 뚱뚱한 전체가 아니라 아주 작은 인터페이스 하나만 바라보면 된다.
- 물론 모듈 간 연결 폭을 최소화하는 방향으로 가야한다.
Dependency Inversion Principle(의존성 역전 법칙)
- 상위클래스는 하위클래스에 의존해서는 안된다는 법칙.
- 하위클래스가 상위클래스에 의존을 해야지 상위클래스가 하위클래스에 의존하면 안된다.
- 인터페이스와 관련이 있다.
- 로버트 마틴 “상위 수준 모듈은 하위 수준 모듈에 의존해서는 안되며 이 둘은 추상화에 의존해야 한다.”
- 클래스 A가 클래스 B의 서비스가 필요할 때 A는 B를 생성하지 않는다.
- 대신 A 생성자에 건넨 파라미터 하나가 B를 서술하는 인터페이스 역할을 한다.
- 이제 A는 B에 의존하지 않고 자신의 인터페이스만 바라본다.
- A가 생성되면 구체화한 B를 넘겨받는다.
- B역시 인터페이스에 의존한다.
- 리스코프 치환 원칙 덕분에 인터페이스를 만족하는 B의 파생형 버전을 제공할 수 있는 이점이 있다.
- 또 인터페이스는(개방/폐쇄 원칙에도 불구하고) B를 고쳐야 할 경우 하위 버전 호환성을 유지하려면 로직을 계속 갖고 있어야 하는지 일목요연하게 서술한다.
의존성 주입
의존성 역전이 일어나지 않기 위해서 하는 방법중 하나가 제대로 의존성 주입을 하는 것이다.
di는 코드 재사용을 적극적으로 유도 di는 실제 객체보다 주입한 모의 객체에 더 많은 제어권 준다.
이중 한가지라도 yes이면 직접 인스턴스화 하지말고 주입하는 방향
- 객체 또는 의존성 중 어느 하나라도 DB,설정파일, HTTP 등의 외부 자원에 의존?
- 객체 내부에서 발생할지 모를 에러를 테스트에서 고려해야?
- 특정한 방향으로 객체를 작동해야 할 테스트 있나?
- third-party 제공 객체가 아닌 온전히 내 소유 객체?
의존성 주입 프레임워크 동작상황
- 애플리케이션 시작되자 마자 각 injectable명을 확인 후 해당 인젝터블이 지닌 의존성을 지칭하며 순서대로 DI 컨테이너에 등록
- 객체가 필요하면 컨테이너에 요청
- 컨테이너는 일단 요청 받은 객체와 그 의존성을 모두 재귀적으로 인스턴스화하고 필요 객체에 주입
injectable(주입가능한) -> 모든 의존성을 집합적으로 일컫는 말
참고자료
solid 원칙 참고한 곳: https://wkdtjsgur100.github.io/solid-principle/ https://ko.wikipedia.org/wiki/SOLID_(객체_지향_설계)