"프로그래밍에서 가치는 원칙보다 높은 수준의 개념이며, 원칙을 가치를 지키기 위해서 존재해야 한다." - 켄트 백
가치
가 없다!!시간
이 생기고 시간은 곧 비용
으로 직결된다.최선의 선택
을 추구해야하고 최선의 선택을 위해서는 우리만의 기준을 세워두어야 한다.SOLID 원칙 간단 정리 표
약어 | 개념 | |
---|---|---|
S | SRP | 단일 책임 원칙(Single Responsibility Principle) → 한 클래스는 하나의 책임만 가져야 한다. |
O | OCP | 개방 - 폐쇄 원칙(Open Closed Principle) → 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다. |
L | LSP | 리스코프 치환 원칙(Liskov Substitution Principle) → 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다. |
I | ISP | 인터페이스 분리 원칙(Interface Segregation Principle) → 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다. |
D | DIP | 의존 관계 역전 원칙(Dependency Inversion Principle) → 프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안된다. 의존성 주입은 이 원칙을 따르는 방법 중 하나다. |
소프트웨어 요소(타입, 모듈, 함수 등)는
응집도 있는 하나의 책임(기능)
을 가져야 한다.
- 타입을 변경해야 하는 이유는 단지
응집도
여야 한다.- 변경을 위한 이유가 같은 것들끼리 잘 모여있어야 한다.
- 높은 응집도를 바탕으로 코드의 수정은 한 곳에 집중되어야 한다.
응집도(Cohesion)
: 응집도는 모듈에 포함된 내부 요소들이 하나의 책임/ 목적을 위해 연결되어있는 연관된 정도를 뜻한다. 응집도는 높을 수록 좋다.
소프트웨어 요소는
확장 가능하도록 열려있고, 변경에는 닫혀있어야 한다.
- 기존 코드의 변경 없이도 기능을 추가할 수 있도록 설계해야 한다.
- 기존 코드의 변경은 버그의 가능성을 높이고 테스트 코드의 변경도 필요할 수 있기 때문에 확장을 할 때는 연쇄적인 수정이 일어나지 않도록 기존의 코드를 최대한 건드리지 않아야 한다.
- 즉, 프로토콜이 있고 그 프로토콜을 채택하는 타입들이 있다면 확장을 할 때 프로토콜 내부는 건들지않고 타입 내부에서 수정되는게 좋은 방식이다.
자식 클래스는
언제나 부모 클래스로 교체 가능
해야한다.
- 부모 클래스의 인스턴스를 사용하는 위치에 자식 클래스의 인스턴스를 대신 사용했을 때 코드가 원래 의도대로 작동해야 한다는 뜻이다.
- 생각보다 지키지기 어려운 원칙 중 하나다.
클라이언트 객체는 사용하지 않는 메소드에 의존하면 안된다.
- 프로토콜이 커지면 그만큼 한번에 요구되는 구현량이 많아진다. 일부 기능만 필요함에도 불구하고 나머지 기능들은 사용할 수 없는데도 구현해주어야 한다.
- 예를 들어보자
스마트폰 프로토콜이 존재하고 그곳엔 스마트폰을 구현하기 위한 각종 기능들이 들어가 있고 그 중에는 생체 인식 기능도 있다. 만약 iPhone 14 클래스를 구현해야한다면 프로토콜 내부의 동작들을 모두 사용할 수 있고 ISP원칙을 지킬 수 있다. 하지만 iPhone 2 클래스를 구현하게 된다면 생체 인식 기능은 포로토콜 규칙 상 구현은 하되 빈공간으로 버려지는 기능이 될 것이고 이런 상황은 ISP원칙을 위반한 것이다.- 그렇기 때문에 각각의 프로토콜은 잘게 분리가 되어있고 그 중에 정말 필요한 기능만 들어있는 프로토콜을 선택해서 사용할 수 있게 해야 한다.
- 한번 프로토콜을 분리하여 구성해놓고 나중에 무언가 수정사항이 생겨서 또 프로토콜을 분리하는 행위는 지양하자.
상위 레벨 모듈은 하위 레벨 모듈에 의존하면 안된다.
- 둘 다
추상화된 프로토콜에 의존
해야 한다. 추상화는 구체화에 의존하면 안되고, 구체화는 추상화에 의존하면 안된다.- 이유: 구체적인 것은 쉽게 변하지만, 추상적인 것은 잘 변하지 않는다.