3

I need to implement a Message Sending functionality based on Roles.

  • Role A: Message should be sent by Email and sms
  • Role B: Message should be sent by only Email
  • Role C: Message should be sent by only sms
  • Role D: Message should be sent by Twitter

I have to accommodate for change regarding what Roles can use what Message Sending functionality, e.g. I need to be able to change Role B to also include sms. Any of the Roles may need any of the Message Sending functionality.

I have considered having one Interface IMessageChannel with a method SendMessage. Then three classes implementing that interface, e.g. Email, SMS and Twitter. I am thinking of using the Strategy pattern and Factory? Is this correct?

What Design Patterns should I consider to implement this?

Gordon
  • 312,688
  • 75
  • 539
  • 559
Sameer More
  • 589
  • 1
  • 6
  • 13
  • In addition to the three classes implementing the IMessageChannel, you also want to create a concrete class MultiChannel that utilizes a Composite pattern so you can put multiple MessageChannels into class and treat them as one. Your Factory can then push the email, sms and twitter MessageChannels into the MultiChannel according to the Role rules and pass that to the using client. – Gordon Jul 20 '13 at 17:41

2 Answers2

7
I am thinking of below solution:
Interface IMessageSystem
{
void Send();
}
Public class Email : IMessageSystem
{
   public void Send()
  {
    console.writeline("Message From Email");
  }
}
Public class SMS : IMessageSystem
{
   public void Send()
  {
    console.writeline("Message From SMS");
  }
}
Public class Twitter : IMessageSystem
{
   public void Send()
  {
    console.writeline("Message From Twitter");
  }
}
Interface ISendMessageStrategy
{
  void SendMessages();
}
Public class SendMessageStrategyForRoleA : ISendMessageStrategy
{
   Public void SendMessages()
  {
    Email objemail = new Email();
   objemail.Send();
   SMS objSMS = new SMS();
   objSMS .Send();
   Twitter objtwitter = new Twitter();
   objtwitter.Send();   
  }
}
Public class SendMessageStrategyForRoleB : ISendMessageStrategy
{
   Public void SendMessages()
  {
   SMS objSMS = new SMS();
   objSMS .Send();
  }
}
Public class SendMessageStrategyForRoleC  : ISendMessageStrategy
{
  Public void SendMessages()
  {  
    Twitter objtwitter = new Twitter();
    objtwitter.Send();
  }
}
Public class SendMessageSystem
{    
   public ISendMessageStrategy sendMessageStrategy;
   List<Keyvaluepair<string,ISendMessageStrategy>> lstkeyval = new List<Keyvaluepair<string,ISendMessageStrategy();
   public SendMessageSystem(string role)
   {
       lstkeyval.add(new keyvaluepair<string,ISendMessageStrategy>("A",new SendMessageStrategyForRoleA()));
       lstkeyval.add(new keyvaluepair<string,ISendMessageStrategy>("B",new SendMessageStrategyForRoleB()));
       lstkeyval.add(new keyvaluepair<string,ISendMessageStrategy>("C",new SendMessageStrategyForRoleC()));
       sendMessageStrategy = lstkeyval.where(x=>x.Key == role).Value;
   }
   public void SendMessage ()
   {
       sendMessageStrategy.SendMessages();
   }
}
public class programme
{
   static void main (string[] args)
   {
     SendMessageSystem objMessage = new SendMessageSystem("A");
     objMessage.SendMessage();
   }
}
Sameer More
  • 589
  • 1
  • 6
  • 13
2

It looks like you need the "Chain of Responsibility" pattern. The example is in java, but it's the same principle.

Make an abstract handler and implement a subclass for every role.

abstract Handler:

class abstract Handler{
 Handler succesor;
 Role ROLE;

 Handler(Handler succesor, Role role){
     this.succesor = succesor;
     this.ROLE = role
 }

 void sendMessage(Message msg, Role role){
    if(role == ROLE){
        this.handleMessage(msg);
    } else if(succesor != null){
        succesor.sendMessage(msg, role);
    }
 }

 abstract void handleMessage(msg);
}

You make than a concrete handler like this:

class RoleAHandler extends Handler{

   RoleAHandler(Handler succesor){
        super(succesor, RoleA);
   }

   @override
   void handleMessage(msg){
        // put handlecode here
   }
}

and use it like:

// initialize
Handler handler = new RoleAHandler(null);
handler = new RoleBHandler(handler);

// usage
handler.sendMessage(new Message, RoleA);

you can make as many roles as you want

Joris W
  • 517
  • 3
  • 16
  • 3
    I don't think CoR is the right pattern here. Quoting the GoF: "Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it." While you could implement it in a way that doesn't stop after an object handled the message, I think this is better suited for a simple Composite Pattern and some Strategies. – Gordon Jul 20 '13 at 17:28