Spring 핵심 원칙 이해 – 객체 지향 설계

새로운 정책 개발

코드에서 다형성을 잘 사용하는 경우 새 정책을 추가하는 것은 문제가 되지 않습니다.

그러나 새로운 정책의 적용에 문제가 있다.

  • 클라이언트 코드순차 서비스 구현도 변경해야 합니다.
  • 클라이언트는 구현과 인터페이스 모두에 의존합니다 → DIP 위반

관심사의 분리

  • AppConfig는 구현 개체를 만들고 연결하는 역할을 합니다.
  • 앱 구성의 출현으로 더 이상 기존 클라이언트 코드에서 구현을 만들 필요가 없습니다.
  • 결과적으로 클라이언트 개체는 자신의 역할 수행에만 집중하고 권한은 축소됩니다(책임이 명확해짐).

AppConfig 리팩토링

  • 명확한 역할 분리 및 구성 정보 구현
  • 역할이 잘 어울린다
  • 중복 제거

이전 코드

public class OrderServiceImpl implements OrderService {

	// OrderService는 생성(new), 연결, 실행 등 다양한 책임이 있음
	// 인터페이스(DiscountPolicy)뿐만 아니라, 구현체(FixDiscountPolicy)에도 의존관계임
	// 만약 FixDiscountPolicy -> newDiscountPolicy로 변경한다면 FixDiscountPolicy 구현체를 사용하는 모든 코드를 수정해야함
	private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
...
}

리팩토링 코드

public class OrderServiceImpl implements OrderService {
		// 인터페이스에만 의존관계
		private final DiscountPolicy discountPolicy;
		//생성자 추가
		public OrderServiceImpl(DiscountPolicy discountPolicy) {
		        this.discountPolicy = discountPolicy;
		    }
...
}

public class AppConfig {
		// OrderService에 구현체(discountPolicy)를 주입하고 있음
    public OrderService orderService() {
        return new OrderServiceImpl(discountPolicy());
    }
	  
    public DiscountPolicy discountPolicy() {
		// 새로운 정책을 변경해야한다면, 이 부분만 수정하면 됌
//      return new FixDiscountPolicy();
        return new newDiscountPolicy();
    }
}

졸업 증서

  • 앱 구성의 출현으로 사용 영역과 객체 생성 및 구성 영역으로 구분
  • 할인 정책이 변경되더라도 앱 구성. 적용 분야는 변경할 필요가 없습니다.

좋은 객체지향 설계의 5가지 원칙 적용

개인 책임의 SRP 원칙

클래스는 하나의 책임만 가져야 합니다.

  • 기존 클라이언트 개체에는 다음과 같은 다양한 역할과 책임이 있었습니다. B. 구현 개체의 생성, 연결 및 실행.
  • AppConfig를 통한 관심사 분리, 클라이언트 개체는 작업만 담당

DIP 종속성 역전의 원리

프로그래머는 “물화가 아니라 추상화에 의존”해야 합니다. 종속성 주입은 이 원칙을 따르는 한 가지 방법입니다.

  • 새로운 정책을 개발하고 수정하면서 클라이언트 코드도 변경해야 했습니다. (기존 클라이언트 코드도 구체적인 구현 클래스에 의존함)
  • AppConfig는 클라이언트 코드 대신 개체 인스턴스를 만들어 클라이언트 코드에 종속성을 주입하는 DIP 원칙을 따랐습니다.

OKP

소프트웨어 요소는 확장에는 열려 있어야 하지만 수정에는 닫혀 있어야 합니다.

  • 다형성이 사용되고 클라이언트가 DIP를 고수한다면 무한히 확장 가능합니다.
  • 응용 프로그램을 사용 도메인과 구성 도메인으로 나눕니다.
  • 소프트웨어 요소가 새롭게 확장되더라도 사용 영역의 변경은 완료됩니다.