ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TIL] OOD (Object-Oriented Design) principles - SOLID
    TIL 2024. 6. 9. 23:23

     

     > 강의를 수강하고 이전에 자세히 알지 못했던 객체 지향 설계 (OOD)의 5가지 원칙인 SOLID에 대해 정리해보았다.

     

    학습 키워드: Object-Oriented Design, SOLID

     

    Object-Oriented Design

    1) SOLID:

     객체 지향 프로그래밍(OOP)에서 객체 지향적인 설계를 위해 지켜야 하는 다섯가지 원칙이 있는데, 이를 SOLID 라고 부른다. SOLID는 각각 단일 책임(Single Responsibility) 원칙, 개방-폐쇄(Open-Close) 원칙, 리스코프 치환(Liskov Substitution) 원칙, 인터페이스 분리(Interface Segregation) 원칙, 그리고 의존성 역전(Dependency Inversion) 원칙이 있다.

     

    2) Single Responsibility Principle (SRP):

     단일 책임 원칙이란, 하나의 객체가 단 하나의 책임을 가지도록 하는 원칙으로, 상속 시 기능의 충돌이 일어나는 것을 최소화 할 수 있도록 도와주는 효과가 있다. 실제로 작동만 하면 되는 코드를 쓰는 것에 집중하는 경우가 많이 때문에 개발자들이 가장 잘 알면서도 가장 많이 무시하는 원칙이라고 한다.

     

     

    3) Open-Close Principle (OCP):

     개방-폐쇄 원칙은 확장에는 열려있고, 변경에는 닫혀있는 형태를 말하는데, 새로운 기능의 추가에서 기존 클래스의 기능을 수정하지 않고 새로운 기능만 추가할 수 있는 구조여야 한다는 의미다.

    /** OCP Before **/
    function calculator(nums, option) {
      let result = 0;
      for (const num of nums) {
        if (option === "add") result += num; // option이 add일 경우 덧셈 연산을 합니다.
        else if (option === "sub") result -= num; // option이 sub일 경우 뺄셈 연산을 합니다.
        // 새로운 연산(기능)을 추가 하기 위해서는 함수 내부에서 코드 수정이 필요합니다.
      }
      return result;
    }
    
    console.log(calculator([2, 3, 5], "add")); // 10
    console.log(calculator([5, 2, 1], "sub")); // -8

     강의 노트에서는 계산기를 예시로 들었는데, 덧셈 뺄셈 기능만 하는 계산기가 위와 같이 구현되어 있다면, 곱셈과 나눗셈을 추가할 때 덧셈 뺄셈이 구현되어있던 부분에서 if 구문을 추가하게 되어 기존 코드를 수정하는 형태가 되기 때문에 OCP에 위배된다.

     

     JS에서는 callback 함수를 이용하여 각 연산을 별개의 함수로 구현한 뒤, 계산이 필요할 때 마다 해당 함수를 calculator 함수의 인자로 넘겨서 루프에서 각 숫자에 대해 해당 callback을 사용하는 방식으로 구현하여 OCP의 조건을 충족할 수 있다.

     


    4) Liskov Substitution Principle (LSP):

     리스코프 치환 원칙은 어떤 객체를 그 하위 객체로 치환할 때 별다른 추가 작업이 없어도 동작에 아무런 문제가 생기지 않아야 한다는 원칙이다. 다른 말로 하면, 하위 객체는 상위 객체에서 주어진 input 만으로도 버그 없이 동작할 수 있어야 한다는 뜻이 된다. 

     


    5) Interface Segregation Principle (ISP):

     인터페이스 분리 원칙은 각각의 기능들을 인터페이스 단위로 분리하여 새로운 하위 객체를 정의할 때 필요한 기능만 implement 할 수 있도록 하는 것이다. SRP랑 비슷한 느낌이라고 생각했지만 약간 다른데, SRP는 클래스가 한 가지 기능에만 집중하게 만드는 것이 목적이고, ISP는 상속받는 클래스가 인터페이스에서 불필요한 기능을 상속받지 않도록 하는 것이 목적이라서 약간 다른 개념이다. 강의 노트에선 프린터 복합기를 예시로 들었는데, 프린터, 팩스, 그리고 스캐너를 각각 다른 인터페이스로 둬서 추후 프린터 모델을 구현할 때 필요한 기능을 가진 인터페이스만 골라서 구현할 수 있게 하는 것이다.

     


    6) Dependency Inversion Principle (DIP):

     의존성 역전 원칙은 구체적 구현(concretion)이 아닌 추상화(absctraction)에 의존해야하며, 상위 객체가 하위 객체에 의존해서는 안된다는 원칙이다. 그냥 말로만 보면 어렵지만 예시를 들면 추상화된 상위 클래스를 통해 하위 객체를 생성하는, 객체 지향에서 많이 쓰는 그 방식을 말하는 것이다. 강의 노트에서는 Formatter 라는 abstact 클래스를 두고, ReportReader에서 constructor의 parameter로 Formatter를 받게 설정하여 실제로 ReportReader를 사용하게 될 때 Formatter의 하위 클래스인 XMLFormatter, JSONFormatter를 인자로 넘겨줄 수 있는 형태를 의미한다.

     

     

     

    --

     

    REFERENCES:

     

     

    5.2 객체 지향 설계 5 원칙 (SOLID) | Notion

    <Goal> 1. 객체 지향 설계 5원칙(SOLID)에 대해 알아봅니다. 2. 객체 지향 설계 원칙을 통해 어떤 이점을 얻을 수 있는지 알아봅니다.

    teamsparta.notion.site

     > 강의 노트, "5.2 객체 지향 설계 5 원칙 (SOLID)"

    728x90
Designed by Tistory.