본문 바로가기
DEV/Java

[객체지향설계] SOLID 원칙

by 어쩌다개발 2023. 3. 3.
반응형

SRP : 단일 책임 원칙(Single responsibility principle)

한 클래스는 하나의 책임만 가져야 한다.
하나의 책임이란 말은 모호하다.
판단의 기준은 변경이다.
즉, 변경이 있을 때 파급 효과가 적을수록 단일 책임 원칙을 잘 따른 것이다.
범위를 너무 작게하면 단위가 너무 쪼개져서 문제고, 너무 크게 하면 책임이 커져서 문제다.

 

OCP : 개방-폐쇄 원칙(Open/closed principle)

소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
확장을 하려면 당연히 코드 변경이 필요한데, 이해하기 힘들수 있다.
자주 변하는 기능을 추상화함으로써 기존 코드를 수정하지 않고도 기능을 확장할 수 있어야 한다.

public class MemberService {
    //private MemberRepository memberRepository = new MemoryMemberRespository;
    private MemberReposiory memberRepository = new JdbcMemberRepository;
}

위의 소스를 보면 기존에 DB가 확정되기 전 MemoryMemberRepository를 사용하다가 DB가 확정되고 나서 JdbcMemberRepository로 변경한다.
얼핏보기에는 다형성을 잘 지켜서 만든 거 같지만, 소스를 수정해야되므로 개방-폐쇄 원칙에는 어긋난다.
여기서 소스는 정말 눈에 보이는 소스 자체를 수정하면 안 된다는 것이 아니라 클라이언트 쪽 소스를 수정하면 안 된다는 것이다.
즉, 소프트웨어 요소를 새롭게 확장해도 사용 영역의 변경은 닫혀 있어야 한다.
객체를 생성하고, 연관관계를 맺어주는 별도의 조립, 설정자가 필요한데 스프링의 경우 DI/IoC 등을 이용해서 이 문제를 해결할 수 있다.

 

LSP : 리스코프 치환 원칙(Liskov substitution principle)

하위 타입 객체는 상위 타입 객체에서 가능한 행위를 수행할 수 있어야 한다.
쉽게 얘기하면 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것이다.
예를 들면, 자동차 인터페이스에 엑셀 기능을 구현할 때 규약에 따라 무조건 앞으로 가게 해야되는데 뒤로 가게 하는 기능을 만든것이다.
+를 해줘야 되는걸 - 해줬다고해서 컴파일 에러가 나지는 않겠지만 리스코프 치환 원칙에는 위배된다.

 

ISP : 인터페이스 분리 원칙(Interface segregation principle)

클라이언트는 자신이 사용하는 메서드에만 의존해야 한다는 원칙
자동차라는 인터페이스가 있다.
이 부분을 운전 인터페이스, 정비 인터페이스로 분리하고 클라이언트는 운전자 클라이언트, 정비사 클라이언트로 분리를 한다.
이렇게 하면 자동차에 문제가 생겼을 때 정비 인터페이스와 정비사 클라이언트만 수정하면 된다.
즉, 특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다라는 의미이다.
너무 크게 설정을 하면 에러가 발생 할 확률이 높아지고, 복잡하므로 적당히 인터페이스를 쪼개는게 좋다. 
 

DIP : 의존관계 역전 원칙(Dependency inversion principle)

의존 관계를 맺을 때, 변하기 쉬운 것(구체적인 것)보다 변하기 어려운 것(추상적인 것)에 의존해야 한다.
"프로그래머는 추상화에 의존해야지 구체화에 의존하면 안 된다.

운전자는 자동차에 의존해야되는거지 차종에 의존하면 안 된다.
즉, 운전자가 k3에서 k5로 차가 변경됐다고 해서 운전을 못 하면 문제가 있는 것이다.
그리고 k3와 k5는 서로의 존재를 알 필요가 없다.
즉, 추상적인 인터페이스에 의존해야되는거지 인터페이스를 구현한 구현체에 의존하면 안 된다는 것이다.

LSP(리스코프 치환 원칙)와 DIP(의존관계역전원칙)는 OCP(개방-폐쇄 원칙)를 서포트한다.
 
참고: 스프링 핵심 원리 - 기본편 https://inf.run/KjAN

반응형

댓글