본문 바로가기

카테고리 없음

[Spring] 생성자 주입을 통해 SOLID의 OCP, DIP를 개선하기

이전 OCP, DIP의 문제점

이전 글의 OCP와 DIP는 생성자 주입을 통해 조금 더 세세한 분리를 통해 개선할 수 있다. 아래는 OCP와 DIP의 개선 코드이다.

OCP

예를 들어, 아래의 코드의 경우, OCP를 준수하기 위해선 변경에는 닫혀 있어야 한다. 하지만, 'SimpleCaculatorV1'에서 'SimpleCaculatorV2'로 변경할 때 '공학계산기' class 안에서 코드의 변경이 발생한다.

interface SimpleCaculator {
    public void 더하기();
}

class SimpleCaculatorV1 implements SimpleCaculator{
    public void 더하기(){}
}

class SimpleCaculatorV2 implements SimpleCaculator{
    public void 더하기(){}
}

class 공학계산기 {
    // SimpleCaculator simpleCaculator = new SimpleCaculatorV1();
    SimpleCaculator simpleCaculator = new SimpleCaculatorV2();

    public void 공학계산(){
        simpleCaculator.더하기();
    } 
}

DIP

아래의 코드 역시, '공학계산기' class는 simpleCacculator 인터페이스와 SimpleCaclulatorV1 클래스를 의존하고 있다. 이부분 역시 DI를 통해 SimpleCaclulatorV1을 의존하지 않는 방향으로 개선이 가능할 수 있다.

interface SimpleCaculator {
    public void 더하기();
}

interface 공학기능 {
    public void 공학계산();
    public void 공학더하기();
}

class SimpleCaculatorV1 implements SimpleCaculator{
    public void 더하기(){}
}

class 공학계산기 implements 공학기능{
    SimpleCaculator simpleCaculator = new SimpleCaculatorV1();
	
    public void 공학계산(){}
    public void 공학더하기(){}
}

OCP와 DIP 개선

아래와 코드와 같이 생성자 주입을 통해 OCP와 DIP를 개선할 수 있다. 

Config 생성자

원하는 구현체를 반환해주는 Config 클래스를 작성한다. 이후, 기존 '공학계산기' 클래스는 Config를 통해 생성자 주입을 받아 인터페이스와 구현체를 매핑한다.

class config {
    public SimpleCaculatorV1 SimpleCaculatorV1() {
        return new SimpleCaculatorV1();
    }
}

 공학계산기 클래스

class 공학계산기 {
    // SimpleCaculator simpleCaculator = new SimpleCaculatorV1();
    private final SimpleCaculator simpleCaculator;
    
    public 공학계산기(SimpleCaculator simpleCaculator) { 
        this.simpleCaculator = simpleCaculator; 
    }

    public void 더하기(){}
    public void 공학계산(){}
    public void 공학더하기(){}
}

위처럼 구현체들을 관리해주는 별도의 클래스를 이용해 필요한 구현체들을 생성자 주입해줄 수 있다.

이렇게 별도로 별도로 관리할 경우, OCP와 DIP를 잘 지키도록 개선할 수 있다.

  1. OCP의 '변경에는 닫혀 있어야 한다' : 이후, SimpleCalculator의 구현체를 변경해야할 경우, Config를 수정해주면 된다. 따라서 공학계산기는 수정할 필요가 없으며, OCP를 잘 준수하고 있다.
  2.  DIP의 '구현체가 아닌, 인터페이스에 의존해야한다' : 이제 공학계산기 내부에는 구현체가 없다. 따라서, 공학계산기는 구현체가 아닌 인터페이스에만 의존하고 있으므로, DIP를 잘 준수하고 있다.