728x90

어댑터 패턴은 인터페이스간 호환성을 제공하기 위해 사용되는 패턴이다.

 

여행 필수품

우리가 외국가서 콘센트 규격 (전기를 사용하기 위한 인터페이스)이 달라 "어댑터"를 들고 가듯,

 

클라이언트에게 동일한 인터페이스로 제공해야할때 유용하게 쓸 수 있는 패턴이다.

 

(우리는 대한민국 220V 규격의 (ㅇ ㅇ) 콘센트로만 동작하는 기계들을 가지지만, 어댑터를 통해

다른 여러 나라에서도 사용이 가능하다!)

 

 

 

다수의 몬스터를 등장시키는 게임을 만든다고 하자.

 

몬스터 개체를 만들고 특정 버튼을 누르면 진화시키는 요구사항이 있어 evolve() interface가 있다.

class IMonster
{
public: virtual void evolve(void) = 0;
};

디지몬 관련 기능은 신규 기능이라, 여러분이 직접 만들기에 interface를 잘 재정의 하여 만들었다.

class Digimon : public IMonster
{
public: virtual void evolve(void) override
{
  // 진화
}
};

이제 포켓몬 기능을 붙이려 하는데, 문제가 발생했다. 기존에 개발된 포켓몬 모듈을 수정하려 했는데,

 

인터페이스를 상속시킬 수가 없다. 기존 포켓몬 기능의 요구사항중에 외부에서는 "절대" 진화를 못시키는 요구사항이

 

있는 것이다. (최근 디지몬 사이버 슬루스를 재밌게 하고 있는데, 조건만 맞추면 아무때나 진화시킬 수 있는

디지몬에 반해 포켓몬은 진화레벨에 도달해야 자동으로 진화한다. #진화의돌은 무시...)

 

여기서 여러분은 2가지 고민을 한다.

 

1. 이전 요구사항을 무시하고 상속시킨뒤, 관련 사항들을 모두 고친다.

 => 리소스(시간, 돈, 열정, .. )이 많다면 OK다. 아무도 말리지 않는다. 하지만 넘 고된 노가다가 기다린다.

2. 포켓몬 모듈을 건들이지 않고 인터페이스를 맞출 방법 고민

 => 현명하다. 기존 시스템(모듈)을 마구마구 건들이는것은 현명하지 못하다. 잘 설계되어 있건 아니건을 떠나 이미

      잘 동작하고 있는 "콘크리트" 코드이기 때문이다.

 

현명한 여러분은 2번을 생각하여 "어댑터" 패턴을 적용하였다.

class Pokemon
{
//@return : 진화레벨 도달하여 진화한 여부.
public:	bool levelUp(void);
};

class PokemonAdaptor : public IMonster
{
public: PokemonAdaptor(Pokemon* pokemon) : _pokemon(pokemon) {}

public: virtual void evolve(void) override
{
  // 포켓몬이 진화할때까지 레벨업한다.
  while (false == _pokemon->levelUp())
  {
  }

  // 진화
}

private:  Pokemon* _pokemon;
};

이제 이 간단한 adaptor를 도입하여 무사히 프로젝트를 완수하였다.

꼭 위와 같은 형태가 아니어도, 인터페이스 호환을 맞추는 형태라면 여러 형태가 될 수 있다.

 

이런 팔방미인이지만 단점도 존재한다.

 

Adaptor는 클라이언트에게 제공하기 위한 인터페이스와 기존 모듈 양쪽에 "의존성"이 생기기 때문에

 

어느정도 인터페이스가 확립된 두 모듈간 사용하는것이 좋다. 양쪽다 숱하게 수정된다면,

 

Adaptor를 만들어둔 담당자는 스트레스가 많이 올라갈 것이다. ㅋㅋ

728x90

'프로그래밍 > C++' 카테고리의 다른 글

Bridge Pattern  (0) 2021.07.15
Prototype Pattern  (0) 2021.07.13
Factory Pattern - Simple Factory  (1) 2021.02.21
[C++] Cyclic Reference - Weak Reference  (0) 2020.11.11
[C++] Reference Counting  (2) 2020.11.04

+ Recent posts