SRP (Single Responsibility Principle) : 단일 책임 원칙
OCP (Open-Closed Principle) : 개방 폐쇄 원칙
LSP (Liskov Substitution Principle) : 리스코프 치환 원칙
ISP (Interface Segragation Principle) : 인터페이스 분리 원칙
DIP (Dependency Inversion Principle) : 의존관계 역전 원칙
앞자를 따서 SOILD 원칙이라고 부른다.
1. 단일 책임 원칙 (Single Responsiblity Principle)
모든 클래스는 각각 하나의 책임만 가져야 한다. 클래스는 그 책임을 완전히 캡슐화해야 함을 말한다.
- 사칙연산 함수를 가지고 있는 계산 클래스가 있다고 치자. 이 상태의 계산 클래스는 오직 사칙연산 기능만을 책임진다. 이 클래스를 수정한다고 한다면 그 이유는 사직연산 함수와 관련된 문제일 뿐이다.
- 변경사항이 있을때, 애플리케이션의 파급 효과가 적으면 SRP 원칙을 잘 따른것으로 볼 수 있다.
2. 개방-폐쇄 원칙 (Open Closed Principle)
확장에는 열려있고 수정에는 닫혀있는. 기존의 코드를 변경하지 않으면서( Closed), 기능을 추가할 수 있도록(Open) 설계가 되어야 한다는 원칙을 말한다.
- 캐릭터를 하나 생성한다고 할때, 각각의 캐릭터가 움직임이 다를 경우 움직임의 패턴 구현을 하위 클래스에 맡긴다면 캐릭터 클래스의 수정은 필요가없고(Closed) 움직임의 패턴만 재정의 하면 된다.(Open)
- 높은 응집도와 낮은 결합도 라는 원리
높은 응집도
응집도가 높다는건 하나의 모듈, 클래스가 하나의 책임 또는 관심사에만 집중되어 있다는 뜻이다. 같은 책임, 관심사를 기반으로 하나의 객체로 설계하기 때문에 객체에 변경이 발생하더라도 다른 곳에 미치는 영향이 제한적이다.
낮은 결합도
책임과 관심사가 다른 객체 도는 모듈과는 낮은 결합도를 유지해야 한다. 이는 높은 응집도보다 더 민감한 원칙이라고 토비의 스프링에서는 설명하고 있다. 결합도란 하나의 오브젝트가 변경이 일어날때 관계를 맺고있는 다른 오브젝트에게 변화를 요구하는 정도로 설명한다. 즉 낮은 결합도란, 하나의 변경이 발생할 때 다른 모듈과 객체로 변경에 대한 요구가 전파되지 않는 상태라고 할 수 있다.
확장에 열려있다?
모듈의 확장성을 보장하는 것을 의미한다. 새로운 변경사항이 발생했을 때 유연하게 코드를 추가 또는 수정할 수 있기 때문이라고 한다.
변경에 닫혀있다?
객체를 직접적으로 수정하는건 제한해야 한다. 기능이 추가되거나 수정할 때, 객체를 직접적으로 수정해야 한다면 새로운 변경사항에 대해 유연하게 대응할 수 없는 애플리케이션이다. 이는 유지보수의 비용증가가 될 수 있으며, 객체지향적인 설계로 볼 수 없다.따라서 객체를 직접 수정하지 않고도 변경사항을 적용할 수 있도록 설계해야 한다. 그래서 변경에 닫혀있다고 표현한 것으로 추론된다.결과적으로 OCP는 추상화를 의미하는 것으로 해석된다. 객체를 추상화함으로써 확장엔 열려있고, 변경엔 닫혀있는 유연한 구조를 만들수 있는 것이다.
OCP를 구현하기 위해서는 DI(Dependency Injection), IoC(Inversion Of Container)가 필요하다.
3. 리스코프 치환 원칙 (Liskov Substitution Principle)
자식 클래스는 언제나 자신의 부모 클래스를 대체할 수 있다는 원칙이다. 즉 부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 계획대로 잘 작동해야 한다.
자식클래스는 부모 클래스의 책임을 무시하거나 재정의하지 않고 확장만 수행하도록 해야 LSP를 만족한다.
4. 인터페이스 분리 원칙 (Interface Segregation Principle)
한 클래스는 자신이 사용하지않는 인터페이스는 구현하지 말아야 한다. 하나의 일반적인 인터페이스보다 여러개의 구체적인 인터페이스가 낫다.
범용 인터페이스 하나보다는 특정 클라이언트를 위한 여러 개의 인터페이스 분리가 더 좋다고 한다.
5. 의존 역전 원칙 (Dependency Inversion Principle)
의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 것, 거의 변화가 없는 것에 의존하라는 것이다. 한마디로 구체적인 클래스보다 인터페이스나 추상 클래스와 관계를 맺으라는 것이다.
프로그래머는 구체화가 아니라 추상화에 의존해야 한다고 한다. 즉 구현 클래스(구현체)가 아니라 인터페이스(역할)에 의존하라는 이야기이다.
댓글