당니의 개발자 스토리
좋은 객체 지향 설계의 5가지 원칙의 적용 본문
좋은 객체 지향 설계의 5가지 원칙의 적용
이번 시간에는 좋은 객체지향 설계 5가지 원칙이 어떻게 적용되어 있는지 정리를 해드리겠습니다.

여기서는 크게 3가지 SRP, DIP, OCP가 적용된 걸 볼 수가 있죠.
SRP, 단일 책임 원칙부터 말씀 드리면,

한 클래스는 하나의 책임만 가져야 한다고 합니다.
클라이언트 객체인 OrderServiceImpl 구현 객체는 너무 많은 책임을 가지고 있었어요. 직접 구현 객체를 생성을 하고 연결하고 실행하는, 굉장히 다양한 책임을 가지고 있었단 말이에요. 그런데 SRP, 단일 책임 원칙을 따르면서 관심사를 분리를 한 거에요.
분리하고 나서, 구현 객체를 생성하고 연결하는 책임은 이제 AppConfig 라는 애가 담당하도록 다 넘겨 버렸어요.
그리고 클라이언트 객체는 딱 실행만 하는 책임만 담당하도록 설계를 변경을 했습니다.
그 다음에 DIP, 의존관계 역전 원칙인데요.

프로그래머는 추상화에 의존해야지 구체화에 의존하면 안된다. 의존성 주입(Dependency Injection)은 이 원칙을 따르는 방법 중에 하나다.
우리가 객체에 대한 의존관계를 어떻게 했습니까? 외부에서, 즉 AppConfig에서 생성해서 넣어 줬죠. 그랬더니 엄청난 유연성이 발휘가 되잖아요. 그렇게 하려면 클라이언트 코드에서 객체가 추상화에 의존을 해야 이게 가능한 거예요. 주문 서비스가 추상화에 의존하기 때문에 이게 가능한 거예요. 구체에 의존하고 있었으면 아예 불가능했겠죠.
그래서 이 의존성 주입은 DIP 원칙을 따르는 방법 중 하나라는 의미가 추상화에만 의존을 하고, 구체적인 클래스에 대한 선택을 외부에서 넣어줘야 된다는 뜻입니다. 왜냐면 의존관계 주입을 할 때, 만약 DIP를 위반하면, 클라이언트 코드가 구체적인 클래스에 의존해서 외부에서 주입해주지 못하잖아요.
그래서 의존관계 주입이 DIP를 따르는 방법 중 하나라는 겁니다.
자 그래서 새로운 할인 정책을 개발하고, 적용하려고 하니 클라이언트 코드도 함께 변경해야 했습니다. 왜냐하면 기존 클라이언트 코드 OrderServiceImpl는 DIP를 지키면서 마치 DiscountPolicy 추상화 인터페이스에 의존하는 것 같았지만, 사실은 FixDiscountPolicy 구체화 구현 클래스에도 함께 의존을 했었죠.
그래서 클라이언트 코드가 DiscountPolicy 추상화 인터페이스에만 의존하도록 코드를 변경을 했습니다. 하지만 NullPointException이 났었죠? 클라이언트 코드는 인터페이스만으로는 아무것도 할 수가 없어요.
그래서 AppConfig 라는 전체 애플리케이션을 구성하는 객체가 클라이언트 코드 대신, FixedDiscountPolish 라는 객체 인스턴스를 생성해서 클라이언트 코드에 이 의존관계를 주입을 해줬다는 거죠.
그랬더니 DIP 원칙을 따르면서 이 문제도 해결이 됐습니다.
그 다음에 OCP, 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야된다.

다형성을 사용하고 클라이언트가 DIP를 잘 지키면, OCP가 적용될 수 있는 가능성이 열리는 거예요. 그래서 우리는 애플리케이션을 사용 영역과 구성 영역으로 나눴습니다.
AppConfig가 의존 관계를 FixedDiscountPolicy에서 RateDiscountPolicy로 변경을 하더라도, AppConfig 라는 애가 변경을 해서 클라이언트 코드에 주입을 하기 때문에, 클라이언트 코드는 어떤 코드도 변경하지 않아도 됐어요.
그래서 결과적으로 소프트웨어 요소를 새롭게 확장을 해도, 이 사용 영역 자체에 대한 변경은 완전히 닫혀 있었죠. 변경이 닫혀 있다는 말은 변경할 필요가 없다는 거예요. 그냥 외부에서 바꿔서 의존관계 주입하면 끝나는 거예요.
외부의 AppConfig 같은 전체적인 애플리케이션을 구성하는 코드만 변경이 되는 거지, 사용 영역이나 클라이언트 코드들은 전혀 변경할 필요가 없었습니다.
이게 바로 사용 영역은 닫혀있다는 거고, 그래서 소프트웨어 요소를 새롭게 확장을 해도 사용 영역의 변경은 닫혀있다는 거죠.
이렇게 해서 좋은 객체 지향 설계 5가지 원칙에 대해서도 한번 정리를 해봤습니다.
다음 시간에는 IoC, DI, 그리고 컨테이너, 이젠 정말 스프링과 관련된 용어들이 하나씩 설명을 해드리겠습니다.
'스프링 > 스프링 핵심 원리 - 기본편' 카테고리의 다른 글
| 스프링으로 전환하기 (0) | 2024.01.19 |
|---|---|
| IoC, DI, 그리고 컨테이너 (0) | 2024.01.19 |
| 전체 흐름 정리 (0) | 2024.01.18 |
| 새로운 구조와 할인 정책 적용 (0) | 2024.01.18 |
| AppConfig 리팩터링 (0) | 2024.01.18 |