Decorator design pattern falls under the category of Structural Design Pattern.
**Structural design pattern emphasizes upon the overall structure of classes and objects in the system
* either by doing class inheritance or by composing objects into larger structures using object composition.
**** Decorator pattern comes handy when we want to add additional responsibilities to the object during run time.
*Additional responsibilities can be added statically by class inheritance also.
*But this will create another problem when we want to add such responsibilities to objects of many classes.
*We may have to create many child classes to support additional new functions.
*
* So instead of creating many child classes of already existing concrete classes,
* we create a new Decorator, and a new Concrete Decorator class that will add new methods and properties to the existing class object during run time.
* This way we are not modifying the existing concrete or legacy classes. Responsibilities to objects can be added during runtime because base class of the object and Decorator class share the same base type.
* And Concrete Decorator class extends the new Decorator.
*** This design pattern does not come initially during system design. It generally comes during maintenance phase or later in the development phase.
Now let’s see the example of decorator design pattern. We even use mobile phone to send text and multimedia messages.
Once the message is sent, the Outbox becomes empty. But sometimes we want to save the sent content message.
To do this, we need to select the option of “Send and Save”, and any message sent this way will be saved inside “Sent” folders.
Here, even if the user may not always want to save the sent messages, it is for sure that he may definitely want to send messages.
Keeping this use case in mind, let’s look into such a class design.
class Program
{
public enum SendMessageOption
{
SendOnly = 0,
SendAndSave = 1
}
private void SendSMS(SendMessageOption option)
{
//Send sms
MobileSMS sms = new MobileSMS("123", "1222", "This is an example of decorator pattern");
if (option == SendMessageOption.SendOnly)
sms.SendMessage();
else if (option == SendMessageOption.SendAndSave)
{
MessageProcessor msgProcess = new MessageProcessor(sms);
msgProcess.SendMessage();
}
}
private void SendMMS(SendMessageOption option)
{
//Send MMS
MobileMMS mms = new MobileMMS("111", "222", new byte[] { 1, 2, 3 });
if (option == SendMessageOption.SendOnly)
mms.SendMessage();
else if (option == SendMessageOption.SendAndSave)
{
MessageProcessor mmsProcess = new MessageProcessor(mms);
mms.SendMessage();
}
}
static void Main(string[] args)
{
Program obj = new Program();
obj.SendSMS(SendMessageOption.SendOnly);
obj.SendSMS(SendMessageOption.SendAndSave);
obj.SendMMS(SendMessageOption.SendOnly);
obj.SendMMS(SendMessageOption.SendAndSave);
Console.ReadKey();
}
}
//
abstract class BaseMessage
{
private string _sender;
private string _recipient;
public string Recipient
{
get { return _recipient; }
set { _recipient = value; }
}
public string MessageSender
{
get { return this._sender; }
set { this._sender = value; }
}
public abstract void SendMessage();
}
class MobileSMS : BaseMessage
{
private string _message;
public string Message
{
get { return _message; }
set { _message = value; }
}
public MobileSMS(string strSender, string strRecipient, string strMessage)
{
this.MessageSender = strSender;
this.Recipient = Recipient;
this.Message = strMessage;
}
public override void SendMessage()
{
//Send Text Message
}
}
class MobileMMS : BaseMessage
{
private byte[] _image;
public byte[] Image
{
get { return _image; }
set { _image = value; }
}
public MobileMMS(string strSender, string strRecipient, byte[] image)
{
this.MessageSender = strSender;
this.Recipient = strRecipient;
this.Image = image;
}
public override void SendMessage()
{
//Send MMS Message.
}
}
//Decorator Pattern
class Decorator : BaseMessage
{
protected BaseMessage message;
public Decorator(BaseMessage message)
{
this.message = message;
}
public override void SendMessage()
{
message.SendMessage();
}
}
//Message Process
class MessageProcessor : Decorator
{
public MessageProcessor(BaseMessage message)
: base(message)
{ }
public void SaveMessage()
{
//Save outgoing messages
}
public override void SendMessage()
{
base.SendMessage();
SaveMessage();
}
}
**Structural design pattern emphasizes upon the overall structure of classes and objects in the system
* either by doing class inheritance or by composing objects into larger structures using object composition.
**** Decorator pattern comes handy when we want to add additional responsibilities to the object during run time.
*Additional responsibilities can be added statically by class inheritance also.
*But this will create another problem when we want to add such responsibilities to objects of many classes.
*We may have to create many child classes to support additional new functions.
*
* So instead of creating many child classes of already existing concrete classes,
* we create a new Decorator, and a new Concrete Decorator class that will add new methods and properties to the existing class object during run time.
* This way we are not modifying the existing concrete or legacy classes. Responsibilities to objects can be added during runtime because base class of the object and Decorator class share the same base type.
* And Concrete Decorator class extends the new Decorator.
*** This design pattern does not come initially during system design. It generally comes during maintenance phase or later in the development phase.
Now let’s see the example of decorator design pattern. We even use mobile phone to send text and multimedia messages.
Once the message is sent, the Outbox becomes empty. But sometimes we want to save the sent content message.
To do this, we need to select the option of “Send and Save”, and any message sent this way will be saved inside “Sent” folders.
Here, even if the user may not always want to save the sent messages, it is for sure that he may definitely want to send messages.
Keeping this use case in mind, let’s look into such a class design.
class Program
{
public enum SendMessageOption
{
SendOnly = 0,
SendAndSave = 1
}
private void SendSMS(SendMessageOption option)
{
//Send sms
MobileSMS sms = new MobileSMS("123", "1222", "This is an example of decorator pattern");
if (option == SendMessageOption.SendOnly)
sms.SendMessage();
else if (option == SendMessageOption.SendAndSave)
{
MessageProcessor msgProcess = new MessageProcessor(sms);
msgProcess.SendMessage();
}
}
private void SendMMS(SendMessageOption option)
{
//Send MMS
MobileMMS mms = new MobileMMS("111", "222", new byte[] { 1, 2, 3 });
if (option == SendMessageOption.SendOnly)
mms.SendMessage();
else if (option == SendMessageOption.SendAndSave)
{
MessageProcessor mmsProcess = new MessageProcessor(mms);
mms.SendMessage();
}
}
static void Main(string[] args)
{
Program obj = new Program();
obj.SendSMS(SendMessageOption.SendOnly);
obj.SendSMS(SendMessageOption.SendAndSave);
obj.SendMMS(SendMessageOption.SendOnly);
obj.SendMMS(SendMessageOption.SendAndSave);
Console.ReadKey();
}
}
//
abstract class BaseMessage
{
private string _sender;
private string _recipient;
public string Recipient
{
get { return _recipient; }
set { _recipient = value; }
}
public string MessageSender
{
get { return this._sender; }
set { this._sender = value; }
}
public abstract void SendMessage();
}
class MobileSMS : BaseMessage
{
private string _message;
public string Message
{
get { return _message; }
set { _message = value; }
}
public MobileSMS(string strSender, string strRecipient, string strMessage)
{
this.MessageSender = strSender;
this.Recipient = Recipient;
this.Message = strMessage;
}
public override void SendMessage()
{
//Send Text Message
}
}
class MobileMMS : BaseMessage
{
private byte[] _image;
public byte[] Image
{
get { return _image; }
set { _image = value; }
}
public MobileMMS(string strSender, string strRecipient, byte[] image)
{
this.MessageSender = strSender;
this.Recipient = strRecipient;
this.Image = image;
}
public override void SendMessage()
{
//Send MMS Message.
}
}
//Decorator Pattern
class Decorator : BaseMessage
{
protected BaseMessage message;
public Decorator(BaseMessage message)
{
this.message = message;
}
public override void SendMessage()
{
message.SendMessage();
}
}
//Message Process
class MessageProcessor : Decorator
{
public MessageProcessor(BaseMessage message)
: base(message)
{ }
public void SaveMessage()
{
//Save outgoing messages
}
public override void SendMessage()
{
base.SendMessage();
SaveMessage();
}
}
No comments:
Post a Comment