// Purpose. Mediator design pattern lab // // Discussion. In this design, each user "knows" its groups, and each group // "knows" its users. The many-to-many mapping between the User class and the // Group class couples them together. If we "objectified" this mapping rela- // tionship several benefits would result: the two classes are no longer // coupled, many mappings could be supported simply by creating many "mediator" // instances, and the "mediator" abstraction could be refined through // inheritance. // // Assignment. // o The new main() and the Mediator implementation are provided. // o Create a Mediator declaration. It's state will include: array of 10 ptrs // to Group, array of 10 ptrs to User, totalGroups int, totalUsers int, 10x10 // matrix of int for the "mapping". It's behavior will include: // addUser(User*), addGroup(Group*), map(User*,Group*), reportUsers(Group*), // reportGroups(User*) // o User::addGroup() and Group::addUser() have been moved to Mediator // o User::groups_ and Group::users_ have been moved to Mediator // o User and Group ctors need to accept a reference to the Mediator instance // o User::reportGroups() and Group::reportUsers() now delegate to the Mediator #include #include class Group; class User { public: User( char* ); const char* getName(); void addGroup( Group* ); void reportGroups(); private: char name_[15]; Group* groups_[10]; int total_; }; class Group { public: Group( char* ); const char* getName(); void addUser( User* ); void reportUsers(); private: char name_[15]; User* users_[10]; int total_; }; User::User( char* name ) { strcpy( name_, name ); total_ = 0; } const char* User::getName() { return name_; } void User::addGroup( Group* group ) { groups_[total_++] = group; } void User::reportGroups() { cout << " " << name_ << ": "; for (int i=0; i < total_; i++) cout << ((i == 0) ? "" : ", ") << groups_[i]->getName(); cout << endl; } Group::Group( char* name ) { strcpy( name_, name ); total_ = 0; } const char* Group::getName() { return name_; } void Group::addUser( User* user ) { users_[total_++] = user; } void Group::reportUsers() { cout << " " << name_ << ": "; for (int i=0; i < total_; i++) cout << ((i == 0) ? "" : ", ") << users_[i]->getName(); cout << endl; } void main( void ) { User* users[4]; Group* groups[4]; users[0] = new User( "Kermit" ); users[1] = new User( "Gonzo" ); users[2] = new User( "Fozzy" ); users[3] = new User( "Piggy" ); groups[0] = new Group( "Green" ); groups[1] = new Group( "ColdBlooded" ); groups[2] = new Group( "Male" ); groups[3] = new Group( "Muppets" ); for (int i=0; i < 4; i++) for (int j=0; j <= i; j++) { groups[i]->addUser( users[j] ); users[j]->addGroup( groups[i] ); } cout << "Groups:" << endl; for (i=0; i < 4; i++) groups[i]->reportUsers(); cout << "Users:" << endl; for (i=0; i < 4; i++) users[i]->reportGroups(); for (i=0; i < 4; i++) { delete users[i]; delete groups[i]; } } // Groups: // Green: Kermit // ColdBlooded: Kermit, Gonzo // Male: Kermit, Gonzo, Fozzy // Muppets: Kermit, Gonzo, Fozzy, Piggy // Users: // Kermit: Green, ColdBlooded, Male, Muppets // Gonzo: ColdBlooded, Male, Muppets // Fozzy: Male, Muppets // Piggy: Muppets #if 0 Mediator::Mediator() { totalGroups_ = 0; totalUsers_ = 0; for (int i=0; i < 10; i++) for (int j=0; j < 10; j++) mappings_[i][j] = 0; } void Mediator::addUser( User* user ) { users_[totalUsers_++] = user; } void Mediator::addGroup( Group* group ) { groups_[totalGroups_++] = group; } void Mediator::map( User* user, Group* group ) { int i, j; for (i=0; i < totalGroups_; i++) if ( ! strcmp( groups_[i]->getName(), group->getName() ) ) break; for (j=0; j < totalUsers_; j++) if ( ! strcmp( users_[j]->getName(), user->getName() ) ) break; mappings_[i][j] = 1; } void Mediator::reportUsers( Group* g ) { int i, j, first; for (i=0; i < totalGroups_; i++) if ( ! strcmp( groups_[i]->getName(), g->getName())) break; for (j=0, first=1; j < totalUsers_; j++) if (mappings_[i][j]) { cout << ((first) ? "" : ", ") << users_[j]->getName(); first = 0; } cout << endl; } void Mediator::reportGroups( User* u ) { int i, j, first; for (j=0; j < totalUsers_; j++) if ( ! strcmp( users_[j]->getName(), u->getName())) break; for (i=0, first=1; i < totalGroups_; i++) if (mappings_[i][j]) { cout << ((first) ? "" : ", ") << groups_[i]->getName(); first = 0; } cout << endl; } void main( void ) { User* users[4]; Group* groups[4]; Mediator mapping; users[0] = new User( "Kermit", mapping ); users[1] = new User( "Gonzo", mapping ); users[2] = new User( "Fozzy", mapping ); users[3] = new User( "Piggy", mapping ); groups[0] = new Group( "Green", mapping ); groups[1] = new Group( "ColdBlooded", mapping ); groups[2] = new Group( "Male", mapping ); groups[3] = new Group( "Muppets", mapping ); for (int i=0; i < 4; i++) { mapping.addUser( users[i] ); mapping.addGroup( groups[i] ); } for (i=0; i < 4; i++) for (int j=0; j <= i; j++) mapping.map( users[j], groups[i] ); cout << "Groups:" << endl; for (i=0; i < 4; i++) groups[i]->reportUsers(); cout << "Users:" << endl; for (i=0; i < 4; i++) users[i]->reportGroups(); for (i=0; i < 4; i++) { delete users[i]; delete groups[i]; } } #endif