티스토리 뷰

728x90

SOLID 란?

SOLID란 객체 지향 프로그래밍을 하면서 지켜야하는 5대 원칙으로 각각 SRP(단일 책임 원칙), OCP(개방-폐쇄 원칙), LSP(리스코프 치환 원칙), DIP(의존 역전 원칙), ISP(인터페이스 분리 원칙)의 앞글자를 따서 만들어졌다. SOLID 원칙을 철저히 지키면 시간이 지나도 변경이 용이하고, 유지보수와 확장이 쉬운 소프트웨어를 개발하는데 도움이 되는 것으로 알려져있다.

 

참고로 SOLID는 어떠한 특정 프로그래밍 언어 혹은 프레임워크를 위해 만든 원칙이 아니다.

SOLID는 프레임워크도 라이브러리의 패턴도 아니며, 특정 기술에 국한되지 않는다. 그래서 TypeScript 또는 Java 와 같은 선호하는 프로그래밍 언어나 프레임워크에 원칙을 자유롭게 적용할 수도 있다. (왠만한 언어는 oop를 지원하니 고대로 이론 원칙을 적용이 가능하다)

 

1️⃣ 단일 책임의 원칙(SRP, Single Responsibility Principle)

단일 책임 원칙은 클래스(객체)는 단 하나의 책임만 가져야 한다는 원칙이다. 여기서 '책임' 이라는 의미는 하나의 '기능 담당'으로 보면 된다.

즉, 하나의 클래스는 하나의 기능 담당하여 하나의 책임을 수행하는데 집중되도록 클래스를 따로따로 여러개 설계하라는 원칙이다.

 

만일 하나의 클래스에 기능(책임)이 여러개 있다면 기능 변경(수정) 이 일어났을때 수정해야할 코드가 많아진다.
예를 들어 A를 고쳤더니 B를 수정해야하고 또 C를 수정해야하고, C를 수정했더니 다시 A로 돌아가서 수정해야 하는, 마치 책임이 순환되는 형태가 되어버린다.


따라서 SRP 원칙을 따름으로써 한 책임의 변경으로부터 다른 책임의 변경으로의 연쇄작용을 극복할 수 있게 된다.

최종적으로 단일 책임 원칙의 목적은 프로그램의 유지보수 성을 높이기 위한 설계 기법이다.

 

이때 책임의 범위는 딱 정해져있는 것이 아니고, 어떤 프로그램을 개발하느냐에 따라 개발자마다 생각 기준이 달라질 수 있다. 따라서 단일 책임 원칙에 100% 해답은 없다.

 

이렇게 각각 도구들이 있을 때 청소기는 청소라는 책임만 가지면 되며, 선풍기의 책임을 가질 필요가 없다는 것이다.

각각의 도구들이 그 책임을 가지는 것과 같이 각각의 클래스는 하나의 책임만 가지면 된다.

 

2️⃣ 개방 폐쇄 원칙 (Open-Closed Principle, OCP)

OCP 원칙은 클래스는 '확장에 열려있어야 하며, 수정에는 닫혀있어야 한다' 를 뜻한다.

기능 추가 요청이 오면 클래스를 확장을 통해 손쉽게 구현하면서, 확장에 따른 클래스 수정은 최소화 하도록 프로그램을 작성해야 하는 설계 기법이다.

 

- [ 확장에 열려있다 ] - 새로운 변경 사항이 발생했을 때 유연하게 코드를 추가함으로써 큰 힘을 들이지 않고 애플리케이션의 기능을 확장할 수 있음

- [ 변경에 닫혀있다 ] - 새로운 변경 사항이 발생했을 때 객체를 직접적으로 수정을 제한함. 

 

어렵게 생각할 필요없이, OCP 원칙 추상화 사용을 통한 관계 구축을 권장을 의미하는 것이다. (자바에서 추상 클래스와 상속을 통환 클래스 관계 구축을 생각하면 된다.)

즉, 다형성과 확장을 가능하게 하는 객체지향의 장점을 극대화하는 기본적인 설계 원칙이다.

 

3️⃣ 인터페이스 분리 원칙 (Interface segregation principle, ISP)

SP 원칙은 인터페이스를 각각 사용에 맞게 끔 잘게 분리해야한다는 설계 원칙이다.

SRP 원칙이 클래스의 단일 책임을 강조한다면, ISP는 인터페이스의 단일 책임을 강조하는 것으로 보면 된다.

즉, SRP 원칙의 목표는 클래스 분리를 통하여 이루어진다면, ISP 원칙은 인터페이스 분리를 통해 설계하는 원칙.

 

ISP 원칙은 인터페이스를 사용하는 클라이언트를 기준으로 분리함으로써, 클라이언트의 목적과 용도에 적합한 인터페이스 만을 제공하는 것이 목표이다.

다만 ISP 원칙의 주의해야 할점은 한번 인터페이스를 분리하여 구성해놓고 나중에 무언가 수정사항이 생겨서 또 인터페이스들을 분리하는 행위를 가하지 말아야 한다.
(인터페이스는 한번 구성하였으면 왜만해선 변하면 안되는 정책 개념)

 

프린터기의 기능을 보면 크게 인쇄 하는 것과 팩스하는 기능이 있다고 가정 하자.

이때 인쇄와 스캔은 유사한 기능이므로 한가지로 묶고 팩스는 따로 분리한다.

이것과 같이 한개의 인터페이스에 많은 기능을 넣지 않고 유사한 기능을 가진 기능끼리 한개의 인터페이스로 분리하는 것이다.

 

4️⃣ 리스코프 치환 원칙 (Liskov Substitution Principle, LSP)

LSP 원칙은 서브 타입은 언제나 기반(부모) 타입으로 교체할 수 있어야 한다는 원칙이다.

쉽게 말하면 LSP는 다형성 원리를 이용하기 위한 원칙 개념으로 보면 된다.

 

간단히 말하면 리스코프 치환 원칙이란, 다형성의 특징을 이용하기 위해 상위 클래스 타입으로 객체를 선언하여 하위 클래스의 인스턴스를 받으면, 업캐스팅된 상태에서 부모의 메서드를 사용해도 동작이 의도대 흘러가야 하는 것을 의미하는 것이다.

 

따라서 기본적으로 LSP 원칙은 부모 메서드의 오버라이딩을 조심스럽게 따져가며 해야한다.
왜냐하면 부모 클래스와 동일한 수준의 선행 조건을 기대하고 사용하는 프로그램 코드에서 예상치 못한 문제를 일으킬 수 있기 때문이다.

 

자동차를 예를 들어 보자.

자동차라는 부모에서 자식이 될 수 있는건 택시, 소방차와 같은 지상에서 4개의 바퀴를 가지고 움직이는 탈것이다.

하늘을 나는 비행기의 부모는 자동차가 될 수 없다.

 

5️⃣ 의존 역전 원칙 (Dependency Inversion Principle, DIP)

DIP 원칙은 어떤 Class를 참조해서 사용해야하는 상황이 생긴다면, 그 Class를 직접 참조하는 것이 아니라  대상의 상위 요소(추상 클래스 or 인터페이스)로 참조하라는 원칙이다.

즉, 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻이다.

 

 

 

 

Reference Link

https://inpa.tistory.com/entry/OOP-%F0%9F%92%A0-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84%EC%9D%98-5%EA%B0%80%EC%A7%80-%EC%9B%90%EC%B9%99-SOLID

728x90