의존역전원칙에 해당하는 글 2

DDD. DIP 의존 역전 원칙

DDD|2019. 5. 6. 13:56

서비스가 특정 시스템에 의존성을 가지게 되면 서비스 자체만으로 테스트 수행이 어렵고 종속되는 시스템에 따라 서비스의 코드가 지속적으로 변경될 여지가 있다.

이를 해결하기 위해서 DIP개념을 사용할 수 있다.

DIP

제품의 할인율을 구하는 서비스가 있다고 가정해보자. 이 서비스는 의미 있는 단일 기능을 제공하는 고수준 모듈이다. 그리고 이 고수준 모듈의 기능 구현을 위해서 현재 가격과 할인 %등을 구하는 여러 하위 기능이 필요하다. 이때 이 기능들은 하위 기능을 실제로 구현한 저수준 모듈이라고 한다. 

고수준 모듈이 저수준 모듈 여러개의 의존성을 가지게 된다면 테스트와 여러 기능 수정 때마다 변경이 생긴다. 그럼 이를 해결하기위해서는 저수준 모듈이 고수준 모듈을 의존하게 만들어야 하는데 이를 위해서는 추상화한 인터페이스를 이용해서 구현해야한다.

예를 들어서 여러 이벤트마다 할인된 가격을 계산해주는 기능이 포함된 인터페이스 PriceCalculatorI를 정의한다.

package chapter2;

/** * ddd 
* * *@author *wedul 
* *@since *2019-05-06 
**/
public interface PriceCalculatorI {
    int calculaterPrice(int price);
}

그리고 특가 할인 계산하는 SpecialPriceCalculator와 이를 이용하여 가격을 계산하는 고수준 모듈을 구한다.

package chapter2;

/**
 * ddd
 *
 * @author wedul
 * @since 2019-05-06
 **/
public class SpecialPriceCalculator implements PriceCalculatorI {

    @Override
    public int calculaterPrice(int price) {
        return (int) (price * 0.1);
    }
}
package chapter2;

/**
 * ddd
 *
 * @author wedul
 * @since 2019-05-06
 **/
public class ProductPrice {

    private PriceCalculatorI priceCalculator;

    public ProductPrice(PriceCalculatorI priceCalculatorI) {
        this.priceCalculator = priceCalculator;
    }

    public int calculatorProductPrice(int price) {
        return priceCalculator.calculaterPrice(price);
    }
}

이렇게 되면 상품 가격을 구하는 calculatorProductPrice 고수준 모듈은 더이상 이벤트에 따라 저수준 모듈을 변경해야하는 이슈가 없어진다. 대신 PriceCalculatorI는 고수준 모듈에 속하는 인터페이스이기 때문에 이를 구현한 SpecialPriceCalculator의 경우 저수준 모듈이다.

SpecialPriceCalculator와 같은 저수준 모듈들이 PriceCalculatorI와 같은 고수준 모듈을 의존하게 되므로 DIP가 성립된다. DIP는 Dependency Inversion Principle, 의존 역전 원칙을 의미한다.

 

출처 : DDD Start 도메인 주도 설계 구현과 핵심 개념 익히기 (출판 지앤선, 저자 최범균)

댓글()

프로그래밍 코드 작성 시 주요원칙

단일 책임 원칙 (Single Responsibility Principle) SRP
-> 객체는 오직 하나의 책임만을 가져야한다.
-> 객체에서 책임이라고 한다면 객체의 역할을 의미한다.

좋은 설계란
=> 기본적으로 시스템에 새로운 요구사항이나 변경이 있을 때 가능한 한 영향 받는 부분을 줄여야 한다.

프로그램의 요구사항은 계속해서 변경되기 마련이다.
이를 위해서 항상 변경이 가능하도록 조치가 되어있어야 하며, 이런 시스템이 변화에 잘 적용되도록 설계되어 있는지 확인 하는 것을 회귀 테스트(regression)라고 한다.

개방폐쇄원칙 (Open-Closed principle) OCP 
- 기존의 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계가 되어야 한다.


리스코프 치한원칙 
- 자식클래스는 최소한 자신의 부모 클래스에서 가능한 행위는 수행할 수 있어야한다.
- 자식 클래스와 부모클래스 사이의 행위가 일관성이 있어야 한다.
- is a kind of 관계 사이를 유지하라.

의존 역전 원칙 Dependency Inversion Priciple 
- 의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 거, 거의 변화가 없는 것에 의존하라.
- 아이가 장난감을 가지고 노는 행위자체는 변화하기 어렵지만, 가지고 노는 장난감은 변화가 쉽다.
- 행위를 적는 인터페이스는 변화가 적고, 실채가 있는 구체 클래스는 변하기 쉽다.

인터페이스 분리 원칙 (Interface Segregation Principle)
- 복합기라는 하나의 커다란 인터페이스를 구현한 팩스 클래스가 갑작스러운 복합기 기능의 변경으로 인해 인터페이스가 변경되면 영향을 받을 수 있다. 그러한 이유로 자신이외에 다른 곳에서 크게 사용하지 않는 특징일 경우 별도의 인터페이스로 관리하는 것이 좋다.
- 진짜 변하지 않는 인터페이스를 상속 받아 재 구현한 인터페이스를 이용하여 클래스를 구현하는 방식을 이용하면 된다.
- SRP (단일 책임 원칙)을 생각하면서 인터페이스도 분리를 해야한다.

결론.
하나의 객체의 하나의 역할을. 관련이 없는 것 끼리는 서로 독립시킬 것.
섣부른 상속은 큰 문제를 야기할 수 있다.



'IT 지식 > 소프트웨어 공학' 카테고리의 다른 글

프로그래밍 코드 작성 시 주요원칙  (0) 2018.05.30
피터 코드의 상속 규칙  (0) 2018.05.30

댓글()