본문 바로가기
아키텍처/클린 아키텍처

클린 아키텍처 - 설계원칙 - DIP

by SSaMKJ 2023. 2. 11.

설계원칙

SOLID

  • SRP: 단일 책임 원칙 Single Responsible Principle
  • OCP: 개방-폐쇄 원칙 Open-Closed Principle
  • LSP: 리스코프 치환 법칙 Liskov Substitution Principle
  • ISP: 인터페이스 분리 원칙 Interface Segregation Principle
  • DIP: 의존성 역전 원칙 Dependency Inversion Principle

DIP

  • 의존성 역전 원칙 Dependency Inversion Principle
  • '유연성이 극대화된 시스템'이란 소스 코드 의존성이 추상(abstraction)에 의존하며 구체(concretion)에는 의존하지 않는 시스템이다.
  • 소프트웨어 시스템이라면 구체적인 많은 장치에 반드시 의존 할 수 밖에 없다.
    • 자바의 String 클래스는 구체 클래스이다. 하지만 String 클래스가 변경될 것에 대해서 걱정하지는 않는다.
    • 우리가 피해야 할 것은 변동성이 큰 구체적인 요소이다.
  • 추상 인터페이스에서 변경이 일어나면 구현체들도 따라서 수정해야 한다. 반대로 구현체에 변경이 생기더라도 추상 인터페이스에 영향을 끼치는 경우는 극히 드믈다.
  • 뛰어난 소프트웨어 설계자와 아키텍트라면 인터페이스의 변동성을 낮추기 위해서 애쓴다.
    • 인터페이스를 변경하지 않고도 구현체에 기능을 추가 할 수 있는 방법을 찾기 위해 노력한다. 이는 소프트웨어 설계의 기본이다.

안정된 소프트웨어 아키텍처란 변동성이 큰 구현체에 의존하는 일은 지양하고, 안정된 추상 인터페이스를 선호하는 아키텍처.


의존성을 낮추기 위한 코딩 실천 법

  • 변동성이 큰 구체 클래스를 참조하지 말라. 추상 인터페이스를 참조하라.
  • 변동성이 큰 구체 클래스로부터 파생하지 말라. 상속은 소스 코드에 존재하는 모든 관계 중에서 가장 강력한 결합을 가진다. software를 hardware로 만들 수 있다. 상속은 아주 신중하게 사용해야 한다.
  • 구체 함수를 오버라이드 하지 말라. 대체로 구체 함수는 소스 코드 의존성을 필요로 한다. 따라서 구체 함수를 오버라이드 하면 이러한 의존성을 제거 할 수 없게 되며, 실제로는 그 의존성을 상속하게 된다. 이러한 의존성을 제거하려면, 차라리 추상 함수로 선언하고 구현체들에서 각자의 용도에 맞게 구현해야 한다.
  • 구체적이며 변동성이 크다면 절대로 그 이름을 언급하지 말라

팩토리

  • 이 규칙들을 준수하려면 변동성이 큰 구체적인 객체는 특별히 주의해서 생성해야 한다. 사실상 모든 언어에서 객체를 생성하려면 해당 객체를 구체적으로 정의한 코드에 대해 소스 코드 의존성이 발생하기 때문이다.
  • 자바 등 대다수의 객체 지향 언어에서 이처럼 바람직하지 못한 의존성을 처리할 때 추상 팩토리 패턴을 사용하곤 한다.

[그림 5-1 의존성을 관리하기 위해 추상 팩토리 패턴을 사용한다.]

  • 곡선은 아키텍처 경계를 뜻한다. 이 곡선은 구체적인 것들로부터 추상적인 것들을 분리한다. 소스 코드 의존성은 해당 곡선과 교차할 때 모두 한 방향, 즉 추상적인 쪽으로 향한다.
    • 하지만 결국 Application 영역에서 Service Factory Impl을 주입 받아야 한다. Concrete Impl을 주입 받는 것과 어떻게 다를까? 변동성이 큰 구체 클래스가 아니기 때문이다.
  • 곡선은 시스템을 두 가지 컴포넌트로 분리한다. 하나는 추상 컴포넌트이며, 다른 하나는 구체 컴포넌트다.
    • 추상 컴포넌트: 애플리케이션의 모든 고수준 업무 규칙을 포함한다.
    • 구체 컴포넌트: 업무 규칙을 다루기 위해 필요한 모든 세부사항을 포함한다.
  • 제어흐름은 소스 코드 의존성과는 정반대 방향으로 곡선을 가로지른다는 점에 주목하자. 소스 코드 의존성은 제어흐름과는 반대 방향으로 역전된다. 이러한 이유로 이 원칙을 의존성 역전이라고 부른다.

 

remind - SOLID

  • SRP: 단일 책임 원칙 Single Responsible Principle
    • 각 소프트웨어 모듈은 변경의 이유가 하나, 단 하나여야만 한다.
  • OCP: 개방-폐쇄 원칙 Open-Closed Principle
    • 기존 코드를 수정하기보다는 반드시 새로운 코드를 추가하는 방식으로 시스템의 행위를 변경할 수 있도록 설계해야만 소프트웨어 시스템을 쉽게 변경할 수 있다는 것이 이 원칙의 요지이다.
  • LSP: 리스코프 치환 법칙 Liskov Substitution Principle
    • 하위 타입에 관한 법칙. 상호 대체 가능한 구성요소를 이용해 소프트웨어 시스템을 만들 수 있으려면, 이들 구성요소는 반드시 서로 치환 가능해야 한다는 계약을 반드시 지켜야 한다.
  • ISP: 인터페이스 분리 원칙 Interface Segregation Principle
    • 소프트웨어 설계자는 사용하지 않은 것에 의존하지 않아야 한다.
  • DIP: 의존성 역전 원칙 Dependency Inversion Principle
    • 고수준 정책을 구현하는 코드는 저수준 세부사항을 구현하는 코드에 절대로 의존해서는 안 된다. 대신 세부사항이 정책에 의존해야 한다.

 

클린 아키첵처 전체 보기 

클린 아키텍처란? https://blog.kjslab.com/199
클린 아키텍처 - 설계원칙 - SRP https://blog.kjslab.com/200 
클린 아키텍처 - 설계원칙 - OCP https://blog.kjslab.com/201 
클린 아키텍처 - 설계원칙 - LSP https://blog.kjslab.com/202 
클린 아키텍처 - 설계원칙 - ISP https://blog.kjslab.com/203  
클린 아키텍처 - 설계원칙 - DIP & SOLID 요약 https://blog.kjslab.com/204 
클린 아키텍처 - 컴포넌트 https://blog.kjslab.com/205 
클린 아키텍처 - 컴포넌트 결합 - ADP https://blog.kjslab.com/206   
클린 아키텍처 - 컴포넌트 결합 - SDP https://blog.kjslab.com/207
클린 아키텍처 - 컴포넌트 결합 - SAP & 결론 https://blog.kjslab.com/208 

댓글