SOLID, 객체지향의 5대 원칙

Kim Sung Kyu·2021년 5월 27일
0

Design Pattern📐

목록 보기
1/1
post-thumbnail

SOLID 원칙이란?


엉클 밥, 로버트 C. 마틴이 말하는 SOLID 원칙은 기원은 다음과 같다.

SOLID 원칙의 역사는 깊다. 나는 1980년대 후반 유즈넷(과거 버전의 페이스북)에서 다른 사람들과 소프트웨어 설계 원칙에 대해 토론하는 과정에서 이들 원칙을 모으기 시작했다. 시간이 지나면서 원칙은 교체되거나 변경되었다. 사라져 버린 원칙도 있다. 어떤 원칙들은 서로 합쳐졌다. 새롭게 추가된 원칙도 있다. 2000년대 초반 나는 안정화된 최종 버전을 내놓았는데, 이 때 원칙들의 순서는 지금과 달랐다.

2004년 무렵, 마이클 페더스(Michael Feathers)가 이메일 한 통을 보내왔는데, 원칙들을 재배열하면 각 원칙의 첫 번째 글자들로 SOLID라는 단어를 만들 수 있다는 내용이었다. 그렇게 SOLID 원칙이 탄생했다.

SOLID 원칙이란 객체지향 설계에서 지켜야 할 5개의 원칙(SRP, OCP, LSP, DIP, ISP)이다.

1. Single Responsiblity Principle (단일 책임 원칙)

  • 소프트웨어의 설계 부품(클래스, 함수 등)은 단 하나의 책임만을 가져야 한다.

여기서 책임이란, '기능' 정도의 의미로 해석하면 된다.
설계를 잘한 프로그램은 기본적으로 새로운 요구사항과 프로그램 변경에 영향을 받는 부분이 적다. 다시말해, 응집도는 높고 결합도는 낮은 프로그램을 뜻한다. 만약 한 클래스가 수행할 수 있는 기능, 즉 책임이 많아진다. 책임이 많아지면 클래스 내부의 함수끼리 강한 결합을 발생할 가능성이 높아진다. 이는 유지보수에 비용이 증가하게 되므로 따라서 책임을 분리시킬 필요가 있다.

응집도란?
한 프로그램의 요소가 얼마나 뭉쳐있는지, 즉 구성 요소들 사이의 응집력을 말한다.

결합도란?
프로그램 구성 요소들 사이가 얼마나 의존적인지를 말한다.

2. Open-Closed Principle (개방-패쇄 원칙)

  • 기존의 코드를 변경하지 않고(Closed) 기능을 수정하거나 추가할 수 있도록(Open) 설계해야 한다.

OCP에 만족하는 설계를 할 때 변경되는 것이 무엇인지에 초점을 맞춘다. 자주 변경되는 내용은 수정하기 쉽게 설계 하고, 변경되지 않아야 하는 것은 수정되는 내용에 영향을 받지 않게 하는 것이 포인트다. 이를 위해 자주 사용되는 문법이 인터페이스(Interface)이다.
변경되는 부분을 정의 후 인터페이스로 분리해 개방-패쇄 원칙을 만족시키는 것이다.

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

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

리스코프 치환 원칙은 MIT 컴퓨터 사이언스 교수인 리스코프가 제안한 설계 원칙이다. 부모 클래스와 자식 클래스 사이의 행위에는 일관성이 있어야 한다는 원칙이며, 이는 객체 지향 프로그래밍에서 부모 클래스의 인스턴스 대신 자식 클래스의 인스터스를 사용해도 문제가 없어야 한다는 것을 의미한다.
상속 관계에서는 일반화 관계(IS-A)가 성립해야 한다. 일반화 관계에 있다는 것은 일관성이 있다는 것이다. 따라서 리스코프 치환 원칙은 일반화 관계에 대해 묻는 것이라 할 수 있다.

일반화 관계(IS-A)란?
Is a kind of 관계.

BMW, 벤츠, 맥라렌, 현대의 각 자동차 모델이 있지만,

BMW M3 is kind of 자동차
벤츠 E class is kind of 자동차
현대 소나타 is kind of 자동차

처럼 하위 클래스들의 공통점을 상위 클래스에서 가지고, 하위 클래스는 상위 클래스의 공통점을 상속 받는 관계

4. Dependency Inversion Principle (의존 역전 원칙)

  • 의존 관계를 맺을 때, 변화하기 쉬운것 보단 변화하기 어려운 것에 의존해야 한다는 원칙이다.

여기서 말하는 변화하기 쉬운것이란 구체적인 것을 말하고, 변화하기 어려운 것이란 추상적인 것을 말한다. 객체지향적인 관점에서 보자면 변화하기 쉬운것이란 구체화 된 클래스를 의미하고, 변화하기 어려운 것은 추상클래스나 인터페이스를 의미한다. 따라서 DIP를 만족한다는 것은 의존관계를 맺을 때, 구체적인 클래스보다 인터페이스나 추상 클래스와 관계를 맺는다는 것을 의미한다. DIP를 만족하면 '의존성 주입' 이라는 기술로 변화에 유연한 설계를 할 수 있다.

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

  • 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다. 하나의 일반적인 인터페이스보다는, 여러 개의 구체적인 인터페이스가 낫다.

이는 다시 말해서, 자신이 사용하지 않는 기능(인터페이스)에는 영향을 받지 말아야 한다는 의미이다.

한가지 예로. 우리는 스마트폰으로 전화, 웹 서핑, 사진 촬영 등 다양한 기능을 사용할 수 있다. 하지만 전화 기능을 사용할 때는 웹 서핑, 사진 촬영 등 다른 기능은 사용하지 않는다. 따라서 전화 기능과 웹 서핑 기능 사진, 촬영 기능은 각각 독립된 인터페이스로 구현하여, 서로에게 영향을 받지 않도록 설계해야 한다. 인터페이스 분리 원칙을 통해 설계된 소프트웨어는 시스템의 내부 의존성을 약화시켜 리팩토링, 수정, 재배포가 수월해진다.



참고

profile
꿈꾸던 내가 될꺼야😃

0개의 댓글