개발

[Design Pattern] 객체지향의 5대 원칙 Solid원칙

autocat 2021. 7. 24. 15:22

SOLID원칙

자바 관련도서를 찾으면서 리뷰글을 보던 도중 계속해서 나오는 SOLID란 단어에 대해 낯이 익으면서도 정확한 뜻을 모르기 떄문에 찾아보게 되었다.

프로그래밍 설계에서 항상 나오는 객체지향 5대 원칙으로 앞자를 따서 SOLID원칙이라고 부른다.

  • SRP(단일 책임 원칙)
  • OCP(개방-폐쇄 원칙)
  • LSP(리스코프 치환 원칙)
  • DIP(의존 역전 원칙)
  • ISP(인터페이스 분리 원칙

Single Responsiblity Principle(단일책임원칙)

정의

한 클래스는 단 한가지의 변경 이유만을 가져야한다.
하나의 모듈은 하나의, 오직 하나의 액터에 대해서만 책임을 져야한다.

 

내용

작성된 클래스는 하나의 기능 만 가지며 클래스가 제공하는 모든 서비스는 그 하나의 책임(기능)을 수행하는데 집중되어야 한다는 원칙이다.

단일 책임 원칙은 응집도(cohesion)와 관련이 있다.

즉 어떤 변화에 의해 클래스를 변경해야 하는 이유는 오직 하나뿐이여야 한다는것을 의미한다.

SRP 원리를 적용하면 책임의 영역이 확실해 지기 떄문에 책임 변경의 연쇄작용에서 자유로워질 수 있다.
또한 코드의 가독성 향상유지보수의 용이라는 장점을 지닌다.


Open Close Principle(개방폐쇄의 원칙)

정의

소프트웨어 개체는 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다.
기존의 코드를 변경하지 않고(Closed) 기능을 수정하거나 추가할수 있도록(Open) 설계해야 한다.

내용

소프트웨어의 구성요소(컴포넌트, 클래스, 모듈, 함수)는 확장에는 열려있고, 변경에는 닫혀야 한다는 원리이다.

변경을 위한 비용은 가능한 줄이고 확장을 위한 비용은 극대화로 해야 한다는 의미로, 요구사항의 변경이나 추가사항이 발생 하더라도, 기존 구성요소는 수정이 일어나지 말아야 하며, 기존 구성요소를 쉽게 확장해서 재사용할 수 있어야 한다는 뜻이다.

이를 위해 자주 사용되는 문법은 Interface 이다.

OCP는 관리가능하고 재사용 가능한 코드를 만드는 기반이며, 이를 가능케 하는 중요 메커니즘은 추상화다형성이라고 설명하고 있다. 객체지향의 장점을 극대화 하는 아주 중요한 원리다.

 

적용 이슈

모듈을 분리하는 과정에서 실패를 하게 된다면 오히려 관계가 더 복잡해 질 수 있다.

인터페이스는 가능하면 변경되어서는 안된다.


Liscov Substitution Principle(리스코프 치환 원칙)

정의

자식 클래스는 부모클래스에서 가능한 행위를 수행할 수 있어야 한다.

 

내용

MIT CS 교수인 리스코프가 제안한 설계원칙으로 부모클래스와 자식클래스에는 일관성이 있어야 한다는 원칙이다. 객체 지향 프로그래밍에서 부모 클래스의 인스턴스 대신 자식클래스의 인스턴스를 사용해도 문제가 없어야 한다는 것이다.

상속은 구현(extends)/인터페이스(implements)에 관계 없이 궁극적으로 다형성을 통한 확장성 획득을 목표로 한다.

자식 클래스는 부모 클래스의 책임(기능)을 무시하거나 재정의 하지 않고 확장만 수행해야 하도록 해야 LSP를 만족하게 된다.

결국 이 구조는 다형성을 통한 확장의 원리인 OCP 를 제공하게 된다. 따라서 LSP는 OCP를 구성하는 구조가 된다. LSP를 바탕으로 OCP는 확장하는 뿐에 다형성을 제공해 변화에 열려있는 프로그램을 만들 수 있도록 한다.

┌─────────┐   ┌──────< I >─┐
│ Billing ├──>│  License   │
└─────────┘   ├────────────┤
              │+ calcFee() │
              └────────────┘
                   ▵
           ┌───────┴──────┐
    ┌──────┴───┐      ┌───┴──────┐
    │ Personal │      │ Business │
    │ License  │      │ License  │
    └──────────┘      ├──────────┤
                      │- users   │
                      └──────────┘
  • 두 개체가 똑같은 일을 한다면 둘을 하나의 클래스로 표현하고 이들을 구분할 수 있는 필드를 둔다.
  • 공통된 연산이 없다면 별개인 2개의 클래스를 만든다
  • 두 개체가 하는일에 추가적으로 무언가를 더한다면 구현 상속을 사용한다.

Interface Segregation Principle(인터페이스 분리의 원칙)

정의

클라이언트가 지신이 이용하지 않는 메서드에 의존하지 않아야 한다는 원칙이다.

 

내용

하나의 거대한 인터페이스 보다는 여러개의 구체적인 인터페이스가 낫다는걸 의미한다.
어떤 클래스를 이용하는 클라이언트가 여러개고 이들이 해당 클래스의 부분만을 사용한다면, 이들을 따로 인터페이스로 뺴내어 클라이언트가 기대하는 메세지만을 전달할 수 있도록 한다.

SRP가 클래스의 단일책임을 강조한다면 ISP는 인터페이스의 단일책임을 강조한다.


Dependency Inversion Principle(의존성역전 원칙)

정의

상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안된다. 둘 모두 추상화에 의존해야한다.
추상화는 구체적인 사항에 의존해서는 안된다. 구체적인상황은 추상화에 의존해야한다.

 

내용

객체들이 서로 정보를 주고 받을때 의존관계가 형성되는데, 이 때 객체들은 나름대로의 원칙을 갖고 정보를 주고 받아야 한다는 설계 원칙이다. 의존관계를 맺을때, 구체적인 클래스보다 인터페이스나 추상 클래스와 관계를 맺는다는것을 의미한다.

변화 하지 않는것에 의존하는것 즉 추상화에 의존하라는 원칙이다.

 


참고

SOLID - DIP(Dependency Inversion Principle)란 : 의존성 역전 원칙

객체지향 개발 5대 원리: SOLID

SOLID 원칙

[디자인패턴] SOLID 원칙

SOLID 원칙