728x90
반응형
SMALL

의존성 역전 원칙

Dependency Inversion Principle, DIP

**“고차원 모듈은 저차원 모듈에 의존하면 안 된다. 이 두 모듈 모두 다른 추상화된 것에 의존해야 한다.”“추상화된 것은 구체적인 것에 의존하면 안 된다. 구체적인 것이 추상화된 것에 의존해야 한다.” "자주 변경되는 구체(Concrete) 클래스에 의존하지 마라“ - 로버트 C. 마틴

세부적인 사항은 추상화에 의존해야 합니다.

의존성 역전 원칙을 적용한 대표적 사례로는 이전 OCP 에서 설명했던 JDBC 에서 찾아볼 수 있습니다.

또한 OCP 에서 본 계산기 예제도 마찬가지입니다.

의존성 역전 원칙을 위반한 계산기

원칙 위반 증상

저수준 모듈에서 변경이 발생되면 고수준 모듈에 수정사항이 발생합니다.

public class Calculator {
    private AddOperation addOperation;
    private SubstractOperation substractOperation;
    private MultiplyOperation multiplyOperation;
    private DivideOperation divideOperation;

    public Calculator(AddOperation addOperation, SubstractOperation substractOperation, MultiplyOperation multiplyOperation, DivideOperation divideOperation) {
        this.addOperation = addOperation;
        this.substractOperation = substractOperation;
        this.multiplyOperation = multiplyOperation;
        this.divideOperation = divideOperation;
    }

    public int calculate(String operator, int firstNumber, int secondNumber) {
        int answer = 0;

        if(operator.equals("+")){
            answer = addOperation.operate(firstNumber, secondNumber);
        }else if(operator.equals("-")){
            answer = substractOperation.operate(firstNumber, secondNumber);
        }else if(operator.equals("*")){
            answer = multiplyOperation.operate(firstNumber, secondNumber);
        }else if(operator.equals("/")){
            answer = divideOperation.operate(firstNumber, secondNumber);
        }

        return answer;
    }
}
public class Client {
    public static void main(String[] args) {
        Calculator calculator = new Calculator(
                new AddOperation(),
                new SubstractOperation(),
                new MultiplyOperation(),
                new DivideOperation()
        );

        int firNum = 140;
        int secNum = 60;

        String operator = "+";
        int answer = calculator.calculate(operator, firNum, secNum);
        System.out.println(operator + " answer = " + answer);

        operator = "-";
        answer = calculator.calculate(operator, firNum, secNum);
        System.out.println(operator + " answer = " + answer);

        operator = "*";
        answer = calculator.calculate(operator, firNum, secNum);
        System.out.println(operator + " answer = " + answer);

        operator = "/";
        answer = calculator.calculate(operator, firNum, secNum);
        System.out.println(operator + " answer = " + answer);
    }
}
public class AddOperation {
    public int operate(int firstNumber, int secondNumber){
        return firstNumber + secondNumber;
    }
}
public class SubstractOperation {
    public int operate(int firstNumber, int secondNumber){
        return firstNumber - secondNumber;
    }
}
public class MultiplyOperation {
    public int operate(int firstNumber, int secondNumber){
        return firstNumber * secondNumber;
    }
}
public class DivideOperation {
    public int operate(int firstNumber, int secondNumber){
        return firstNumber / secondNumber;
    }
}

계산기(고수준 모듈)가 개별 연산 클래스(저수준 모듈)을 포함하며 계산 기능을 구현할 때 연산 클래스에 의존하고 있습니다.

원칙 적용 방법

고수준 모듈의 변화되는 부분을 추상화합니다.

저수준 모듈을 추상화에 의존시킵니다.

계산기 클래스에 추상화된 부모 클래스를 포함시킵니다.

연산 클래스는 추상화된 부모 클래스를 상속받아 기능별로 구현합니다.

AbstractOperation : 추상 클래스

operate : 추상 메서드

728x90
반응형
LIST

'개발 > JAVA' 카테고리의 다른 글

열거형  (0) 2023.02.23
생성자와 세터의 차이  (0) 2023.02.10
인터페이스 분리 원칙  (0) 2023.01.27
리스코프 치환 원칙  (0) 2023.01.27
개방-폐쇄 원칙  (0) 2023.01.27

+ Recent posts