꾸준한 개발자

계속적인 성장을 추구하는 개발자입니다. 꾸준함을 추구합니다.

계속 쓰는 개발 노트

JAVA

객체 지향 설계의 5가지 원칙 (SOLID)

gold_dragon 2021. 10. 3. 17:01

SOLID란 로버트 마틴이 좋은 객체 지향 설계의 5가지 원칙을 정리한 것입니다.

SOLID 내용

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

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

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

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

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

SRP 단일 책임 원칙

한 클래스는 하나의 책임만 가져야 합니다. 여기서 하나의 책임이란 것이 모호합니다. 클 수도 있고 작을 수도 있고, 문맥과 상황에 따라 달라집니다. 여기서 중요한 기준은 변경입니다. 변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것이라 할 수 있습니다. 책임이라는 범위를 적절하게 조절하는 것이 객체 지향의 묘미입니다.

OCP 개방 폐쇄 원칙

소프트웨어 요소는 확장에는 열려 있지만, 변경에는 닫혀 있어야 합니다. 다형성과 관련한 원칙입니다. 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현하는 것은 기존 코드를 변경하는 것이 아닙니다. 인터페이스를 통한 역할과 구현의 분리를 구현할 수 있고, 이러한 다형성을 통해 개방 폐쇄 원칙을 구현할 수 있습니다.

그런데 다형성을 활용하여 코드를 실제 적용해보면 기존 클라이언트 코드를 변경해야됩니다. OCP 원칙을 지킬 수가 없게 되는 것입니다. 이 문제를 해결하기 위해서 객체를 생성하고 연관관계를 맺어주는 별도의 조립, 설정자가 필요합니다. 이 역할을 해주는 것이 곧 배우게 될 Spring이 됩니다.

LSP 리스코프 치환 원칙

객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 합니다. 예를 들어 자동차 인터페이스를 구현했다고 생각해봅시다. 자동차 인스턴스에는 엑셀이라는 기능이 있는데, 보통 개발자들이 생각하기에는 엑셀이란 것은 앞으로 가는 것이라 생각합니다. 여기서 만약 엑셀이란 기능을 사용했을 때 자동차가 뒤로 가게 된다면 리스코프 치환 원칙을 어긴 것입니다.

다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것, 다형성을 지원하기 위한 원칙, 인터페이스를 구현한 구현체는 믿고 사용하려면, 리스코프 치환 원칙이 필요합니다.

ISP 인터페이스 분리 원칙

특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 좋습니다. 예를 들어 자동차 인터페이스가 있다고 하면 해당 인터페이스에는 운전과 관련된 기능과 정비와 관련된 기능이 들어있습니다. 이 인터페이스를 운전 인터페이스와 정비 인터페이스로 분리하는 것입니다. 그러면 정비와 관련한 문제가 발생했을 경우 정비 인터페이스만 수정하면되고 운전 인터페이스는 건드리지 않아도 됩니다. 적당한 크기로 인터페이스를 쪼개는 것이 좋다는 원칙입니다. 인터페이스가 명확해지고, 대체 가능성이 높아집니다.

DIP 의존관계 역전 원칙

프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안됩니다. 의존성 주입은 이 원칙을 따르는 방법 중 하나입니다. 즉, 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻입니다. 클라이언트 코드가 구현 클래스를 바라보지 말고, 인터페이스를 바라봐야 됩니다.

김영한, 스프링 핵심 원리 - 기본편 <좋은 객체 지향 설계의 5가지 원칙>

위 이미지에서 운전자가 자동차 인터페이스를 바라보야지, K3를 바라보게 된다면 추후 아반떼로 변경할 때 유지보수 비용이 많이 소비됩니다. 철저히 역할에 의존해야 합니다. 구현에 의존하면 안됩니다.

 

다형성만으로는 OCP와 DIP를 지킬 수 없습니다. 여기서 Spring을 통해 두 원칙을 지켜나갈 수 있습니다.


*참조

김영한, 인프런 강의 <스프링 핵심 원리 - 기본편>

'JAVA' 카테고리의 다른 글

객체 지향의 4대 특성  (0) 2021.10.03
자바 프로그램 개발과 구동  (0) 2021.09.14
Java 변수  (0) 2021.09.10
클래스와 객체  (0) 2021.09.09
객체 지향 언어란? (Object Oriented Language)  (0) 2021.06.17