Wzorzec projektowy mediator

Stronę tą wyświetlono już: 92 razy

Opis wzorca projektowego mediator

Wzorzec projektory mediator należy do czynnościowych wzorców projektowych. Jego celem jest udostępnienie interfejsu pośredniczącego w przekazywaniu informacji pomiędzy różnymi nie połączonymi bezpośrednio z sobą obiektami klas, które dziedziczą po wspólnym interfejsie. Klasa pośrednicząca zawiera tablicę interfejsów klas.

Przykład diagramu UML wzorca projektowego mediator

Na poniższym diagramie UML widoczna jest klasa Mediator, która dziedziczy po interfejsie iMediator. Klasa ta zawiera tablicę asocjacyjną umożliwiającą przechowywanie pary danych klucz (std::string) → wartość (iMessage*). Wysłanie wiadomości odbywa się za pomocą metody tej klasy sendMessage zaś dodawanie nowych interfejsów odbywa się za pomocą metody registerObject.

Klasy User i Bot dziedziczą po wspólnym interfejsie iMessage. W moim przypadku dodatkowo zamieściłem wewnątrz interfejsu iMessage pole zawierające wskaźnik na interfejs iMediator. Dzięki temu obiekt klasy sam siebie próbuje zarejestrować oraz (w przypadku obiektów klasy bot) wysyłać automatycznie odpowiedzi.

Przykładowy diagram UML wzorca projektowego mediator
Rys. 1
Przykładowy diagram UML wzorca projektowego mediator

Przykładowa implementacja wzorca projektowego mediator w C++

Listing 1
  1. #include <iostream>
  2. #include <string>
  3. #include <map>
  4. class iMediator;
  5. class iMessage{
  6. protected:
  7. std::string name;
  8. iMediator* mediator;
  9. bool registerUser();
  10. public:
  11. iMessage(std::string name, iMediator* mediator) : name(name), mediator(mediator){
  12. registerUser();
  13. }
  14. virtual void getMessage(std::string from, std::string message) = 0;
  15. };
  16. class iMediator{
  17. public:
  18. virtual bool registerObject(std::string name, iMessage* msg) = 0;
  19. virtual void sendMessage(std::string to, std::string from, std::string message) = 0;
  20. };
  21. bool iMessage::registerUser(){
  22. return mediator->registerObject(name, this);
  23. }
  24. class Mediator : public iMediator{
  25. std::map<std::string, iMessage*> registeredObjects;
  26. public:
  27. void sendMessage(std::string to, std::string from, std::string message){
  28. std::map<std::string, iMessage*>::iterator iTo= registeredObjects.find(to);
  29. if( iTo != registeredObjects.end() ){
  30. iTo->second->getMessage(from, message);
  31. }else{
  32. std::cout << to << " not exist!!!" << std::endl;
  33. }
  34. }
  35. bool registerObject(std::string name, iMessage* msg){
  36. if(msg){
  37. std::map<std::string, iMessage*>::iterator iName = registeredObjects.find(name);
  38. if(iName == registeredObjects.end()){
  39. std::cout << name << " is registered" << std::endl;
  40. registeredObjects[name] = msg;
  41. return true;
  42. }
  43. std::cout << name << " is already registered!!!" << std::endl;
  44. return false;
  45. }
  46. }
  47. };
  48. class User : public iMessage{
  49. public:
  50. User(std::string name, iMediator* mediator) : iMessage(name, mediator){};
  51. virtual void getMessage(std::string from, std::string message){
  52. std::cout << name << " get some message from "<< from << std::endl;
  53. std::cout << message << std::endl << std::endl;
  54. }
  55. void sendMessage(){
  56. std::string to;
  57. std::cout << "Send to who: ";
  58. std::cin >> to;
  59. std::string message;
  60. std::cin.ignore(1);
  61. std::cout << "Message: ";
  62. std::getline(std::cin, message);
  63. mediator->sendMessage(to, name, message);
  64. }
  65. };
  66. class Bot : public iMessage{
  67. int age;
  68. public:
  69. Bot(std::string name, int age, iMediator* mediator) : iMessage(name, mediator), age(age){};
  70. bool registerUser(){
  71. return mediator->registerObject(name, this);
  72. }
  73. virtual void getMessage(std::string from, std::string message){
  74. std::cout << name << " get some message from "<< from << std::endl;
  75. std::cout << message << std::endl << std::endl;
  76. if(message == "what's your name"){
  77. mediator->sendMessage(from, name, std::string("My name is ") + name);
  78. }else if(message == "how old are you"){
  79. char ageBuffor[50];
  80. ltoa(age, ageBuffor, 10);
  81. mediator->sendMessage(from, name, std::string("I'm ") + ageBuffor + " years old");
  82. }else{
  83. mediator->sendMessage(from, name, std::string("I don't understand\nI can ansver only on questions bellow:\n\nwhat's your name\nhow old are you"));
  84. }
  85. }
  86. };
  87. int main(){
  88. Mediator mediator;
  89. User yury("Yury", &mediator);
  90. Bot r2d2("R2D2", 50, &mediator);
  91. int whatToDo = 0;
  92. do{
  93. std::cout << "What you want to do:"<< std::endl << std::endl;
  94. std::cout << "Send a message [0]" << std::endl;
  95. std::cout << "Quit program [not 0]" << std::endl;
  96. std::cin >> whatToDo;
  97. if(!whatToDo){
  98. yury.sendMessage();
  99. }
  100. }while(whatToDo == 0);
  101. std::cin.ignore(100);
  102. std::cin.get();
  103. return 0;
  104. }

Przykładowy wynik działania programu:

Yury is registered
R2D2 is registered
What you want to do:

Send a message [0]
Quit program [not 0]
0
Send to who: R2D2
Message: what's your name
R2D2 get some message from Yury
what's your name

Yury get some message from R2D2
My name is R2D2

What you want to do:

Send a message [0]
Quit program [not 0]
0
Send to who: R2D2
Message: how old are you
R2D2 get some message from Yury
how old are you

Yury get some message from R2D2
I'm 50 years old

Send a message [0]
Quit program [not 0]
0
Send to who: R2D2
Message: what you doing
R2D2 get some message from Yury
what you doing

Yury get some message from R2D2
I don't understand
I can ansver only on questions bellow:

what's your name
how old are you

What you want to do:

Send a message [0]
Quit program [not 0]
Strony powiązane
strony powiązane
  1. sourcemaking.com/design_patterns/mediator - strona opisująca wzorzec projektowy mediator [En]
  2. pl.wikipedia.org - opis tego wzorca na stronie Wikipedii

Komentarze