IT/기초 지식

그림으로 이해하는 SOLID 원칙

개발자 두더지 2023. 7. 9. 17:26
728x90

일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.

 

 이 포스트는 Ugonna Thelam 저자가 작성한 "The S.O.L.I.D Principles in Pictures"을 번역한 것입니다.

 

시작하기에 앞서


 오브젝트 지향 프로그래밍에 정통한 사람이라면 SOLID 원칙에 대해서 들어본 적이 있을 것이다. 이 다섯 가지의 소프트웨어 개발 원칙은 소프트웨어 구축시에 따라야 할 가이드 라인으로 소프트웨어의 확장성이나 보수성을 높이기 위한 것으로, 소프트웨어 엔지니어인 Robert C.Martin이 제안한 것이다. 

 SOLID에 관한 멋진 설명은 인터넷 상에 굉장히 많지만, 일러스트가 있는 것은 거의 보지 못했다. 따라서 나와 비슷한 시각적 학습자에게는 질리지 않고 공부하기 조금 어렵다. 그러므로, 이 포스트의 주된 목적은 일러스트를 사용하여 이 원리를 보다 이해하고, 각 원리의 목적을 명확히 하기 위함이다. 

 이 원칙의 몇 가지는 비슷해보지만, 목적이 동일하진 않다. 예를 들어 한쪽의 원칙을 충족하면서 다른 쪽 원칙은 어길 수 있다는 것이다. 

 이 포스트에서는 알기 쉽게 하기 위해 "클래스"이라는 단어를 사용하고 있지만, 함수, 메소드, 모듈에도 해당하므로 주의하길 바란다.

 

 

SOLID 원칙


S (Single Responsibility)

 클래스는 하나의 책임만을 가져야한다.

 클래스가 많은 책임을 가지면, 버그가 발생할 가능성이 높아진다. 그 이유는 그 책임 중 하나가 바뀌면 인식하지 못한 사이에 다른 책임에도 영향을 끼칠 가능서이 있기 때문이다. 

목적

이 원칙은 변경 결과로 버그가 발생해도, 다른 관계 없는 동작에는 영향을 미치지 않도록 하기 위해 동작을 분리하는 것이 목적이다. 

 

O (Open-Closed)

 클래스는 확장에는 오픈이지만, 변경에는 클로즈여야한다.

 클래스의 현재 동작을 변경하면 그 클래스를 사용하고 있는 모든 시스템에 영향을 미친다. 클래스에서 보다 많은 함수를 실행하고 싶을 때 이상적인 방법은 기존의 함수에 추가하는 것으로 변경은 하지 않는 것이다. 

목적

이 원칙은 클래스의 기존 동작을 변경하는 것이 아닌, 클래스의 동작을 확장하는 것을 목적으로 하고 있다. 이것은 클래스가 사용되고 있는 장소에 버그가 발생하는 것을 피하기 위함이다.

 

L(Liskov Substitution) 

 S가 T의 서브 타입인 경우 프로그램내의 T형 오브젝트를 S형의 오브젝트로 바꿔도 그 프로그램의 특징은 어떠한 것도 바뀌지 않는다. 

 

 자식 클래스가 부모 클래스와 동일한 동작을 실행할 수 없는 경우, 버그가 발생할 가능성이 있다. 한 클래스로 다른 클래스를 만들면 기존의 클래스는 부모가 되고, 새로운 클래스가 자식이 된다.

 자식 클래스는 부모 클래스가 할 수 있는 모든 것을 할 수 있어야한다. 이 프로세를 상속이라고 부른다.

 자식 클래스는 부모 클래스와 동일한 리퀘스트를 처리하고 동일한 결과 혹은 거의 동일한 결과를 제공해야한다. 이 일러스트에서는 부모 클래스가 커피를 제공하고 있다(커피의 종류는 묻지않도록한다). 자식 클래스가 카푸치노를 제공하는 카푸치노가 커피의 한 종류이므로 허용되지만, 물을 제공하는 것은 허용하지 않는다.

 자식 클래스가 이러한 요건을 만족하지 않는 경우, 자식 클래스가 크게 변경되어 이 원칙에 위반되는 것이다.

목적

 이 원칙은 부모 클래스나 그 자식 클래스가 에러 없이 동일한 방법으로 사용되도록 일관성을 가지는 것을 목적으로 한다.

 

I (Interface Segregation)

 클라이언트가 사용하지 않는 메소드에 대한 의존을 강제해서는 안 된다.

 클래스에 사용하지 않는 동작을 실행하려고 하는 것은 낭비가 많고 클래스에 해당 동작을 수행하는 기능이 없을 경우 예기치 않았던 버그가 발생할 수 있다. 

 클래스는 그 역할을 달성하기 위해 필요한 동작만을 실행할 필요가 있다. 그 외의 동작은 완전히 삭제하던가, 미래에 다른 클래스에서 사용할 가능성이 있는 경우는 다른 장소에 이동시켜야한다.

목적

 이 원칙은 동작의 세트를 보다 작게 분할하여 클래스가 필요한 것만 실행하는 것을 목적으로 한다.

 

D (Dependency Inversion)

  •  상위 모듈은 하위 모듈에 의존하면 안 된다. 어떤 쪽이든 추상화에 의존해야한다.
  • 추상화는 세부 사항에 의존해선 안 된다. 세부 사항이 추상화에 의존해야한다.

 먼저 여기서 사용되고 있는 용어에 대해서 간단히 정의하도록 하겠다.

  • 상위 모듈(혹은 클래스) : 툴을 사용하여 동작을 실행하는 클래스
  • 하위 모듈(혹은 클래스) : 동작을 실행하기 위해 필요한 툴
  • 추상화 :  두 개의 클래스를 연결하는 인터페이스
  • 세부 사항 : 툴의 동작 방법

 이 원칙에서는 클래스는 동작을 실행하기 위해서 사용할 툴과 융합해서는 안 된다. 반대고 툴이 클래스에 접속할 수 있는 인터페이스와 융합해야한다.

 또한, 클래스도 인터페이스도, 툴의 동작 방법을 알면 안된다. 그러나, 툴은 인터페이스의 사양을 만족할 필요가 있다.

목적

 이 원칙은 인터페에스를 도입하는 것으로 상위 레벨의 클래스가 하위 레벨의 클래스에 의존하는 것을 줄이기 위한 것이 목적이다.


참고자료

https://qiita.com/baby-degu/items/d058a62f145235a0f007

728x90