//
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 <iostream.h>
#include
<string.h>
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