객체 지향 설계 - SOLID

2022. 5. 14. 20:24프론트엔드/React.js

728x90

회사에서 얘기를 듣다가
내가 SOLID에 대해 모르자
설명하시던 분이 당황하셨던 것 같다.

회사에서 개발하는 내용의 중요한 개념이기도 하고,
알아두면 좋을 것 같아서 기록을 해본다.

 

SOLID (객체 지향 설계) - 위키백과, 우리 모두의 백과사전

 

ko.wikipedia.org


SOLID란?

SOLID는 5개의 객체지향 프로그래밍 및 설계의
다섯 가지 기본 원칙에서 한 글자씩 따온 것이다.

핵심은 유지 보수와 확장이 쉬운 시스템을 개발하기 위함이다.
소스 코드를 리팩토링할 때 이런 기준으로 하면 좋을 것이다.


단일 책임 원칙 (Single responsibility principle)

말 그대로 '하나의 클래스는 하나의 책임만 가진다'는 뜻이다.
그리고 그 클래스는 책임을 완전히 캡슐화해야 한다고 한다.

SOLID가 유지 보수와 확장이 쉽게 위함이라는 것을 생각하며,
이 단일 책임 원칙이 어떻게 유지보수와 확장을 용이하게 하는지 생각해보자.

예를 들어 공장이 있다고 생각해보자.

철을 녹이고, 압착기로 납짝하게 만들고, 절단하고
등등의 기능을 하는 모듈들이 있다.

만약 철을 녹이는 용광로와 압착기를 한 세트로 묶으면 어떻게 될까?
철과 시멘트를 섞는 새로운 제품을 만든다면 문제가 생길 것이다.
어찌어찌 녹이는것까지는 성공해도, 압착기를 피하도록 조정을 해줘야한다.
이런 내용들은 코드의 복잡도를 높인다. (예외 처리가 많아지는 등)

또한 용광로팀이 어떻게 철을 녹이는 지를 공정을 만드는 사람이 알아야 할까?
철을 불로 녹이건 용암으로 녹이건 알아서 잘 녹이는 것은 용광로팀의 일이다.
(물론 실제 회사라면 관리자가 관리를 하겠지만)

핵심 공정은 녹이고 -> 납짝하게 만들고 -> 절단하는 것이다.
녹이고 -> 휘어트리고 -> 절단하는 과정이건 뭐건
알아서 잘 녹이고 알아서 잘 휘어트리면 되는 것이다.


개방-폐쇄 원칙 (Open-Closed Principle)

소프트웨어 개체는 확장에 대해 열려있어야 하고,
수정에 대해서는 닫혀야 한다는 내용이다.

기능을 추가하거나 변경해야 할 때,
이미 동작하던 코드를 변경하지 않더라도,
새로운 코드를 추가함으로써 기능의 추가나 변경이 가능해야 한다는 얘기다.

예를 들어 이런 코드를 살펴보자.

function Button({ text: string }) {
  return(<button>{text}</button>
}

그런데 여기에서 아이콘이 추가된다고 생각해보자.
만약 아이콘을 무조건 넣어야 한다고 생각하면,
기존의 Button호출 부분에서 전부 null값을 넣어줘야 한다.

하지만 아이콘을 선택적으로 넣을 수 있게 하면,
기존 코드를 수정하지 않고도 아이콘 버튼을 만들 수 있다.

function Button({ text:string, icon: React.ReactNode? }) {
  return (<button>{icon}{text}</button>);
}

확장에 대해 열려있다

모듈의 동작을 확장할 수 있어야 한다.
위의 예제에서 아이콘을 추가할 수 있는 것과 같다.

수정에 대해 닫혀있다.

위에서 기본 코드를 수정하지 않고도
내용이 추가된 것과 같다.


리스코프 치환 법칙 (Liskov substitution principle)

하위 자료형은 상위 자료형의 객체로 교체할 수 있다는 것이다.
상위 자료형의 객체를 하위 자료형을 썼을 때 문제가 없어야 한다.

솔직히 이건 봐도 모르겠다 나중에 정리해봐야겠다.


인터페이스 분리 원칙

클라이언트가 자신이 이용하지 않는 메서드에
의존하지 않아야 한다는 원칙이다.

큰 덩어리의 인터페이스들을 작게 분리시켜서,
꼭 필요한 메서드만 이용할 수 있게 해야한다는 얘기다.

단일 책임과 마찬가지로
역할을 분할해서 독립적으로 활용할 수 있게 하는 것이다.

만약 내가 A 메서드를 사용하려는데, A가 내부에서 B메서드를 호출한다.
그러면 나는 쓰지도 않는 B메서드를 호출해야 한다.

그러지 않고 A와 B를 분리하여, A만 호출할 수 있게 하고
기존의 코드는 A와 B가 분리되었으니 리팩토링이 필요할 것이다.


의존관계 역전 원칙

상위 계층이 하위 계층에 의존하는 의존관계를 역전하는 것이다.

상위 모듈은 하위 모듈에 의존하면 안 되고,
추상화는 세부 사항에 의존하면 안 된다.

이 부분은 좀 더 찾아봤다.

 

[SOLID] 의존 역전 원칙(DIP)이란?

안녕하세요? 제이온입니다. 저번 시간에는 인터페이스 분리 원칙을 알아 보았습니다. 오늘은 의존 역전 원칙을 설명하겠습니다. 의존 역전 원칙 (Dependency Inversion Principle)의 정의 의존 역전 원칙

steady-coding.tistory.com

 


마무리

정리를 하고나니 그렇게 엄청 실용적이지 않아보인다.

물론 내가 개발을 하면서 직접 겪고 체득한 개념도 보였지만, (단일 책임, 개방-폐쇄)
'저거 다 지키면서 짜는게 과연 더 효과적인가?'라는 의문이 들기도 한다 (리스코프 등)

그리고 2000년대 초반에 설립된 원칙이니만큼
변화한 시대의 요구사항과 다른 점도 있을 것이다.
시대가 발전하며 다른 방안을 찾았을수도 있고.

하지만 이런 원칙들에서 살펴볼 것은,
어떤 고민들이 있었는가라고 생각한다.

나만 하더라도 예전에 컴포넌트 하나 수정하면
모든 호출부를 찾아가서 바꿨던 기억이 난다.
그래서 그러지 않아도 되는 방법을 고민해서 쓰던 방법이다.

이러한 고민의 과정을 들여다보고, 원리를 파악해서
프로젝트와 개인에 맞는 방식으로 적용하는 것이 좋아보인다.