OCP 원칙
강의를 수강하지 않았지만 질문 주신 내용을 토대로 답변 남겨봅니다.의존성 주입(DI)이 OCP와 DIP를 지원하는 기술이지만, DI를 사용한다고 해서 원칙들이 지켜지는 것은 아닙니다. OCP와 DIP 원칙을 제대로 적용하기 위해서는 설계에 대한 고민이 필요합니다.MemberRepository를 구체 클래스로 직접 의존할 경우, MemberService는 MemberRepository의 변화에 직접적인 영향을 받게 됩니다. 예를 들어, MemberRepository를 NewMemberRepository로 변경해야 할 때 MemberService의 코드도 함께 수정해야 하는 상황이 발생합니다. 이는 OCP와 DIP 원칙을 위반하게 됩니다.이 문제를 해결하기 위해서는 MemberRepository의 인터페이스(추상화)를 정의하고, MemberService가 이 인터페이스에 의존하도록 설계해야 합니다. 이렇게 하면 MemberService는 MemberRepository의 구체적인 구현에 독립적이 되어, 구현체가 변경되어도 MemberService의 코드를 수정할 필요가 없어집니다.이해를 위해 아래에 구체 클래스 의존과 인터페이스 의존의 예시 코드 남겨봅니다. DIP와 OCP 원칙에 대해 학습해보시고 직접 코드를 작성해보시면 금방 이해하실 수 있을거라고 생각합니다. 구현체 의존 예시 (DIP, OCP 원칙 위반)// OriginMemberRepository 사용 @Service public class MemberService { private OriginMemberRepository memberRepository; // DIP 위반 public void setMemberRepository(OriginMemberRepository memberRepository) { this.memberRepository = memberRepository; } } @Repository public class OriginMemberRepository { public void save(String member) { System.out.println("원래 구현체"); } }// OriginMemberRepository -> NewMemberRepository 변경 @Service public class MemberService { private NewMemberRepository memberRepository; // 코드 변경(OCP 위반) public void setMemberRepository(NewMemberRepository memberRepository) { // 코드 변경(OCP 위반) this.memberRepository = memberRepository; } } @Repository public class OriginMemberRepository { public void save(String member) { System.out.println("원래 구현체"); } } @Repository public class NewMemberRepository { public void save(String member) { System.out.println("새로운 구현체"); } }인터페이스 의존 (DIP, OCP 원칙 준수)// OriginMemberRepository 사용 @Service public class MemberService { private MemberRepository memberRepository; public void setMemberRepository(MemberRepository memberRepository) { this.memberRepository = memberRepository; } } public interface MemberRepository { void save(String member); } @Repository public class OriginalMemberRepository implements MemberRepository { @Override public void save(String member) { System.out.println("원래 구현체"); } }// OriginMemberRepository -> NewMemberRepository 변경 @Service public class MemberService { private MemberRepository memberRepository; // 코드 변경 없음 public void setMemberRepository(MemberRepository memberRepository) { // 코드 변경 없음 this.memberRepository = memberRepository; } } public interface MemberRepository { void save(String member); } @Repository public class OriginalMemberRepository implements MemberRepository { @Override public void save(String member) { System.out.println("원래 구현체"); } } @Repository @Primary public class NewMemberRepository implements MemberRepository { @Override public void save(String member) { System.out.println("새로운 구현체"); } }