Single responsibility priciple
한 클래스는 하나의 책임만 가져야 합니다.
하나의 책임이라는 것은 모호하다.
-클 수도 있고, 작을 수 있습니다.
-문맥과 상황에 따라 다릅니다.
중요한 기준은 변경입니다. 변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른것입니다.
-Ex) UI 변경, 객체의 생성과 사용을 분리
Open/Closed principle
객체 지향 설계에서 가장 중요한 부분!
소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 합니다.
다형성을 활용해봅니다.
인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현합니다.
역할과 구현의 분리를 생각해봅니다.
MemberService 클라이언트가 구현 클래스를 직접 선택
-MemberRepository m = new MemoryMemberRepository(); //기존 코드
-MemberRepository m = new JdbcMemberRepository(); //변경 코드
구현 객체를 변경하려면 클라이언트 코드를 변경해야 합니다.
분명 다형성을 사용했지만 OCP원칙을 지킬 수 없습니다.
이럴 때는 객체를 생성하고, 연관관계를 맺어주는 별도의 조립, 설정자가 필요합니다.(스프링 컨테이너)
Liskov substitution priciple
Interface segregation principle
Dependency inversion principle
2번째로 중요한 원칙!
프로그래머는 "추상화에 의존해야지, 구체화에 의존하면 안됩니다." 의존성 주입은 이 원칙을 따르는 방법 중 하나입니다.
클라이언트가 구현클래스를 바로보지말고, 인터페이스만 바라보라.
(멤버 서비스가 멤버 레포지토리 인터페이스만 바라보고 jdbc레파지토리,memorymember레파지토리에 대해서는 몰라야 한다는 말입니다.)
쉽게 이야기해서 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻입니다.
앞에서 이야기한 역할(Role)에 의존해야 하는 것과 같습니다.
객체 세상도 클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있습니다.
구현체에 의존하게 되면 변경이 매우 어려워집니다.
역할과 구현을 철저하게 분리하도록 설계 해야합니다. 언제든지 시스템을 갈아끼울수 있게 설계해야합니다.
그런데 OCP에서 설명한 MemberService는 인터페이스에 의존하지만, 구현 클래스도 동시에 의존합니다.
MemberService 클라이언트가 구현 클래스를 직접 선택
MemberRepository m = new MemoryMemberRepository();
DIP 위반