Seongwon Lim

[OOAD] GRASP Pattern이란? 본문

OOAD

[OOAD] GRASP Pattern이란?

limsw 2022. 5. 24. 16:08
반응형

 서론

이번 글에서는 GRASP Pattern 이라는 Object에 책임(또는 역할)을 부여하여 Object-Oriented 디자인을 설계하는 방법을 다루는 9가지 원칙을 다루고자 한다.

 

GRASP Pattern은 일반적으로 디자인 패턴이라고 불리우는 것들처럼 구체적인 구조는 없지만, 실제로 프로그램을 개발할 때 적용되는 각각의 디자인 패턴들은 GRASP 패턴이 제시하는 철학를 각 상황에서 구체적으로 구현하는 것으로 이해할 수 있다.

 

GRASP 패턴은 9가지로 구성되어 있으며 지금부터 하나씩 살펴보자.

1. Creator Pattern

객체의 생성은 생성되는 객체의 Context를 알고 있는 다른 객체가 있다면, 해당 Context를 알고 있는 객체에 부여하라는 의미이다.

 

예를 들어, A 객체와 B 객체의 관계의 관계가 다음 중 하나라면 A의 생성을 B의 역할로 부여할 수 있다.

  • B 객체가 A 객체를 포함하고 있다.
  • B 객체가 A 객체의 정보를 기록하고 있다.
  • A 객체가 B 객체의 일부이다.
  • B 객체가 A 객체를 긴밀하게 사용하고 있다.
  • B 객체가 A 객체의 생성에 필요한 정보를 가지고 있다.

Creator를 조금 간단하게 설명하면 A라는 객체를 누가 생성을 할 것인가를 정의하는 것이다. 위 예시에서는 A라는 객체를 B가 만들도록 했으므로 B가 A의 Creator가 되는 것이다.

2. Information Expert (또는 Expert)

역할을 수행할 수 있는 정보(Information)를 가지고 있는 객체에 역할을 부여하라는 원칙이다.

단순해보이지만 Expert 원칙은 객체지향의 기본 원리 중 하나이다. 객체는 데이터와 처리 로직이 함께 묶여 있는 것이고, 자신의 데이터를 감추고자 하면 오직 자기 자신의 처리 로직에서만 데이터를 처리하므로 외부에는 그 기능(역할)만을 제공해야 한다.

따라서 위 그림과 같이 각각의 클래스는 서로 다른 정보를 가지고 있기 때문에 각각 다른  역할을 수행한다고 볼 수 있다.

Information Expert Pattern을 적용함으로써 얻을 수 있는 장점은 다음과 같다.

  • 캡슐화를 유지할 수 있어 커플링이 낮아진다. (Low Coupling)
  • 클래스가 가벼워지고, 이해하기 쉽고, 응집력이 높아진다. (High Cohesion)

3. Controller

시스템 이벤트(사용자의 요청)를 처리할 객체를 만들어서 시스템 내부로 요청을 적절하게 처리하라는 원칙이다.

조금 더 쉽게 생각하면 Controller는 시스템, 서브시스템으로 들어오는 외부 요청을 처리하는 최초 객체라고 생각할 수 있다.

 

Controller는 왜 필요할까?

만약 어떤 서브 시스템안에 있는 각 객체의 기능을 사용할 때, 직접적으로 각 객체에 접근하게 된다면 서브시스템과 외부의 Coupling이 증가할 수 있다. 커플링이 높아지면 서브시스템의 특정 객체를 수정할 경우에 외부에 주는 영향이 커질 수 있게 된다.

위 그림의 오른쪽 다이어그램을 보면 컨트롤러를 이용해서 각 객체들의 응집력을 높인 것이다.

왼쪽 그림은 하나의 클래스에 여러 기능이 정의되어 있기 때문에 응집력이 낮아질 수 있다. 응집도는 해야할 일이 특정 위치에 적절하게 있는지를 나타내는 것이기 때문에 응집력을 높게 유지하는 것이 좋은 설계를 하는 것이라고 볼 수 있다.

4. Low Coupling

Low Coupling은 Object 간 상호의존성이 낮아지도록 역할을 부여하라는 원칙이다.

Object-Oriented 시스템은 각 객체들과 그들 간의 상호작용을 통하여 요구사항을 충족시키는 것을 기본으로 한다. 따라서 각 객체들 사이에 커플링이 존재하지 않을 수는 없지만 최대한 불필요한 커플링을 제거하여 객체 사이, 서브 시스템 사이에 연관성을 낮추는 것이 목표이다.

 

커플링은 왜 낮춰야 할까?

  • 낮은 의존성을 유지하고 재사용성을 높이기 위해
  • 물론, 유지보수성도 좋아진다. → 커플링이 낮다면 연결된 것만 수정하면 되기 때문이다.

5. High Cohesion

각 객체가 밀접하게 연관된 역할들만 가지도록 역할을 부여하라는 원칙이다.

한 객체, 한 서브 시스템이 자기 자신이 부여받은 역할을 수행하도록 구성하면, 자신이 부여 받은 역할을 충족시키기 위해 다른 객체나 시스템을 참조하는 일이 적어지게 된다. 이것은 다른 객체, 시스템과의 연관성을 떨어뜨리는 것이기도 하므로 Low Coupling도 동시에 충족할 수 있게 된다.

High(Low) Coupling, Cohesion 이미지를 참고하여 개념을 이해하는데 도움이 되었으면 좋겠다.

정리해보면, Object Oriented 시스템을 설계할 때 Low coupling, High Cohesion을 동시에 유지하는 것이 좋은 설계라고 할 수 있다.

6.  Polymorphism

객체의 종류에 따라 행동이 바뀌는 경우 Polymorphism(다형성)을 적용하라는 원칙이다.

  • 다형성은 간단하게 이해하면 서비스에 이름이 유사하게 결정이 되는데, Object가 다름에 따라서 다른 서비스를 진행하는 것이다.
  • 예를 들어 Animal Class에 move() 메서드가 있다고 가정해보면
    • Dog Class의 move()는 강아지가 달리는 것을 의미할 수 있고
    • Cat Class의 move()는 고양이가 걸어가는 것을 의미할 수 있으며
    • Bird Class의 move()는 날아가는 것을 의미할 수 있다.

예를 들어, 객체 종류에 따라서 수행하는 일이 바뀌는 경우 객체의 종류를 체크하는 조건문(if, switch)을 사용하는 것이 아니라 다형성을 이용하여 클래스를 세분화 하는 것이다.

7. Pure Fabrication

High Cohesion, Low Coupling을 해치고 싶지 않은 경우, 그리고 GRASP를 잘 적용해서 책임을 잘 만들어나가고 싶은 경우에 복잡한 경우가 생길 수 있다. Pure Fabrication은 이런 경우 기능적인 역할을 별도로 한 곳으로 모으라는 원칙이다.

 

예를 들어, 데이터베이스 관련된 작업을 하는 DAO(Data Access Object) 객체를 Pure Fabrication으로 볼 수 있다.

유저 정보를 데이터베이스에 삽입하는 경우, Information Expert에 따르면 유저정보를 가지고 있는 유저 객체가 DB에 접근하는 것은 맞지만 Low Coupling, High Cohesion 원칙을 위반한다.

 

그 이유는 데이터베이스에 접근하는 책임(역할)이 여러 곳에 분산되기 때문이다.

따라서 DAO라는 별도의 객체를 만들고 데이터베이스에 접근하는 책임을 할당하는 것이다.

8. Indirection

직접 부르지 않고 간접적으로 불러서 Object간 커플링을 낮춰 재사용성을 강화시키는 것이다.

그래서 2개의 Object는 intermediate object(중간 객체)에 책임(일)을 할당한다. 이러한 경우 두 객체 사이의 직접적인 Coupling을 피할 수 있다. 여기서 말하는 다른 객체란 인터페이스가 될 수 있으며 주로 인터페이스인 경우가 많다.

9. Protected Variations (PV)

변형을 하고 싶을 때 제한을 할 수 있는 여지를 제공하는 원칙이다. 조금 더 간단하게 설명하면 변경될 여지가 있는 곳에 안정된 인터페이스를 정의하는 원칙이라고 생각할 수 있다.

  • Problem : 서브시스템, 오브젝트, 시스템은 설계를 할 때 Element 안에서 변형, 불안정한 일이 일어난다면 다른 Element에 적절하지 않은 영향을 끼칠 수 있다. → 그래서 그것을 제한하겠다는 것이다.
  • Solution : variation, instability를 어느정도 예측해서 안정된 인터페이스(stable interface)를 만든다.

출처

  • https://www.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS8586826397
Comments