본문 바로가기

소프트웨어 설계1원칙 SOLID『단일책임원칙::SRP』

by Recstasy 2020. 11. 26.

SOLID는 소프트웨어에서 발생하는

다음 7가지 문제를 제거하기 위한 5가지 원칙이다.

 

경직성 시스템을 변경하기 어렵다. 변경을 하려면 시스템의 다른 부분들까지 변경되기 때문이다.
취약성 변경을 하면 시스템에서 그 부분과 개념적으로 아무 관련이 없는 부분까지 무너진다.
부동성 시스템을 다른 시스템에서 재사용할 수 있는 컴포넌트로 구분하기 어렵다.
점착성 옳은 동작을 하는 것이 잘못된 동작을 하는 것보다 더 어렵다.
불필요한 복잡성 직접적인 효용이 전혀 없는 기반구조가 설계에 포함되어 있다.
불필요한 반복 단일 추상 개념으로 통합할 수 있는 반복적인 구조가 설계에 포함되어 있다.
불투명성 읽고 이해하기 어렵다. 그 의도를 잘 표현하지 못한다.

 

 

SOLID의 원론적인 내용과 해결책은 다음과 같다.

 

 

원칙 내용 해결책
단일책임[Single.Responsibility.Principle] 하나의 모듈은 오직 하나의 액터에 대해서만 책임져야 한다 분리
개방폐쇄
[Open.Closed.Principle]
소프트웨어 개체의 행위는 확장할 수 있어야 하지만
이때 산출물을 변경해서는 안 된다
추상클래스
상속
리스코프 치환
[Liscov.Substitution.Principle]
서브타입(sub)은 그것의 기반타입(base)으로
치환 가능해야 한다
상속 메서드명
일치
인터페이스 분리[Interface.Segregation.Principle] 인터페이스는 사용하는 클라이언트를 기준으로
분리해야 한다
추상클래스
다수 생성
의존역전원칙[Dependency.Inversion.Principle] 고수준 모듈이 저수준 모듈에 의해 변경되어서는 안 된다 추상클래스
생성

 

│단일책임원칙 SRP(Single Responsibility Principle)

 

단일책임 원칙은 아래 사진으로 이해할 수 있다.

 

기능분리                                                                                              기능결합

위의 사진에서 드라이버 몸체를 클래스로 생각해보자.

두 개의 드라이버 모두 각자 기능을 구현할 수 있다.

 

왼쪽의 드라이버는 몸체와 여러 개의 드라이버가 결합되어 있으며,

오른쪽은 십자와 일자를 합치려다 삼자가 되어 버렸다. (가정)

 

결론적으로 오른쪽은 드라이버로써 기능을 상실했다.

 

십자 드라이버에 일자 드라이버 기능을 넣으려다

드라이버 전체가 망가져버렸다.

 

단일책임원칙은 왼쪽 드라이버를 지향한다.

일자, 십자를 사용하려는 사람을 액터라고 했을 때,

액터마다 필요한 기능을 각각 분리해서 제공해야 한다.

 

하나의 클래스에 여러명의 엑터를 만족할 수 있는 기능을

모두 집어넣다보면 누구도 사용할 수 없는 클래스가 탄생하게 된다.

 

 

드라이버 기능을 사용하는 몸통 클래스를

자바스크립트 코드로 정리하면 다음과 같다.

 

class DriverBody{

    constructor(){
         this.driver = null;
      }
      
    setDriver(driver){
       this.driver = driver
    }
    
    operate(){
       this.driver.operate()
    }
}

[드라이버 몸통 클래스]

 

DriverBody()클래스는 세부적인 기능이 없다.

드라이버들을 받고, 사용하는 핵심적인 기능만 존재한다.

드라이버의 핵심 기능들은 모두 분리시켜준다.

 

class PillipsOne{
   constructor(){
      this.size = '10mm'
   }
   operate(){
      console.log('십자 드라이버 10mm')
   }
}

class FlatOne{
   constructor(){
      this.size = '10mm'
   }
   operate(){
      console.log('일자 드라이버 10mm')
   }
}

[드라이버 기능(분리)]

 

드라이버를 사용할 때는

필요한 드라이버를 불러온 뒤

operate메서드로 실행한다.(사용)

 

let driverMain = new DriverMain();
let phillipsOne = new PhillipsOne();
let platOne = new PlatOne();

let driverPhillips = driverMain.setDriver(phillipsOne);

//십자 드라이버 사용
driverPhillips.operate();

[드라이버 사용]

 

 

위의 과정을 간단한 다이어그램으로 정리해보자.

 

다이어그램에서 화살표의 방향은 의존성을 관계를 나타내며,

열린 화살표는 '사용'관계를 의미한다.

 

대문자A에서 소문자a,b 방향인 경우,

A클래스는 a,b클래스를 호출한다.

 

 

 

 

반면, a, b클래스는 A클래스를 전혀 호출하지 않으며, 

A클래스의 변경으로부터 보호를 받는다.

 

 

 

댓글

최신글 전체

이미지
제목
글쓴이
등록일