스프링 이전 SRP, OCP, DIP 위반 문제 해결

박찬우·2023년 12월 8일

스프링

목록 보기
4/88
post-thumbnail

SRP(Single responsibility principle) 단일 책임 원칙

  • 한 클래스는 하나의 책임만 가져야 한다
  • 하나의 챔익이라는 것은 모호하다
    • 클 수 있고 작을 수 있다
    • 문맥과 상황에 따라 다르다
  • 중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 적으면 단일 책임원칙을 잘따른 것

OCP(Open/closed principle) 개방-폐쇄 원칙

  • 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다
  • 다형성을 활용
  • 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현

DIP(Dependenct inversion principle) 의존관계 역전 원칙

  • 프로그래머는 추상화에 의존해야지 구체화에 의존하면 안된다. 의존성 주입은 이 원칙을 따르는 방법중 하나
  • 쉽게 이야기해서 구현 클래스에 의존하지 말고 인터페이스에 의존하라는 뜻
  • 역할에 의존하게 해야 한다는 것 객체 세상도 클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다. 구현체에 의존하게 되면 변경이 아주 어려워짐

SRP, OCP, DIP 위반 예시

private final DiscountPolicy discountPolicy = new FixDiscountPolicy();

FixDiscountPolicy, RateDiscountPolicy는 DiscountPolicy 인터페이스의 구현체들이다.
현재 할인 방법이 금액제할인이라고 가정하였을 때 할인방법을 할인율로 변경한다면 아래와 같이 바꿔주면 된다.

//private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();

OrderServiceImpl은 인터페이스에 의존하기 때문에 DIP를 위반하지 않는 것 같지만 RateDiscountPolicy 구현체에 의존적이게 되면서 DIP를 위반했고 이 때문에 코드변경이 일어나서 OCP도 위반하게 된다.
그리고 객체의 생성, 연결, 실행등 다양한 책입을 가지면서 SRP를 위반했다.

관심사의 분리

  • 객체를 생성하고 연결하는 역할과 실행하는 역할이 명확히 분리되는 것
  • 이제 SRP, OCP, DIP 위반 문제를 AppConfig를 통하여 해결해야 한다.
  • AppConfig : 애플리케이션의 전체 동작 방식을 구성하기 위해 구현 객체를 생성 하고 연결하는 책임을 가지는 별도의 설정 클래스
  • AppConfig 구현
public class AppConfig {
    public OrderService orderService() {
        return new OrderServiceImpl(new RateDiscountPolicy());
    }
}
  • Main 메소드
public static void main(String[] args) {
    AppConfig appConfig = new AppConfig();
    OrderService orderService = appConfig.orderService();
}
  • OrderServiceImpl
private final DiscountPolicy discountPolicy;

    public OrderService orderService() {
        return new OrderServiceImpl(discountPolicy());
    }

    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }
}

  • 클라이언트의 입장에서는 의존관계를 마치 외부에서 넣어주는 것 같다 해서 DI(Dependency Injection) 우리말로 의존관계 주입 또는 의존성 주입이라 한다.
  • 만들 때 역할과 구현클래스를 한눈에 들어오게하고 중복코드가 없도록 개발해야한다.
  • AppConfig를 통하여 인터페이스만 의존하고 구현체에 의존하지 않게되어 DIP를 지켰고 언제든지 할인을 변경할 수 있게 되고 그로 인한 코드 변경도 없기 때문에 OCP까지 지킨게된다.
    그리고 OrderServiceImpl이 실행만 담당하게 되므로 SRP도 지켜졌다.
profile
진짜 개발자가 되어보자

0개의 댓글