프로그래밍 언어/Java

객체지향의 원칙 OCP 와 DIP에 대해

happy_life 2022. 4. 5. 10:44

객체지향의 원칙 OCP 와 DIP에 대해 

 

*OCP 개방-폐쇄 원칙

  • 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야 한다.
  • 다형성을 통해 가능하다.
  • 인터페이스를 구현한 새로운 클래스를 하나 만들어 새로운 기능을 구현
  • 지금까지 배운 역할과 구현의 분리

 

DIP 의존관계 역전 원칙

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


공부는 인풋이 있으면 반드시 아웃풋이 있어야한다. 구체적인 코드를 구현해보며 알아보자.

 

샘플 코드

 

위의 코드는 OCP 개방 폐쇄 원칙을 만족하는가? -->  NO

 

예를들어 MemoryMemberRepository()가 아니라 DbMemberRepository()를 구현해야할 때 위의 코드를 변경해야합니다. 따라서, OrderService 구현체 내부의 코드를 직접 수정해야하므로 변경에는 닫혀있어야 한다.는 조건을 만족하지 못합니다.


그렇다면  DIP 의존관계 역전 원칙을 만족하는가? -->  NO

물론 왼쪽의 코드를 보면 MemberRepository 라는 interface에 의존한다.

하지만 오른쪽의 new MemoryMemberRepository() 의 구현체 코드가 있으니 구현에도 의존하는 것이다.

따라서 DIP 의존관계 역전 원칙을 만족하지 못한다.

 


문제 해결

 

역할과 구현으로 클래스를 분리 했음에도 불구하고 객체지향의 원칙들을  실질적으로 지키지 못하게 되는 문제점이 있는데 이를 해결하려면 어떻게 해야할까??

 

의존관계 주입Appconfig 클래스를 활용하면 된다.

 

 

OrderServiceImpl Class

기존에 객체를 생성해서 넣어줬던 것과 달리, 인터페이스만을 남겨두고, 생성자를 통해 외부에서 의존관계를 주입시켜줄 수 있는 코드를 작성하였다.

 

AppConfig Class

이제 부터 OrderService의 구현부분은 AppConfig라는 외부에서 관리하게 된다.

기존의 OrderServiceImpl 클래스에서는 어떤 구현체인지를 더이상 신경 쓰지 않아도 된다. 즉, 구현체에 의존하지 않는다. 오직 인터페이스만 남아있을 뿐이다.

 

OrderApp Class(실제 주문 처리 클래스)

주석처럼 구현체를 넣어주지 않고, AppConfig 클래스를 통해 return 값만 넣어주면 우리는 더이상 구현체에 대해 신경쓸 필요가 없게 된다. MemoryMemberRepository()를 넣을지 DbMemberRepository() 를 넣을지 구현체에 대한 고민은 오로지 외부인 AppConfig에서하면 된다.

빨간부분은 AppConfig에서

 

이렇게 객체지향의 OCP 와 DIP에 대해 한계점과 그 해결방안을 중심으로 공부해보았다.