좋은 객체 지향 설계의 5가지 원칙 (SOLID) 😏
[디자인 패턴의 아름다움] 3. 설계 원칙
1) 단일 책임 원칙클래스와 모듈은 하나의 책임 또는 기능만을 가지고 있어야 한다. 즉, 거대하고 포괄적인 클래스를 설계하는 대신, 작은 단위와 단일 기능을 가진 클래스를 설계해야 한다. 예
progfrog.tistory.com
✍️ 개요
SOLID란, 객체 지향 프로그래밍을 하면서 지켜야 하는 5대 원칙으로 각각 SRP(단일 책임 원칙), OCP(개방-폐쇄 원칙), LSP(리스코프 치환 원칙), ISP(인터페이스 분리 원칙), DIP(의존 역전 원칙)의 앞글자를 따서 만들어졌다. SOLID 원칙을 지키면 시간이 지나도 변경이 용이하고, 유지보수와 확장이 쉬운 소프트웨어를 개발하는데 도움이 되는 것으로 알려져 있다.
객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다. (협력) 객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다.
- 위키백과(https://ko.wikipedia.org/wiki/객체_지향_프로그래밍)
위키백과에 나온 객체 지향 프로그래밍의 정의를 정리하자면,
프로그램은 각각의 명령어를 순차적으로 수행하는 절차지향을 벗어나
객체 하나하나가 서로 메시지를 주고받으며 로직을 수행하는 협력 형태라고 볼 수 있다.
👉 SRP 단일 책임 원칙
Single Responsibility Principle
- 한 클래스는 하나의 책임만 가져야 한다.
- 하나의 책임이라는 것은 모호하다.
- 책임은 클 수도 있고, 작을 수도 있다.
- 문맥과 상황에 따라 다르다.
- 책임을 많이 질수록, 클래스 내부에서 서로 다른 역할을 수행하는 코드끼리 강하게 결합될 가능성이 높아진다.
- 이렇게 되면 결국 기존 시스템에서 변경이 일어날 때 영향받는 부분이 많아지게 되고, 이는 곧 나쁜 설계이다.
- 클래스를 변경할 경우 2가지 이상의 이유가 있다는 것은, 곧 책임도 2가지 이상이라는 뜻!
- 중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 적을수록 단일 책임 원칙을 잘 따른 것이다.
- 한 클래스에 너무 많은 책임을 부여하지 말고 단 하나의 책임만 수행하도록 하여, 변경 사유가 될 수 있는 것(= 책임)을 하나로 만들어야 한다. 이를 책임 분리(≒ 관심사의 분리 Separation Of Concerns)라 한다.
- 책임 분리를 통해 클래스들이 책임을 적절하게 분담하도록 변경하면, 어떤 변화가 생겼을 때 영향을 최소화할 수 있다.
👉 OCP 개방 - 폐쇄 원칙
Open/Closed Principle
- 소프트웨어의 구성 요소는 확장에는 열려 있으나, 변경에는 닫혀 있어야 한다.
- 변화하지 않는 부분(닫힌 부분)과 변화하는 부분(열린 부분)을 분리하자.
- 코드를 변경하지 않으면서 확장을 어떻게 해야 하는가? 정답은 다형성이다.
- 역할과 구현의 분리를 떠올리자!
상속을 사용한 개방 - 폐쇄 원칙
- 클래스 상속을 생각해 보면 부모 클래스가 닫힌 부분이고, 자식 클래스가 열린 부분이다.
- 부모 클래스를 굳이 변경하지 않더라도, 자식 클래스의 행동을 변화시키면 확장할 수 있다.
추상 인터페이스를 사용한 개방 - 폐쇄 원칙
- 추상 인터페이스를 사용하는 클래스가 닫힌 부분이고, 그것을 구현하는 클래스가 열린 부분이다.
- 추상 인터페이스 구현 부분만 교환하면, 사용자 측 클래스의 행동을 간접적으로 변경할 수 있다.
🔎 그러나, 다형성 만으로는 OCP 원칙을 지킬 수 없다.
- 객체를 생성하고, 연관 관계를 맺어주는 별도의 조립, 설정자가 필요하다.
- OCP를 지키기 위해서 DI,IoC, 컨테이너도 필요한 것
👉 LSP 리스코프 치환 원칙
Liskov Substitution Principle
- 리스코프 치환 원칙은 1988년 바바라 리스코프가 올바른 상속 관계의 특징을 정의하기 위해 발표한 것!
- 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서, 하위 타입의 객체로 바꿀 수 있어야 한다.
- 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다. 다형성을 지원하기 위한 원칙으로, 인터페이스를 구현한 구현체를 믿고 사용하려면 이 원칙이 필요하다.
- LSP를 만족하면, 상위 타입의 객체를 하위 타입의 객체로 치환해도 프로그램이 동일하게 수행된다.
- 단순히 컴파일에 성공하는 것을 넘어서 기능적으로도 적절해야한다.
- 특정 인터페이스(Car)에서 전진(go) 기능이 있다고 할 때, 구현체에서는 '전진'이라는 책임을 다해야 하며 특정 구현체가 '전진' 기능을 수행할 때 '후진'이나 '우회전'을 한다면 LSP에 위배되는 것이다.
👉 ISP 인터페이스 분리 원칙
Interface Segregation Principle
- 클라이언트는 자신이 이용하지 않는 메서드에 의존하지 않아야 한다.
- 클래스 사용자에게 불필요한 인터페이스를 공개하지 말라는 원칙.
- 범용 인터페이스 하나보다는 특정 목적을 위한 인터페이스가 여러 개 있는 것이 좋다.
- 이렇게 함으로써, 클라이언트에서는 꼭 필요한 메스드들만 이용할 수 있게 된다.
- 이런 작은 단위들을 역할 인터페이스라고도 부른다.
public interface Car {
void driving(DirectionType direction);
void fix(FixType type);
}
위의 예제처럼 자동차 인터페이스가 있다고 할 때,
운전을 통합하는 driving과 fix처럼 범용적인 인터페이스 2개보다는...
public interface Car {
void go();
void left();
void stop();
void right();
void fixHandle();
void fixEngine();
}
이렇게 특정 기능을 수행하는 작은 단위로 분리하는 게,
내부 의존성을 약화시켜 리팩토링/수정/재배포를 쉽게 한다.
👉 DIP 의존관계 역전 원칙
Dependency Inversion Principle
- 프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안 된다.
- 예를 들어, 운전자는 운전을 하기 위해 자동차 역할에 대해서만 알면 되지 K3에 대해서 알아야 하는 것이 아니다.
- 즉, 구현 클래스가 아닌 인터페이스에 의존하라는 의미이다.
의존 관계 역전 원칙에 위반
의존 관계 역전 원칙의 예
🤔 요약하면...
5가지의 객체 지향 설계 원칙인 SOLID가 얘기하는 핵심은 결국 추상화와 다형성이다.
구현 클래스에 의존하지 않고 추상 클래스 또는 인터페이스에 의존함으로써 우리는 유연하고 확장가능한 애플리케이션을 만들 수 있는 것이다~!~!
단일 책임 원칙
- 한 클래스는 하나의 책임만 가져야한다.
- 변경이 있을 때 파급 효과가 적어야하다.
개방 폐쇄 원칙
- 확장에는 열려있으나, 변경에는 닫혀있어야 한다.
- 역할과 구현의 분리, 다형성을 활용할 수 있다!
- 그러나, 다형성만으로는 한계가 있다. 객체를 생성하고 연관 관계를 맺어주는 별도의 설정자가 필요하다.
- 다형성 + DI, IoC, 컨테이너
리스코프 치환 원칙
- 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서, 하위 타입의 객체로 바꿀 수 있어야 한다.
인터페이스 분리 원칙
- 범용 인터페이스 하나보다는 특정 목적을 위한 인터페이스가 여러 개 있는 것이 좋다.
- 특정 기능을 수행하는 작은 단위로 분리하는 것이 내부 의존성을 약화시켜 리팩토링, 수정, 재배포를 쉽게 한다.
의존관계 역전 원칙
- 추상화에 의존해야지, 구체화에 의존하면 안 된다.
- 즉, 구현 클래스가 아닌 인터페이스에 의존하라는 의미이다.
📚 참고자료
- 오즈 모리하루의 코딩의 기술
- 김영한의 스프링 핵심 기술 기본편
ArticleS.UncleBob.PrinciplesOfOod
The Principles of OOD What is object oriented design? What is it all about? What are it's benefits? What are it's costs? It may seem silly to ask these questions in a day and age when virtually every software developer is using an object oriented language
butunclebob.com