26. January 2010
geoffrey
This the second part of the series of Coding Kata’s. Here we’ll explore the Decorator pattern.
This is the user story:
You need to send alerts to your customers when a new product is available.
An Alert is represented by the Alert Class:
public class Alert
{
public String DestinationAddress { get; set; }
public String SenderAddress { get; set; }
public String Content { get; set; }
public string Log { get; set; }
}
Classes used to send the Alerts implement the following interface:
public interface ISender
{
void Send(Alert alert);
}
- Create an Alerter class that send the appropriate alerts.
- Alerts are always send by e-mail.
- Customers can also subscribe to receive alerts via sms and/or through messenger.
- Use the Decorator pattern to configure the Alerter
You do not need to use real infrastructure code to send the alert, just append a string that contains the Sender through which the message was send.
->Append the following text to the Alert.Log when the message is send by:
- e-mail : “Message was send by e-mail”
- sms : “Message was send by sms”
- messenger: “Message was send by messenger”
Show Solution Hide Solution
using System;
using NUnit.Framework;
namespace Kata2
{
#region Tests
[TestFixture]
public class AlerterTest
{
[Test]
public void SendAlert_ThroughEmailSender_SendEmail()
{
//Arrenge
var sender = new EmailSender();
var subject = new Alerter(sender);
var message = new Alert();
//Act
subject.Send(message);
//Assert
Assert.AreEqual(LogConstants.SendByEmail, message.Log);
}
[Test]
public void SendAlert_ThroughSmsSender_SendEmailAndSms()
{
//Arrenge
var emailSender = new EmailSender();
var smsSender = new SmsSender(emailSender);
var subject = new Alerter(smsSender);
var message = new Alert();
//Act
subject.Send(message);
//Assert
Assert.AreEqual(LogConstants.SendByEmail + LogConstants.SendBySMS, message.Log);
}
[Test]
public void SendAlert_ThroughMessengerSenderWithEmailSender_SendEmailAndMessengerAlert()
{
//Arrenge
var emailSender = new EmailSender();
var messengerSender = new MessengerSender(emailSender);
var subject = new Alerter(messengerSender);
var message = new Alert();
//Act
subject.Send(message);
//Assert
Assert.AreEqual(
LogConstants.SendByEmail + LogConstants.SendByMessenger
, message.Log
);
}
[Test]
public void SendAlert_ThroughMessengerSenderWithSmsSender_SendEmailAndSmsAndMessengerAlert()
{
//Arrenge
var emailSender = new EmailSender();
var smsSender = new SmsSender(emailSender);
var messengerSender = new MessengerSender(smsSender);
var subject = new Alerter(messengerSender);
var message = new Alert();
//Act
subject.Send(message);
//Assert
Assert.AreEqual(
LogConstants.SendByEmail + LogConstants.SendBySMS + LogConstants.SendByMessenger
, message.Log
);
}
}
#endregion
#region Decorators
public class MessengerSender: ISender
{
private ISender _sender;
public MessengerSender(ISender sender)
{
_sender = sender;
}
public void Send(Alert message)
{
_sender.Send(message);
//Here we would send a messenger alert
message.Log += LogConstants.SendByMessenger;
}
}
public class SmsSender : ISender
{
private ISender _sender;
public SmsSender(ISender sender)
{
_sender = sender;
}
public void Send(Alert message)
{
_sender.Send(message);
//Here we would send the SMS
message.Log += LogConstants.SendBySMS;
}
}
#endregion
#region Component
public class EmailSender : ISender
{
public void Send(Alert message)
{
//Here we would send an e-mail
message.Log = LogConstants.SendByEmail;
}
}
public interface ISender
{
void Send(Alert message);
}
#endregion
#region Client
public class Alerter
{
private ISender _sender;
public Alerter(ISender sender)
{
_sender = sender;
}
public void Send(Alert message)
{
_sender.Send(message);
}
}
#endregion
#region Other
public class Alert
{
public String DestinationAddress { get; set; }
public String SenderAddress { get; set; }
public String Content { get; set; }
public string Log { get; set; }
}
public class LogConstants
{
public const string SendByEmail = "Message was send by e-mail /n";
public const string SendBySMS = "Message was send by sms /n";
public const string SendByMessenger = "Message was send by messenger /n";
}
#endregion
}