본문 바로가기
study/Spring

객체지향 설계에서 꼭 필요한 SOLID 5대원칙(SRP/OCP/LSP/ISP/DIP)

by 고기만두(개발자) 2021. 9. 22. 21:49
728x90
반응형

SRP : Single Responsibility Principle, 단일책임 원칙
OCP : Open Closed Principle, 개방-폐쇄 원칙
LSP : Liskov Subtitution Principle, 리스코프 치환원칙
ISP : Interface Segregation Principle, 인터페이스 분리 원칙
DIP : Dependency Inversion Principle, 의존 역전 원칙

의 앞글자를 따서 SOLID 원칙이라고 말한다.
객체지향을 공부하면서 꼭 알아야할 원칙이라고 할 수 있다.

스프링을 공부하면서, 자바 밑단까지 파고 들어가려고 보니 현업에서 정말 안 지켜지고 있는 원칙이 많구나 싶다.
이러니 매년 제도 바뀔때마다 개정 하면서, 매달 마감하면서 코드가 누더기가 되는 걸까......


1. SRP : Single Responsibility Principle, 단일책임 원칙

어떤 클래스를 변경해야 하는 이유가 생긴다면, 그 이유는 오직 하나뿐이어야 한다.

한 사람은 친구들 사이에서, 부모님의 자녀로서, 애인으로, 직장에서 등 여러 상황에 맞는 자아를 갖는다.

SRP
아 참, 예시로 들긴 했지만 애인은 있는지부터 물어보는 게 순서 아닌가 ...

그 자아의 역할이 혼종되지 말아야 한다는 얘기다. (회사에서 애인 자아를 꺼내오면 안 되잖아?)
코드도 마찬가지다.
하나를 변경했을 때 여러 가지가 변경되어서는 안 된다.

-Bad Example-

  • 변수 레벨
    • 하나의 속성이 여러 의미를 갖는 경우
    • 어떤 곳에서는 쓰고, 어떤 곳에서는 쓰지 않는 속성이 있는 경우
  • 메소드 레벨: 분기 처리를 위한 if문이 덕지덕지 많을 경우

2. OCP : Open Closed Principle, 개방-폐쇄 원칙

소프트웨어의 엔티티(클래스, 모듈, 함수 등)는 자신의 확장에는 열려있고, 주변의 변화에 대해서는 닫혀 있어야 한다.
주로 interface 를 구현하여 해결한다.

극을 올릴 때, 그래서는 안되겠지만 원래 출연하기로 한 배우가 모종의 사정으로 갑작스럽게 불참하는 경우
혹은 여러 회차를 며칠간 여러 명이 돌아가면서 서는 뮤지컬 같은 경우
대본은 다시 쓰지 않고, 배우만 다른 사람으로 갈아 끼울 수 있어야 하는 거랑 비슷하다.
어쨌거나 극이 돌아가기만 하면 된다.
(물론 이렇게 말하면 예술성 측면에서 태클이 걸릴지 모르겠으나. 기능적인 측면만 두고 보면 그렇다.)

OCP
대본을 바꾸지 않고, 발연기일지언정 누가 들어가도 일단 구현 자체는 돼야 한다는 말이다.

아니면 좀 더 기술적인 예시를 들어 보자면..
JDBC 설정 변경에 따라서 데이터베이스를 오라클을 연결하든 MySQL을 연결하든
구현 자체에는 무리가 없이 돌아가야 하는 거랑도 비슷하겠다.


3. LSP : Liskov Subtitution Principle, 리스코프 치환원칙

리스코프치환원칙
자동차에서 오픈카, 경찰차는 파생될 수 있지만, 갑자기 비행기로의 비약은 곤란하다

하위 클래스는, 상위 클래스의 행동범위 안에서 놀아야 하고 벗어난 기능을 구현할 순 없다.
그리고 서브타입은 언제나 자신의 기반타입으로 교체할 수 있어야 한다.

경찰차도, 오픈카도 자동차의 기본적인 도로주행 역할을 그대로 수행할 수 있다.
경찰차가 고장날 경우, 그냥 일반 자동차 하나 빌려와서 경찰 팻말 하나 달면 경찰차라고 우길 수 있다.
기능 자체에는 문제가 없으니까(?)
자동차의 기본적인 기능과 행동양식을 그대로 물려받으면, 가능하다.
하지만 갑자기 '비행기'가 자동차의 파생이라고 우기면 감당하기 힘들어진다.


4. ISP : Interface Segregation Principle, 인터페이스 분리 원칙

ISP
SRP를 조금 다른 관점으로 바라보는 방법이라고도 볼 수 있겠다. SRP는 클래스, ISP는 인터페이스 관점으로

SRP와 비슷한듯 하지만 약간 다른 점이 있다.
인터페이스를 활용한다는 것이다.
'나' 라는 객체에 직장봇, 친구, 자녀, 애인 기능을 하는 메소드를 모두 몰아넣을 수 있다.
하지만

//class 나 implement 직장봇일 때 직장봇 고기만두 = new 나();

고기만두를 직장봇으로 생성한 경우,
직장봇 기능의 메소드만 생성하고 다른 기능에서의 메소드를 가져오지 않는 형태의 설계이다.


5. DIP : Dependency Inversion Principle, 의존 역전 원칙

DIP
우리는 '운전'을 하는 방법을 배우고 면허를 따지, 각 세부 차종에 대해 면허를 따지 않는다

고차원 모듈은 저차원 모듈에 의존하면 안된다.
추상화된 것은 구체적인 것에 의존하면 안된다.

차종이 바뀌어도, 운전하는 방법은 동일하다.
버스 면허를 별도로 따는 정도의 스케일 아니고서야,
소나타 타던 사람이 테슬라로 차를 바꾼다고 면허를 다시 따지 않는 거랑 비슷하다.

오늘은 이렇게 다섯가지 객체 지향의 기본 원리 SOLID에 대해 알아보았다.


도움받은 자료
1. 인프런 - 스프링핵심원리 강의자료
2. https://sjh836.tistory.com/159
3. https://slenderankle.tistory.com/162
4. https://velog.io/@tataki26/%EB%A6%AC%EC%8A%A4%EC%BD%94%ED%94%84-%EC%B9%98%ED%99%98-%EC%9B%90%EC%B9%99
5. 그외 미친듯한 구글링

728x90
반응형

댓글