프로그래머가 시간이 지나도 유지 보수와 확장이 쉬운 소프트웨어를 만드는데 필요한 원칙이다.
이 원칙은 일반적인 상황에서 보다 높은 수준으로 따라야 할 원칙으로 정의한다.
밑의 5가지 원칙의 앞글자를 따서 SOLID원칙이라고 부른다.
- SRP(Single Responsiblity Principle, 단일 책임 원칙)
- OCP(Open - Close Principle, 개방 - 폐쇄 원칙)
- LSP(Liskov Substitution Principle, 리스코프 치환 원칙)
- ISP(인터페이스 분리 원칙)
- DIP(Dependency Inversion Principle, 의존 역전 원칙)
SRP(Single Responsiblity Principle, 단일 책임 원칙)
- 클래스나 함수는 하나의 책임만 가져야 한다.
- 클래스 수는 많아질지라도 프로그램 복잡도는 낮아진다.
여기서 책임이란, 기능 정도의 의미로 해석 가능하다.
설계를 잘한 프로그램이란 새로운 요구사항과 프로그램의 변경에 영향을 받는 부분이 적은데, 이것은 높은 응집도와 낮은 결합도를 가진 프로그램을 의미한다.
만약 한 클래스가 가지고 있는 책임이 많다면, 클래스 내부 함수끼리 강한 결합을 발생할 가능성이 높아지고, 유지보수 비용이 증가하므로 책임을 분리하여 개발할 필요가 있다.
OCP(Open - Close Principle, 개방 - 폐쇄 원칙)
- 기존의 코드를 변경하지 않고 기능을 확장할 수 있어야 한다.
- 변경이 필요한 경우 기존 코드를 변경하지 않고 상속과 확장으로 대응한다.
- 변경 비용은 줄이고 확장 비용은 최대화
OCP에 만족하는 설계를 할 때 변경되는 것이 무엇인지에 초점을 맞춘다.
자주 변경되는 내용은 수정하기 쉽게 설계하고, 변경되지 않아야 하는 것은 수정되는 내용에 영향을 받지 않도록 설계해야 한다.
코드의 변경이 아예 안 일어나는 것은 아니다.
OCP 적용의 대표적인 사례는 인터페이스를 이용한 설계이다.
LSP(Liskov Substitution Principle, 리스코프 치환 원칙)
- 부모 클래스와 자식 클래스 사이의 행위에는 일관성이 있어야 한다.
- 하위 클래스는 언제나 상위 클래스의 인스턴스로 교체 가능하다.
- 상속은 다형성을 통한 확장성 획득이 목표다.
- 다형성과 확장성을 극대화하려면 인터페이스를 사용.
객체지향 프로그래밍에서 부모 클래스의 인스턴스 대신 자식 클래스의 인스턴스를 사용해도 문제가 없어야 한다는 것을 의미한다.
상속관계에서는 일반화 관계(IS-A)가 성립해야 하며 이는 일관성이 있다는 것이다. 따라서 리스코프 치환원칙은 일반화 관계에 대해 묻는 것이라 할 수 있다.
ISP(Interface Segregation Principle, 인터페이스 분리 원칙)
- 사용하지 않는 메소드에 대한 의존 관계 배제
- 사용자에게 필요한 메소드만 인터페이스 제공
- 하나의 일반적인 인터페이스보단 여러 개의 구체적인 인터페이스가 낫다.
인터페이스 분리원칙은 기본적으로 자신이 사용하지 않는 기능(인터페이스)에는 영향을 받지 말아야 한다는 의미로 범용 인터페이스 설계를 배제하는 원칙이다.
DIP(Dependency Inversion Principle, 의존 역전 원칙)
- 추상화에 의존해야지, 구체화에 의존하면 안 된다.
- 의존 관계를 맺을 때, 변화하기 쉬운 것보단 변화하기 어려운 것에 의존해야 한다는 원칙이다.
변화하기 쉬운 것 = 구체적인 것
변화하기 어려운 것 = 추상적인 것
객체지향적인 관점에서 봤을 때 변화하기 쉬운 것이란 구체화된 클래스를 말하고, 변화하기 어려운 것이란 추상클래스나 인터페이스를 말한다.
따라서 DIP를 만족한다는 것은 구체적인 클래스보다, 추상클래스와 인터페이스와 관계를 맺는다는 것을 의미한다.