SOLID 원칙(w.OOP)

후훗♫·2020년 1월 31일
4

SOLID원칙에 대해 알아보자.

시작에 앞서..

SOLID원칙은 좋은 객체 지향 설계를 위한 5가지 원칙이라고 흔히 말한다.
그럼 좋은 객체 지향 설계는 왜 필요할까?

OOP(Object-Oriented Programming, 객체지향 프로그래밍)를 공부하려고 구글링을 하면,
OOP의 요소(캡슐화, 추상화, 상속, 다형성), SOLID 5원칙 등에 대한 얘기가 많이 나온다.

그러나 정확하게 OOP가 무엇인지는 설명하는 자료는 없었다.
(물론 설명이 없는건 아니지만, 그래서 왜 OOP를 해야하지 라는 느낌은 오지 않았다.)

SOLID 원칙을 정리하려고 찾아보던 중
무엇이 OOP인지 대략적인 느낌을 알려준(?) 블로그가 하나 있었다. *출처링크

  • OOP프로그램을 어떻게 설계해야 하는지에 대한 개념이자 방법론이다.

  • 프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라,
    프로그램을 수많은 '객체'라는 기본 단위로 나누고, 객체 간 상호작용으로 서술한다.

  • 객체는 단순히 데이터의 묶음으로 착각 하기 쉬운데,
    그보다는 하나의 '역할'을 하는 메소드데이터의 묶음으로 봐야한다.

  • 프로그래밍 방식은 절차적 -> 구조적 -> 객체지향 방식으로 발전해왔다.

  • 절차적 프로그래밍은 Input에서 Output의 흐름 관점에서 프로그래밍하는 것이다.

    • 어떤 논리를 어떤 순서로 적는 것이 중요하다.
    • 프로그램의 기능이 중심이고, 프로그램이 취급하는 데이터는 관심이 없었다.
  • 구조적 프로그래밍은 프로그램을 함수 단위로 나누고,
    그 함수 간 호출을 하면서 구동되도록 프로그래밍하는 방법이다.

    • 절차적 프로그래밍을 개선하기 위한 방식이다.
    • 프로그램을 큰 문제라 보고, 이를 해결하기 위해 몇 개의 작은 문제로 나누어
      해결하기 때문에 Top-Down 방식이라고도 한다.
  • 객체지향 프로그맹은 먼저 작은 문제들을 해결할 수 있는 객체들을 만든 뒤,
    이 객체들을 조합해서 큰 문제를 해결하는 방식이다.

    • 구조적 프로그래밍 방식을 개선하기 위한 방식이다.
    • 작은 문제를 해결해서 큰 문제를 해결하는 방식이라 Bottom-up 방식이라고도 한다.
    • <객체>는 일단 한번 독립성/신뢰성이 높게 만들어 놓기만 하면,
      그 후 객체를 수정없이 재사용할 수 있으므로 개발 기간과 비용이 대폭 줄어들게 된다.

'객체''지향'하는 '프로그래밍' 방식을 적용하면,
코드의 재사용, 유지보수의 용이성 등의 장점으로 인해 개발 기간, 비용이 대폭 줄어들 수 있다.

즉, 좋은 객체 지향 설계를 하면, 개발 기간을 단축하고 비용을 줄일 수 있다!

(개발 기간과 비용!!, 이게 핵심인 것 같다.)

시작이 길어졌다.
SOLID 원칙은 Robert C. Martin이 고안한 방법이다.
(martin이 Uncle Bob으로 유명하다던데...왜일까?ㅎㅎ)

항상 코드유연하고, 확장할 수 있고, 유지보수가 용이하고, 재사용할 수 있어야한다.
(why? 안 그럼 반복되는 코드도 계속 따로 따로 써야되고...
코드 하나 고칠려면 수천, 수만줄의 코드를 전부 봐야될 수도 있고...
그럼 개발이 어려워지고... 그럼 개발 기간이 길어지고... 시간과 돈이 든다!)

이러한 코드를 구현하고 적용하기 위해 OOP라는 방법론(패러다임)이 제안되었고,
OOP 방식을 잘 준수하기 위한 원칙으로 SOLID원칙이 제안되었다.

따라서 SOLID 원칙이 무엇인지 이해하고 코드를 작성하는 것이 중요하다고 생각한다.
(물론 잘 안되겠지?ㅎㅎㅎ)

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

  • class(=객체)는 하나의 책임(목적, 역할 등)만 지녀야 한다는 원칙이다.
    • 새로운 기능을 기존 class에 추가하게 되면, (=하나의 class가 여러 기능을 수행하면)
      코드가 길어지고 복잡해진다. 또 나중에 수정해야할 때 시간이 많이 걸릴 수 있다.

얼마전 과제를 수행할 때, 입력된 값이 모두 숫자, 갯수는 5~10개 등 몇가지 검증이 필요했는데,
처음 코드를 짤때는 하나의 함수에서 모든걸 검증하는 방식으로 만들었다.
근데 만약 그 함수에서 에러가 나면 숫자를 검증하는 부분이 잘못된건지,
아니면 입력된 숫자의 갯수를 검증하는 부분이 잘못된건지 하나하나 다 봐야했다...

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

  • class(=객체, 함수 등)는 확장에는 개방 되어야하나, 수정에는 폐쇄 되어야한다.
    (Class should be open for extension, but closed for modification.)
    • 부모 class에서 자식 class를 만들 때, 자식 class에서 기능을 추가/수정할 수 있지만,
      자식 class를 위해 부모 class가 수정될 필요는 없다.

동물 class에서 사람 class, 치타 class를 만든다고 하자.
사람은 직립보행을 하고, 치타는 4족보행을 한다.
따라서 동물 class에 '움직임'의 '기능'만 담긴 method만 만들고,
'움직임'에 대한 '방식'은 하위 class인 사람, 치타 class에서 수정하면 된다.
사람과 치타의 '움직임'을 표현하기 위해 동물 class를 수정할 필요는 없다

3. 리스코프 치환 원칙(Liskov’s Substitution Principle, LSP)

  • 자식 class는 언제나 자신의 부모 class를 교체할 수 있다는 원칙이다.
    • 이 원칙은 1987년 Barbara Liskov가 소개했다.
    • 부모 class의 위치에 자식 class로 넣어도 어떠한 issue도 없어야 한다는 원칙이다.

도형 class가 있다고 가정하자.
➲ "<도형>은 둘레를 가지고, 넓이를 가지고, 각을 가진다."
<도형>의 단어를 교체해 보자. (도형의 class로 사각형 class를 만들었다.)
➲ <사각형>은 둘레를 가지고, 넓이를 가지고, 각을 가진다."
다시한번 <도형>의 단어를 교체해 보자. (도형의 class로 원 class를 만들었다.)
➲"<원>은 둘레를 가지고, 넓이를 가지고, 각을 가진다."
여기서 "각을 가진다" 라는 부분은 어색하다.
따라서 도형 class는 LSP 원칙을 만족하지 않은 설계이다.

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

  • 클라이언트가 자신과 관련이 없는 인터페이스는 구현하지 않아야 한다.
    (Do not force any client to implement an interface which is irrelevant to them.)
    • class는 자신이 사용하지 않는 method는 구현하지 않아야 한다.

ISP와 SRP는 비슷하게 느껴질 수 있다. 아래의 예시를 보자. #출처링크
➲ '게시판' 인터페이스는 '게시판'관련 기능을 수행하고 있어 SRP만족한다.
➲ 일반 사용자 클라이언트(=class)는 인터페이스의 '삭제'를 사용하지 못하므로,
ISP는 만족하지 못한다.

ISP, SRP

5. 의존성 역전 법칙(Dependency Inversion Principle, DIP)

  • 고차원 module/class는 저차원 module/class에 의존하면 안된다는 원칙이다.
    (High-level modules/classes should not depend on low-level modules/classes.)
    (고차원, 저차원 module/Class는 모두 추상화(abstractions)에는 의존한다.)
  • 추상화는 세부사항에 의존해서는 안되고, 세부사항은 추상화에 의존해야한다.
    (Abstractions should not depend upon details. Details should depend upon abstractions.)

부모 classs는 자식 class에 의존해서는 안된다는 원칙이라는데,
당연한 얘기를 하고 있는 것 같아 사례를 찾아보았다..
출처링크
(검색해보면 아이와 장난감, 자동차와 타이어 얘기가 많이 보인다.)
➲ 자동차는 스노우타이어, 일반타이어, 광폭타이어와 같은 디테일한 개념보다,
타이어라는 추상화된 개념에 의존하도록 설계되어야 한다.*
DIP

참고

SOLID Principle in Programming: Understand With Real Life Examples
객체지향 디자인의 5원칙(SOLID 원칙)

profile
꾸준히, 끄적끄적 해볼게요 :)

1개의 댓글

comment-user-thumbnail
2021년 4월 5일

잘 보고 갑니다!

답글 달기