Backend/JAVA

객체지향 5원칙 (SOLID)

keepbang 2021. 7. 28. 17:52

객체지향 5원칙

  • 개발을 진행하면서 좋은 소프트웨어를 만들기 위해 지켜야할 5가지 원칙을 말하며 각 원칙의 앞 글자를 축약하여 SOLID라고 말한다.

 

5가지 원칙은 아래와 같다.

SRP(Single Responsibility Principle) : 단일 책임 원칙
OCP(Open/Closed Principle) : 개방 폐쇄 원칙
LSP(Liskov Substitution Principle) : 리스코프 치환 원칙
ISP(Interface Segregation Principle) : 인터페이스 분리 원칙
DIP(Dependency Inversion Principle) : 의존관계 역전 원칙

1. SRP(Single Responsibility Principle) : 단일 책임 원칙

  • 모든 클래스는 각각 하나의 기능만 가진다는 의미이다.
  • 각각의 해당 클래스가 제공하는 모든 서비스는 단 하나의 책임을 수행하는 데 집중 되어야 한다는 원칙
  • 객체지향에서 책임이란 객체가 할 수 있는 것해야 하는 것으로 나뉘어져 있다.

 

SRP를 적용하면 높은 응집도낮은 결합도를 갖는 객체지향적인 설계가 가능하다. 다른 클래스들이 서로 영향을 미치는 의존성이 낮아져서 코드의 유지보수 및 가독성이 향상되며 코드의 중복 제거에도 용이하다.

 

2. OCP(Open/Closed Principle) : 개방 폐쇄 원칙

  • 기존의 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계되어야 한다.
  • 소프트웨어의 모든 구성요소는 확장에 열려있고, 변경에는 닫혀있어야한다.
  • 확장에는 유연하게, 변경은 최소화하는 것을 의미한다.

OCP는 요구사항이 변경되었을 때 코드에서 변경되어야 하는 부분변경되지 않아야 하는 부분을 명확하게 구분하여, 변경되어야 하는 부분을 유연하게 작성하는 것을 의미한다.

 

로버트 마틴은 OCP를 다음과 같이 설명한다.

OCP는 관리가 용이하고 재사용 가능한 코드를 만드는 기반이며, OCP를 가능케 하는 중요한 메커니즘은 추상화다형성이다. 

 

OCP는 객체지향의 장점을 극대화하는 아주 중요한 원리이다.

 

자바에서 interface를 통해 확장에는 열려있고, private를 통해 변경에 대하여 닫혀있는 코드를 작성할 수 있다.

 

3. LSP(Liskov Substitution Principle) : 리스코프 치환 원칙

  • 부모 클래스를 상속한 자식 클래스는 부모 클래스의 역할 및 기능을 정확히 수행할 수 있어야 한다.
  • 자식 클래스의 상세 내부를 부모 클래스는 알 필요가 없으며 서브 클래스가 확장에 대한 인터페이스를 준수해야 함을 의미한다.

부모 클래스의 메소드를 override하면 LSP원칙을 위반하는 것이 된다. 부모 클래스의 기존 메소드를 자식 클래스가 수정하면 부모 클래스의 역할 및 책임이 변경되기 때문에 문제가 생기는 것이다.

 

LSP를 지키는 가장 간단한 방법은 override를 안하는 것이지만 이게 무조건 적인 방법은 아니다.

 

상속을 할 때 override가 필요하다면 기존 부모 클래스의 메소드가 하던 역할을 출실히 수행하고 기능의 추가만 신중하게 하면 된다.

 

LPS는 결국 상속을 할 때 재정의(override)가 필요한 경우 부모 클래스 메소드의 의미를 해치지 않는지 신중히 고민하고 코드를 작성해야 한다.

 

4. ISP(Interface Segregation Principle) : 인터페이스 분리 원칙

  • 자신이 사용하지 않는 인터페이스는 구현하지 말하야 한다는 원칙으로 자신이 사용하지 않는 기능에는 영향을 받지 않아야한다.
  • 하나의 큰 인터페이스를 상속 받기 보다는 인터페이스를 구체적이고 작은 단위들로 분리시켜 꼭 필요한 인터페이스만 상속하자라는 의미이다.

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

 

인터페이스 하나의 크기가 크다는 것은 한번에 지켜야 할 약속이 많아진다는 것을 의미한다. 때문에 기능별로 인터페이스를 나누는 것이 중요하다고 생각한다.

 

5. DIP(Dependency Inversion Principle) : 의존관계 역전 원칙

  • 클래스 사이에 의존관계에서 의존관계가 존재하되, 구체적인 클래스에 의존하지 말고 최대한 추상화한 클래스에 의존하라는 의미이다
  • 구체적인 클래스보다 interface나 추상클래스를 적극적으로 활용하라는 의미이기도 하다.

DIP를 만족하면 의존성 주입이라는 기술로 변화를 쉽게 수용할 수 있는 코드를 작성할 수 있다. 의존성 주입이란 말 그대로 클래스 외부에서 의존되는 것을 대상 객체의 인스턴스 변수에 주입하는 기술이다.

 

실제 사용 관계는 바뀌지 않으며, 추상을 매개로 메시지를 주고 받음으로써 관계를 최대한 느슨하게 만드는 원칙이다.

 

 

[참조]

 

 

객체지향 5원칙 : SOLID

디자인 패턴에 대해 공부하던 중 예전 소프트웨어 공학 때 배운 객체지향 5원칙(SOLID)에 대해 다시 정리해보기로 했습니다.

jaeyeong951.medium.com