※ 본 포스팅은 21.10.11에 게시된 글을 이전한 것 입니다.
SOLID 원칙은 객체지향에서 대표적인 원칙이라고 할 수 있으며 로버트 마틴이 좋은 객체 지향 설계의 5가지 원칙을 정리한 것이다.
SRP, 단일 책임 원칙
Single responsibility principle, 단 하나의 책임만을 가져야 한다는 것을 의미한다.
여기서 책임의 기본단위는 객체를 의미하며, 하나의 객체가 하나의 책임을 가져야 한다는 의미이다.
그렇다면 책임은 무엇인가?
객체지향에서 책임은 객체가 할 수 있는 것과, 해야 하는 것으로 나누어져 있다.
즉, 하나의 객체는 할 수 있는 것과 해야 하는 것만 수행할 수 있도록 설계되어야 한다.
하지만 하나의 책임이라는 것은 모호하다. 책임은 클 수도 있고 작을 수도 있으며 문맥과 상황에 따라 다르다.
중요한 기준은 변경이다.
변경이 있을 때 파급효과가 적으면 단일 책임의 원칙을 잘 따른 것이라고 볼 수 있다.
다시 말해, 하나를 변경했을 때 외부 변경사항이 적은 것 결국 유지 보수하기 쉬운 것을 의미한다.
OCP, 개방 - 폐쇄 원칙
open-closed Principle, 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야 한다는 뜻이다.
기존의 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계되어야 한다는 의미이다.
요구 사항 변경 시 변경되어야 하는 부분과 변경되지 않아야 하는 부분을 명확하게 구분 (사용영역, 구성영역으로 구분)하여 유연하게 작성해야 한다.
이는 다형성을 활용하면 된다.
인터페이스를 구현한 클래스를 만들어 기능을 추가하면 기존의 코드를 변경하는 것이 아니므로 ocp 원칙을 지킬 수 있다.
하지만 다형성만으로는 ocp 원칙을 완벽하게 지킬 수는 없다.
ocp 원칙을 완벽하게 지키기 위해서는 객체를 생성하고, 연관관계를 맺어주는 별도의 조립, 설정자가 필요하다.
스프링에서는 스프링 컨테이너가 알아서 해준다.
LSP, 리스코프 치환 원칙
Liskov substitution principle, 일반화 관계에 관한 이야기다.
자식 클래스는 최소한 부모 클래스에서 가능한 행위를 수행할 수 있어야 한다는 의미이다.
LSP를 만족하면 부모 클래스의 인스턴스 대신 자식 클래스의 인스턴스로 대체해도 프로그램의 의미는 변화되지 않으며, 정확성도 깨뜨리지 않음을 의미한다.
예를 들면 자식 클래스가 부모 클래스를 오버라이딩 하거나 추가적인 기능을 통해 부모의 상태를 변경시킬 수 없으며,
부모 클래스의 책임을 무시하거나 재정의 하지 않고 오직 확장만 수행한다는 것을 의미한다.
부모 클래스가 수행하고 있는 책임을 그대로 수행하면서
추가적인 필드나 기능을 제공하는 경우에만 상속하는 것이 바람직하다.
이는 단순히 컴파일에 성공하는 것을 넘어서는 이야기이다.
다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것, 다형성을 지원하기 위한 원칙, 인터페이스를 구현한 구현체를 믿고 사용하려면 이 원칙이 반드시 필요하다.
예를 들면 자동차 인터페이스의 엑셀은 뒤로 가게 구현하면 이를 위반하므로 느리더라도 반드시 앞으로 가게 구현해야 한다.
ISP, 인터페이스 분리 원칙
Interface Segregatiton Principle, 인터페이스를 클라이언트에 특화되도록 분리시키라는 의미이다.
특정 클라이언트를 위한 인터페이스가 여러 개 범용 인터페이스 하나보다 낫다는 뜻을 포함하며,
클라이언트 자신이 이용하지 않는 기능에는 영향을 받지 않아야 한다는 뜻이다.
예를 들어 자동차 인터페이스는 운전 인터페이스와 정비 인터페이스로 분리하며 사용자 클라이언트는 운전사 클라이언트, 정비사 클라이언트로 분리할 수 있다. 정비 인터페이스 자체가 변해도 운전자 클라이언트에게 영향을 주지 않는다.
결과적으로 인터페이스가 명확해지며 대체 가능성이 높아진다.
※ ISP와 SRP
이 두 가지 원칙은 동일한 문제에 대해 다른 해결책을 제시한다고 볼 수 있다.
하나의 클래스가 기능이 비대하여 책임을 분할하여 갖게 하는 것이 SRP이고 비대한 기능을 인터페이스로 분할하여 사용하는 것이 ISP이다.
DIP, 의존 역전 원칙
Dependency inversion principle, 의존성 주입이라고 일컫는다.
의존성 주입은 "프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안 된다."라는 이 원칙을 따르는 방법 중 하나이다. 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 것, 거의 변화가 없는 것에 의존하라는 원칙이다.
다시 말해, 구현 클래스가 아닌 인터페이스(역할)에 의존하라는 의미이다.
클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다.
예를 들면 컴퓨터와 키보드에서 컴퓨터는 한 제조사의 키보드가 아닌, 모든 키보드를 사용할 수 있으므로 이 원칙을 준수한 것이다.
'📑 개발 이론 > 🌱 SPRING' 카테고리의 다른 글
스프링 핵심 원리 - 스프링 빈 (0) | 2023.06.17 |
---|---|
스프링 핵심 원리 - 스프링 컨테이너 (0) | 2023.06.17 |
스프링 핵심 원리 - 객체지향 원리 적용 정리 (0) | 2023.06.17 |
[스프링 핵심원리] OCP와 DIP (0) | 2023.04.18 |
[스프링 핵심원리] 객체지향프로그래밍이란? (0) | 2023.04.18 |