Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[Clean Architecture] 8. SOLID 원칙 - SRP (Single Responsibility Principle) 본문

Clean Architecture/Clean Architecture 기초

[Clean Architecture] 8. SOLID 원칙 - SRP (Single Responsibility Principle)

jake-kim 2021. 6. 17. 02:13

SRP 개념

  • 개념: 하나의 *모듈은 오직 하나의 *액터에 대해서만 책임져야한다는 원칙
    * 액터(actor): 해당 변경을 요청하는 한 명 이상의 사람을 지칭
    * 모듈: 함수와 데이터 구조로 구성되어 응집된(cohesion) 집합
  • 잘못된 SRP의 의미 주의
    • 잘못된 개념1: 모든 모듈이 단 하나의 일만 해야한다는 잘못된 개념
      -> 모든 모듈이 단 하나의 일만 해야한다는 개념은 '함수'의 정의
    • 잘못된 개념2: 하나의 모듈은 오직 하나의 사용자 또는 이해관계자에 대해서만 책임
      -> 시스템이 동일한 방식으로 변경되기를 원하는 사용자나 이해관계자가 두 명 이상일 수 있기 때문에 잘못된 개념
  • SRP는 메서드와 클래스 수준의 원칙이며, 이보다 상위 수준인 컴포넌트 수준은 공통 폐쇄 원칙(Common Closure Principle)

SRP 위반 사례

Employee클래스는 SRP를 위반

  • 상황
    • calculatePay(): 회계팀에서 기능을 정의하며, CFO 보고를 위해 사용
    • reportHours(): 인사팀에서 기능을 정의하며, COO 보고를 위해 사용
    • save(): DBA가 기능을 정의하며, CTO 보고를 위해 사용
  • 문제
    • 한 클래스가 세 액터에 대해 책임지는 형태

- 예시 1) 우발적 중복
CFO에서 결정한 조치가 COO팀이 의존하는 무언가에 영향을 줄 수 있는 형태

  • ex) calculatePay() 메서드와 reportHours() 메서드가 초과 근무를 제외한 업무 시간을 계산하는 알고리즘을 공유할 때,
    개발자는 코드 중복을 피하기 위해 두 함수에서 공통적인 부분을  regularHours()로 이용

  • 이때 CFO팀에서 초과 근무를 제외한 업무 시간을 계산하는 방식을 약간 수정 했지만,
    인사를 담당하는 COO팀에서는 초과 근무를 제외한 업무 시간을 CFO 팀과는 다른 목적으로 사용하기 때문에 변경을 원하지 않는 상황
  • COO팀은 regularHours()가 바뀐지 모르는 상태에서 계속 쓰고 있으므로 사후 문제가 발생
  • SRP를 통해 액터가 의존하는 코드를 서로 분리하여 설계되었다면, 이런 문제가 발생 방지

- 예시 2) 병합

한 메소드가 여러 액터를 책임진다면 병합이 발생할 가능성이 더욱 높은점 존재

  • 병합 발생: DBA가 속한 CTO팀에서 DB의 Employee테이블 스키마를 수정하고, 인사 담당자가 속한 COO팀에서 reportHours() 메서드의 보고서 포멧을 변경하는 경우 
  • SRP를 통해 액터 의존을 하나만 둔다면 이런 문제 방지

- 우발적 중복, 해결책 ) 데이터와 메서드를 분리

  • 아무런 메서드가 없는 EmployeeData 클래스를 만들어서, 세 개의 클래스가 공유
  • 각 클래스는 자신의 메서드에 반드시 필요한 소스 코드만을 포함하여, 각각 공통 메서드를 사용하지 않도록 의존관계를 분리
  • 단점: 개발자가 세 가지 클래스를 인스턴스화하고 추적해야 하는 단점

- 다수의 인스턴스화 방지, 해결책) 퍼사드(Facade) 패턴

  • 개발자가 세 가지 클래스를 인스턴스화 하지 않고, EmployeeFacade 하나만 인스턴스화하여 사용
  • EmployeeFacade: 다수의 클래스의 객체를 생성하고 요청된 메서드에서, 다른 객체로 위임하는 일을 책임지는 클래스

- 데이터와 가깝게 배치, 해결책) 

  • 개발자에 따라, 업무 규칙을 데이터와 가깝게 배치하는 방식을 선호하는 경우
  • 가장 중요한 메서드는 Employee 클래스에 유지하고 덜 중요한 메서드는 Facade로 구현

  • SRP 잘못된 개념 주의: 모든 클래스는 반드시 단 하나의 메서드를 가져야 한다는 잘못된 개념
    -> 각 클래스에서 private 메서드로 지불, 보고서 생성, 데이터 저장 기능을 구현하는 데 필요한 메서드는 사실상 실제로 훨씬 더 많을 것이기 때문

* 참고: Clean Architecture

Comments