[객체지향설계와패턴]SOLID 원칙
설계 원칙을 학습하는 이유는 무엇인가?
- 예측하지 못한 변경사항이 발생하더라도 유연하고 확장성이 있도록 시스템 구조를 설계하기 위해서이다.
- 좋은 설계란 기본적으로 시스템에 새로운 요구사항이나 변경이 있을 때 가능한 한 영향 받는 부분을 줄여야 한다.
- 단일 책임 원칙(Single Responsibility Principle, SRP)
객체지향 설계 관점에서, SRP에서 말하는 책임의 기본 단위는 ‘객체’를 지칭한다.
책임이란? ‘해야 하는 것’, ‘할 수 있는 것’ -> ‘해야 하는 것을 잘 할 수 있는 것’
어떤 클래스를 변경해야 하는 이유는 오직 하나여야 한다는 것이다.
1-1. 산탄총 수술
하나의 책임이 여러 개의 클래스들로 분산되어 있는 경우에도 단일 책임 원칙에 입각해 설계를 변경해야 하는 경우도 있다.
- 개방-폐쇄 원칙(Open-Closed Principle, OCP)
기존의 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계가 되어야 한다는 뜻이다.
OCP를 위반하지 않은 설계를 하려면, 무엇이 변하는 것인지 무엇이 변하지 않는 것인지를 구분해야 한다.
클래스를 변경하지 않고도(Closed) 대상 클래스의 환경을 변경할 수 있는(Open) 설계가 되어야 한다는 것이다.
- 리스코프 치환 원칙(Liskov Substitution Principle, LSP)
LSP는 일반화 관계에 대한 이야기다. 자식 클래스는 최소한 자신의 부모 클래스에서 가능한 행위는 수행할 수 있어야 한다는 뜻이다.
(부모 클래스와 자식 클래스 사이의 행위가 일관성이 있어야 한다는 의미이다.)
LSP를 만족한다면, 프로그램 내부에서 부모 클래스의 인스턴스 대신에 자식 클래스의 인스턴스로 대체해도 프로그램의 의미는 변화되지 않는다.
LSP를 만족시키는 간단한 방법은 재정의하지 않는 것이다.
- 인터페이스 분리 원칙(Interface Segregation Principle, ISP)
클라이언트 자신이 이용하지 않는 기능에는 영향을 받지 않아야 한다는 내용이다.
클라이언트에 특화된 인터페이스를 사용해야 한다.
즉, 인터페이스를 클라이언트에 특화되도록 분리시키라는 설계 원칙이라고 할 수 있다.
- 의존 역전 원칙(Dependency Inversion Principle, DIP)
DIP를 만족하려면 어떤 클래스가 도움을 받을 때(다른 클래스에 의존할 때) 구체적인 클래스보다는 인터페이스나 추상클래스와 의존 관계를 맺도록 설계해야 한다.
DIP를 만족하면 의존성 주입이라는 기술로 변화를 쉽게 수용할 수 있는 코드를 작성할 수 있다.
의존성 주입(Dependency Injection)? 클래스 외부에서 의존되는 것을 대상 객체의 인스턴스 변수에 주입하는 기술이다.
- 정리
- SRP : 어떤 클래스를 변경해야 할 이유는 오직 하나 뿐이어야 한다.
- OCP : 클래스를 변경하지 않고도 그 클래스의 환경을 바꿀 수 있어야 한다.
- LSP : 유도된 클래스의 메서드를 퇴화시커거나 불법으로 만드는 일을 피하라. 기반 클래스의 사용자는 그 기반 클래스에서 유도된 클래스에 대해 아무것도 알 필요가 없어야 한다.
- DIP : 자주 변경하는 컨크리트 클래스 대신 인터페이스나 추상 클래스에 의존하라.
- ISP : 어떤 객체의 사용자에게 그 사용자한테 필요한 메서드만 있는 인터페이스를 제공하라.