중재자 패턴은 한 집합에 속해있는 객체의 상호작용을 캡슐화하는 객체를 정의하는 패턴이다. 객체들이 직접 서로를 참조하지 않도록하여 객체 사이에 결합도를 낮추며 개발자가 객체의 상호작용을 독립적으로 다양화시킬 수 있게 한다.
활용성
- 여러 객체가 잘 정의된 형태지만 복잡한 상호작용을 가질 때
- 한 객체가 다른 객체를 너무 많이 참조하고 너무 많은 의사소통을 해서 재사용하기 힘들 때
- 여러 클래스에 분산된 행동들이 상속 없이 상황에 맞게 수정되어야 할 때
중재자 패턴 사용에 따른 결과
서브클래싱 제한
중재자는 다른 객체 사이에 분산된 객체의 행동들을 하나의 객체로 국한한다. 이 행동을 변경하고자 한다면 Mediator 클래스를 상속하는 서브 클래스만 만들면 되며 Colleague 클래스는 재사용 가능하다.
Colleague 객체 사이의 종속성 저하
중재자는 행동에 참여하는 객체간 결합도를 낮춘다.
객체 프로토콜 단순화
중재자는 다 : 다의 관계를 일 : 다의 관계로 축소시킨다.
객체간 협력 방법 추상화
객체 사이에 독립적인 중재자를 두고 이것을 통해 캡슐화 함으로써 사용자는 객체의 행동과 상관없이 객체간 연결 방법에만 집중할 수 있다.
통제 집중화
중재자 패턴은 모든 상호작용이 중재자 안에서만 이루어지기 때문에 어느 객체보다도 제일 복잡해질 가능성이 크다.
중재자
구조
중재자의 구조는 다음과 같다.
C++ 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| void MediatorPattern::MediatorPattern() { IChatClient* client1 = new ChatClient("Client1"); IChatClient* client2 = new ChatClient("Client2"); IChatClient* client3 = new ChatClient("Client3"); IChatClient* client4 = new ChatClient("Client4"); IChatClient* client5 = new ChatClient("Client5"); IChatMediator* mediator = new ChatMediator(4, client1, client2, client3, client4);
client1->setMediator(mediator); client2->setMediator(mediator); client3->setMediator(mediator); client4->setMediator(mediator);
client1->send("Hello"); client2->send("Hi Client1"); client3->send("Bye");
client3->quit();
mediator->addClient(client5); client5->setMediator(mediator);
client5->send("I`m noob"); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class IChatMediator; class IChatClient { public: virtual ~IChatClient() {} virtual void setMediator(IChatMediator* mediator) = 0; virtual void display(std::string message) = 0; virtual void send(std::string message) = 0; virtual void quit() = 0; };
class ChatClient : public IChatClient { IChatMediator* mediator; std::string name; public: ChatClient(IChatMediator* mediator, std::string name) : mediator(mediator), name(name) {} ChatClient(std::string name) : name(name) {}
void setMediator(IChatMediator* mediator) override { this->mediator = mediator; }
void display(std::string message) override { std::cout<<name<<" : "<<message<<std::endl; }
void send(std::string message) override { mediator->mediate(this, "From " + this->name + " : " + message); }
void quit() override { mediator->removeClient(this); } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| class IChatClient; class IChatMediator { public: virtual ~IChatMediator() {} virtual void addClient(IChatClient* chatClient) = 0; virtual void removeClient(IChatClient* chatClient) = 0; virtual void mediate(IChatClient* chatClient, std::string message) = 0; };
class ChatMediator : public IChatMediator { std::vector<IChatClient*> clients;
public: ChatMediator() {}
ChatMediator(int args, ...) { va_list ap;
va_start(ap, args); for(int i = 0; i < args; i++) clients.push_back(va_arg(ap,IChatClient*)); va_end(ap); }
void addClient(IChatClient* chatClient) override { clients.push_back(chatClient); }
void removeClient(IChatClient* chatClient) override { for(auto it = clients.begin(); it != clients.end(); ++it) if(*it == chatClient) clients.erase(it); }
void mediate(IChatClient* chatClient, std::string message) override { for(auto client : clients) if(client != chatClient) client->display(message); } };
|
java 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Client { public static void main(String[] args) { ChatClient client1 = new ChatClientImpl("Client1"); ChatClient client2 = new ChatClientImpl("Client2"); ChatClient client3 = new ChatClientImpl("Client3"); ChatClient client4 = new ChatClientImpl("Client4"); ChatClient client5 = new ChatClientImpl("Client5"); Mediator mediator = new MediatorImpl(client1, client2, client3, client4);
client1.setMediator(mediator); client2.setMediator(mediator); client3.setMediator(mediator); client4.setMediator(mediator);
client1.send("Hello"); client2.send("Hi Client1"); client3.send("Bye");
client3.quit();
mediator.addClient(client5); client5.setMediator(mediator);
client5.send("I`m noob"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public interface ChatClient { void setMediator(Mediator mediator); void display(String message); void send(String message); void quit(); }
public class ChatClientImpl implements ChatClient{ private Mediator mediator; private String name;
public ChatClientImpl(String name) { this.name = name; }
@Override public void setMediator(Mediator mediator) { this.mediator = mediator; }
@Override public void send(String message) { mediator.mediate(this, "From " + name + " : " + message); }
@Override public void display(String message) { System.out.println(name + " : " + message); }
@Override public void quit() { mediator.removeClient(this); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public interface Mediator { void addClient(ChatClient client); void removeClient(ChatClient client); void mediate(ChatClient client, String message); }
public class MediatorImpl implements Mediator{ private List<ChatClient> clients;
public MediatorImpl() { this.clients = new ArrayList<>(); }
public MediatorImpl(ChatClient client) { this(); clients.add(client); }
public MediatorImpl(ChatClient client, ChatClient... varClients) { this(client); for(ChatClient chatClient : varClients) clients.add(chatClient); }
@Override public void addClient(ChatClient client) { clients.add(client); }
@Override public void removeClient(ChatClient client) { clients.remove(client); }
@Override public void mediate(ChatClient client, String message) { for(ChatClient chatClient : clients) if(!chatClient.equals(client)) chatClient.display(message); } }
|