티스토리 뷰
객체 지향 설계 원칙을 정리한다.
설계 원칙 5개의 첫 철자를 따서 SOLID라 칭한다.
SRP 단일 책임 원칙(Single Responsibility Principle)
한 클래스는 단 한가지의 변경 이유만을 가져야 한다.
책임이란건 변경을 위한 이유인데 한 클래스가 둘 이상의 책임을 맡는다면 한 책임에 대한 변경이 다른 책임을 충족하는 클래스의 능력을 떨어뜨리거나 저하시킬 수 있다.
이해하기 쉽게 여러 가지 기능을 가진 클래스를 만들지 말자. 다른 기능 수정하다가 정상적인 기능을 했던 메서드가 원치 않는 동작을 할 수 있다
주의할 것은 자주 변경되지도 않는데 SRP 충족시킨다고 클래스를 잘게 쪼개다가는 불필요한 복잡성이란 악취를 풍기게 한다... 그냥 복잡해진다고 하자
OCP 개방 폐쇄 원칙(Open-Closed Principle)
소프트웨어 개체(클래스, 모듈 함수 등)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다.
이미 제대로 동작하고 있던 원래 코드를 변경하는 것이 아니라 새로운 코드를 만들어서 해당 기능을 제공하는 방법
Client, Server 라는 클래스가 있고 Client 클래스에서 Server 클래스를 사용할 때 중간에 ClientInterface라는 추상 클래스를 두어 Client 클래스가 ClientInterface 클래스를 구현한 Server클래스를 사용하도록 한다.
Client 입장에서는 Server 클래스가 AnotherServer 클래스로 바꿔도 ClientInterface라는 추상 클래스를 사용하기 때문에 수정할 필요가 없다.
하지만 OCP를 처음부터 적용하기는 쉽지 않다.
변경에 대한 모든 가능성을 예상해서 만들었다치자.... 내가 신이 아닌 이상 수정은 이루어진다
복잡해지는 것을 피하기 위해서 우선 처음 변경이 일어나는 시점까지는 변경이 일어나지 않을 것처럼 작성한다.
너무 많은 생각을 하지 않는다.
변경이 일어나고 추상화하기 위해서는 테스트 케이스 작성이 우선이다.
어설픈 추상화를 피하는 일은 추상화 자체 만큼이나 중요하다
LSP 리스코프 치환 원칙(Liskov Substitution Principle)
서브타입(subtype)은 그것의 기반 타입(base type)으로 치환 가능해야 한다.
A가 B의 상위 타입(클래스)이라면 A 타입의 인스턴스에 대해 성립하는 모든 규칙은 B 타입의 인스턴스에 대해서도 성립해야 한다 - kotlin in action p.384
바바라 리스코프 교수님(1939년생)이 1988년에 처음으로 작성한 원칙이다.
깔끔하게 설명한 동영상 강의로 대체
LSP 위반은 OCP 위반이다.
코드에 instanceOf나 downcasting, 서브 클래스에서 슈퍼클래스를 호출 하는 경우 LSP 위반이다. 상속 관계를 끊고 composition 관계(참고 : UML 클래스 다이어그램, 소스코드 매핑)로 만들 수 있는지 확인한다.
ISP 인터페이스 분리 원칙(Interface Segregation Principle)
클라이언트가 자신이 사용하지 않는 메소드에 의존하도록 강제되어서는 안 된다.
어떤 클라이언트가 자신은 사용하지 않지만 다른 클라이언트가 사용하는 메소드를 포함하는 클래스에 의존할 때 그 클라이언트는 다른 클라이언트가 그 클래스에 가하는 변경에 영향을 받게 된다.
비대한 클래스는 클라이언트 간에 높은 결합도를 유발한다. 클라이언트 고유의 인터페이스를 만들어서 여러개로 분리한다.
DIP 의존 관계 역전 원칙(Dependency Inversion Principle)
a. 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다.
b. 추상화는 구체적인 사항에 의존해서는 안 된다. 구체적인 사항은 추상화에 의존해야 한다.
구체 클래스에 의존하는 대신 추상 클래스에 의존하는 것을 선호해라
추상화를 통해 클라이언트는 인터페이스로 접근하고 해당 인터페이스를 구현한 여러 클래스를 제어할 수 있도록 만든다.
참고