프로그램을 작성하다 보면 클래스 간의 관계를 이루게 되는데 그 클래스들이 많아지게 되면 그 관계를 이해하는 것도 어려워지게 됩니다. 구현 측면에서도 각 클래스들이 서로 순환 참조를 해야 하기 때문에 프로그램이 지저분해지게 됩니다. 이처럼 복잡한 관계를 회피할 수 있는 방법으로는 각각의 클래스나 객체 간의 커뮤니케이션을 특정 클래스 중재해주는 형태로 변환시킴으로써 M:N의 관계를 M:1로 간소화시킬 수 있습니다.
자동판매기 시뮬레이션 프로그램을 작성하기 위해 현재 상태를 표시하기 위한 램프, 요청 시 커피를 만드는 믹서, 동전을 관리하는 동전 박스, 지폐를 관리하는 지폐 박스와 같은 4가지 클래스가 복잡한 관계로 구성되어 있습니다. 각 클래스들은 동작, 상태를 위해 서로의 클래스들과 커뮤니케이션을 해줘야 하는데 어떤 식으로 설계하는 것이 좋을지를 소개합니다.
간단히 생각했을 때는 각 클래스들이 필요한 동작을 하기 위해 서로의 객체를 참조하는 방식으로 구성이 되어야 합니다. 각 객체들은 인터페이스를 통해 서로 접근을 해주게 됩니다.
이렇게 M:N의 관계를 가지면서 각 클래스들이 자신이 맡은 역할을 수행하기 위해 여러 클래스들을 참조해야 합니다. 이렇게 작성이 된다면 프로그램이 어려워질 뿐 아니라 새로운 기능을 맡은 클래스가 추가가 된다면 엄청나게 복잡해지게 됩니다. 그리고 클래스들이 모두 순환참조를 하고 있기 때문에 구현 측면에서도 여러 가지 귀찮은 문제가 발생하게 됩니다. 객체를 생성할 때 일일이 필요한 객체들을 참조해줘야 하는데 객체 생성이 모두 일어난 다음에 또다시 각 객체들을 전달하면서 참조를 시켜줘야 합니다.
int main()
{
Lamp l;
CoinBox c;
BillBox b;
Mixser m;
l.setCoinBox(&c);
l.setBillBox(&b);
l.setMixser(&m);
...;
}
이런 문제를 해결하기 위해 각 클래스들이 직접적인 관계를 맺는것이 아니라 클래스 간 중재를 맡아줄 클래스를 별도로 정의해서 사용하는 것이 좋습니다.
class Lamp;
class Mixer;
class CoinBox;
class BillBox;
class Mediator {
Mediator(Lamp* pLamp, Mixer* pMixer, CoinBox* pCoin, BillBox* pBill) :
pLamp(m_Lamp), pMixer(m_Mixser), pCoin(m_Coin), pBill(m_Bill) {}
bool IsResourceLack();
bool IsCoinLack();
void InformMixerState();
...; // 각 인터페이스들은 참조되고 있는 객체들로부터 인터페이스를 호출
private:
Lamp* m_Lamp;
Mixer* m_Mixer;
CoinBox* m_Coin;
BillBox* m_Bill;
};
int main()
{
Lamp l;
Mixer m;
CoinBox c;
BillBox b;
Mediator m(&l, &m, &c, &b);
m.setMediator(&m);
c.setMediator(&m);
l.setMediator(&m);
b.setMediator(&m);
...;
}
위처럼 객체간에객체 간에 관계를 간소화하기 위해 클래스를 두어 구성하는 방식을 중재자 패턴이라고 합니다. 중재자 패턴을 사용하면 객체 간에 순환 참조도 필요 없어지고 복잡한 관계없이 객체 간 중재자 객체를 통해서 서로 커뮤니케이션을 하게 됩니다. 중재자 패턴을 사용할 때 하나 고려할 사항은 중재자 객체와 연동되어 있는 객체들에게 이벤트가 발생했을 때 어떻게 알려주는가 인데 이럴 때는 중재자 객체에게 특정 이벤트가 발생했음을 알려주는 인터페이스를 별도로 정의해서 사용해서 연동되어 있는 객체들은 이벤트의 발생을 중재자 객체에게 알려줄 수 있게 됩니다.
'Programming > C++' 카테고리의 다른 글
C++ 옵저버 패턴 (0) | 2021.06.13 |
---|---|
C++ 메멘토 패턴 (0) | 2021.06.10 |
C++ 이터레이터 패턴 (0) | 2021.06.06 |
C++ 인터프리터 패턴 (0) | 2021.06.06 |
C++ 커맨드 패턴 (0) | 2021.05.30 |