본문 바로가기

💻 개발IT/Design Patterns

2. 객체지향 개념과 설계원칙 - GRASP Principle

GRASP Principles 소개

1. GRASP

  • General Responsibility Assignment Software Patterns 
  • OOAD 구축 시, design model을 만들 때 사용하며 각 Object에 책임(Responsibility)을 부여(Assignment)하는 원칙을 설명

    여기서 Responsibility이란?
    • method의 집합(조합)
    • Knowing Responsibility, Doing Responsibility를 적절히 구분하여 배치

 

2. Modularity (모듈성)

  • 설계의 목표 : 시스템을 모듈로 나누고 적절한 책임을 부여한 행태
  • 방안 : 유사한 함수는 모으고, 작고 잘 정의된 interface를 통해 모듈들이 소통
  • 측정 방법
    • Coupling : 모듈 간의 inter-dependencies 
      • 낮을 수록 좋은 상태
      • 높을 경우 단점
        • 한 클래스가 변경되었을 때 연관된 많은 모듈들도 영향
        • 이해하기 위해서 연관된 모듈도 같이 이해해야함
        • 재사용 어려움
    • Cohension : 한 모듈 내 element들이 얼마나 관련성 있게 응집되어있나
      • 높을수록 좋은 상태
        • 쉽게 이해할 수 있음
        • 재사용
        • Low coupling
      • SRP 연관

 

 

Case Study - POS System

1. Creator Pattern

Object의 Context를 알고 있는 Object에게 생성 책임을 부여

  • 사용하지 않는 경우. contradiction
    • 성능 측면에서 기존 인스턴스를 재사용할 수도 있음
    • 생성해야하는 class가 그룹 단위로 생성하는 게 좋을 경우 
    • 외부에서 wiring 필요한 경우
  • 관련 패턴 : abstract factory, singleton
  • 적용 : SalesLineItem의 인스턴스 생성을 누가?
    • 도메인 모델에서 Sale이 SalesLineItem과 contains관계가 있음

 

2. Information Expert Pattern

데이터를 가지고 있는 object에게 책임을 부여

  • 책임을 할당할 때 가장 많이 쓰이는 원칙
  • Contraindication : Saparation of concerns 과 충돌 될 때
    • 예시 : sale을 DB에 저장하는 책임
      • 보통 Sale 클래스에 있어야 한다고 생각.
      • 하지만, DB 저장은 Sale 뿐만 아니라 다른 클래스도 DB에 저장해야 할 것들이 있어서 모아서 처리하는 것이 좋음
  • 적용 : 판매의 전체 금액 계산은 어디서 해야할까?
    • 주어진 정보를 가지고 있는 곳! 개별 금액은 Product Description에 저장되어있고, line item 정보는 SalesLinItem을 가지고 있고. Sale은 이 모든 정보를 가지고 있음

 

3. Controller Pattern

아래 중 하나 이상이라면 UI layer 뒤의 컨트롤러 역할을 할당함

 1. 시스템 전체, 최상위 Object, 디바이스에서 동작하는 SW나 가장 주요한 서브시스템을 표현하는 경우

 2. 시스템 operation을 구성하는 Use case scenario를 표현하는 경우

  • facade controller의 경우 너무 많은 책임이 부가되면 use-case로 나누거나 다른 객체에게 delegate역할로 한정
  • 장점
    • GUI에 Application logic이 없어 재사용성 높음
  • 적용 : enterItem, endSale 버튼을 눌렀을 때 누가 도메인 레이어로 보내줄 것인가?
    • 시스템 전체로 1개를 만들든지, use case/session별로 나눠서 만들든지..

 

 

4. Low Coupling Pattern

 

  • 설계 관련해서 여러 선택지가 있을 때 변화 영향도(낮은 coupling)가 적은 것 선택
  • Information Expert, High Cohesion 등과 같이 고려될 필요가 있음
  • Stable한 global objects는 고려할 필요 없음 (global한 것은 잘 변하지 않기 때문)
  • 적용 : payment instance를 생성하고 관련된 sale과 연관시키는 일을 누가 해야할까?
    • Register가 Payment를 create하고 Sale과 연관시키거나(real-world와 동일) Sale에게 부탁해서 Sale이 Payment를 생성
    • 전자는 Payment, Sale간의 coupling이 생기게 되고 후자는 Register가 Sale만 알게 되어서 더 좋음

 

 

5. High Cohesion Pattern

높은 응집력을 위해 각 Object가 밀접하게 연관된 책임들만 가지고 있음

  • 적용 : 앞 예제에서 makePayment를 어디에 둘지 고민
    • Option 1은 Register의 책임이 커지지만 Option2는 Sale에게 payment 생성 책임을 delegate함 (cohesion을 높게 해줌)

 

6. Pure Fabrication Pattern

높은 응집도와 낮은 Coupling을 깨지 않고 다른 원칙들을 적용하기 어려운 상황에서는, behavior class를 만들어 책임을 할당하라

  • 설계 단계에서 도메인 모델에서 나오지 않은 새로운 클래스를 만들어내는 경우에 사용
  • 적용 : Sale instance를 DB에 저장
    • Information Expert에서는 해당 정보를 가지고 있는 클래스에 책임을 할당(즉, Sale class)
      • DB operation을 여기저기서 가지고 있어서 재사용 어렵고 duplication 발생하고 sale class는 cohesive 낮게 됨
    • Pure Fabrication에서는 DB에 저장하는 새로운 클래스를 생성

 

7. Polymorphism Pattern

behavior이 다형성을 갖도록 책임을 할당하라

  • 우리가 아는 Polymorphism
  • 단점 (미래를 과도하게 예측하지 말자!)
    • 클래스의 개수가 증가함
    • indirect하여 코드 이해 어려움
  • 적용

 

 

8. Indirection Pattern

두 Object 이상에서 직접적인 연결을 하지말고 중간 intermediate object에게 책임을 할당하라

  • 중재자로 일할 수 있는 class 도입
  • ex) Adapter, Facade, Proxy, Mediator, ...
  • 적용 : Sale이 Tex 계산(위 Polymorphism보면 다양한 타입이 있기 때문)을 TexMasterAdapter에 위임

 

9. Protected Variations Pattern

변화에 영향이 없도록 시스템을 설계하기 위해, 변화할 요소나 불안정한 요소를 식별하여 안정적인 인터페이스를 갖도록 책임을 할당하라

 

 

 

반응형