개발

객체지향의 5대 원칙

소밍소밍 2022. 3. 14. 00:30

SOLID, 로버트 마틴이 2000년대 초반에 명명한 객체 지향 프로그래밍 및 설계의 다섯가지 기본 원칙이다.

SOLID라고 외우는 것은 쉽지만 각 원칙도 줄이면 오히려 외우기가 어렵고, 풀어서 읽는 것이 오히려 이해하기 좋다고 생각해서 약어로 쓰지 않았다.

Single Responsibility Principal, 단일 책임의 원칙

There should never be more than one reason for a class to change, 클래스 변경의 이유는 단 하나여야 한다. 쉽게 말해, 하나의 클래스는 하나의 책임만을 가지고 있어야 한다. 

이 원칙을 도입하면

  • 코드가 간결해지기 때문에
  • 가독성이 향상되고
  • 유지보수가 용이해진다

이 원칙을 도입하기 위해서는

  • 기존에 여러 곳에 흩어져있는 책임을 한 곳에 모으거나 (응집도(cohesion) 높이기)
  • 여러 원인에 의해 변경되는 것을 발견할 때 클래스를 분리하면 된다 (결합도(coupling) 낮추기)

Open Close Principle, 개방 폐쇄의 원칙

You should be able to extend a classes behavior, without modifying it. 소프트웨어의 구성요소가 확장에는 열려있고, 변경에는 닫혀 있어야 한다. 요구사항의 추가, 변경시 기존 구성요소의 수정이 아니라 기존 구성요소를 확장해서 재사용할 수 있어야 한다. 

이 원칙을 도입하면

  • 코드 재사용성을 높일 수 있다

이 원칙을 도입하기 위해서는

  • 변경되지 않을 부분과, 변경 또는 확장될 부분을 구분한다.
  • 단, 구분 시 관계가 복잡해질 수 있으니 변경상황을 예측하여 적절히 구분해야 한다.

The Liskov Substitution Principle, 리스코브 치환의 원칙

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it. 서브 타입은 언제나 기반 타입으로 교체할 수 있어야 한다. 즉, 서브타입은 기반 타입이 약속한 규약(public 인터페이스)을 지켜서 확장에 대한 인터페이스를 준수해야 한다.

예를 들어, 리스코브 치환의 원칙을 적용하면 A 인터페이스를 구현한 B를 사용한 코드는 A로 선언하고, A 타입으로 로직을 만들어 둬야 한다. 그래야 A 인터페이스를 구현한 C로 B를 대체해도 대체하는 부분 외의 코드를 수정하지 않을 수 있기 때문이다.

이 원칙을 도입하면

  • 다형성을 통한 확장성을 얻을 수 있으며, 다형성과 확장성을 극대화할 수 있다.
  • 리스코브 치환의 원칙을 바탕으로 개방 폐쇄의 원칙으로 확장하는 부분에 다형성을 제공할 수 있다.

이 원칙을 도입하기 위해서는

  • 두 개체가 똑같은 일을 한다면 둘을 하나의 클래스로 표현하고 이들을 구분할 수 있는 필드를 둔다.
  • 두 클래스가 같은 연산을 조금씩 다르게 제공한다면 공통의 인터페이스를 만들어 이를 구현하게 한다.
  • 공통된 연산이 없다면 별개의 클래스로 만든다.
  • 두 개체가 하는 일에 추가로 무언가를 더한다면 구현 상속을 사용한다.

Interface Segregation Principal, 인터페이스 분리의 원칙

Clients should not be forced to depend upon interfaces that they do not use. 사용하지 않는 인터페이스는 구현하지 않아야 한다는 원리이다. Single Responsibility Principle이 클래스의 단일책임을 강조한다면 Interface Segregation Principle은 인터페이스의 단일책임을 강조한다. 단, 인터페이스는 여러 책임 또는 역할을 갖는 것이 인정된다는 점이 다르다.

예를 들어 인터페이스 분리의 원칙에 의하면 A 인터페이스를 구현하는 B가 A 인터페이스 중 한개 이상의 기능을 사용하지 않는다면, A 인터페이스를 분리해야 한다. B는 사용하지 않는 기능을 구현하지 않아야 하기 때문이다.

이 원칙을 도입하면

  • 인터페이스의 클라이언트가 기대하는 메시지만을 전달할 수 있다. (사용하지 않는 메시지는 제외되기 때문)

이 원칙을 도입하기 위해서는

  • 여러 클래스 중 반드시 사용하는 기능에 대해 인터페이스를 생성하여 그 인터페이스를 상속하도록 한다. 
  • 사용하지 않는 기능이 있다면 인터페이스를 분리한다.

Dependency Inversion Principle, 의존성 역전의 원칙

A. High level modules should not depend upon low level modules. Both should depend upon abstractions. 상위 모듈은 하위 모듈에 의존해서는 안된다. 상위 모듈과 하위 모듈 모두 추상화에 의존해야 한다.

B. Abstractions should not depend upon details. Details should depend upon abstractions. 추상화는 세부 사항에 의존해서는 안된다. 세부사항이 추상화에 의존해야 한다.

의존성 역전의 세가지 키워드는 IOC, 훅 메소드(슈퍼클래스에서 디폴트 기능을 정의하거나 비워두었다가 서브클래스에서 선택적으로 오버라이드할 수 있도록 만들어 둔 메소드), 확장성이다.

의존성 역전의 원칙은 비동기적으로 커뮤니케이션이 이루어져야 하는 경우, 컴포넌트간 커뮤니케이션이 복잡한 경우, 컴포넌트 간 커뮤니케이션이 빈번해서 비효율적일 경우 사용된다.

이 원칙을 도입하면

  • 컴포넌트간의 커뮤니케이션을 단순화할 수 있다.

 

참고자료

www.nextree.co.kr/p6960/ 

'개발' 카테고리의 다른 글

파일 & 디렉토리 권한  (0) 2022.03.14
LINUX 서버에서 자주 쓰는 명령어  (0) 2022.03.14
로컬 파일을 게이트웨이를 통해 서버로 보내기  (0) 2022.03.14
메소드 네이밍  (0) 2022.03.14
로그 레벨 (Log Level)  (0) 2022.03.14