The Command pattern is intended to encapsulate a request as an object. A Command object encapsulates an action and its parameters. It is useful for implementing transactional behavior or a simple workflow.
Code examples (click to enlarge/collapse):
-
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253public class Client{public static void Run(){Receiver receiver = new Receiver();Command command = new ConcreteCommand(receiver);Invoker invoker = new Invoker(command);invoker.DoAction();}}public abstract class Command{public abstract void Execute();}public class ConcreteCommand : Command{Receiver m_Receiver;public ConcreteCommand(Receiver receiver){this.m_Receiver = receiver;}public override void Execute(){m_Receiver.Action();}}public class Invoker{private Command m_Command;public Invoker(Command command){this.m_Command = command;}public void DoAction(){m_Command.Execute();}}public class Receiver{public void Action(){Console.WriteLine("Action performed");}}
-
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128public class Client{public static void Run(){PaymentProcessor processor = new PaymentProcessor();IPaymentCommand action = new DoPaymentAction(processor);PaymentTransaction trans = new PaymentTransaction(action);PaymentRequest request = new PaymentRequest();request.Amount = 25.33;ProcessPaymentRequest(trans, request);request.Amount = -5.75;ProcessPaymentRequest(trans, request);}private static void ProcessPaymentRequest(PaymentTransaction trans, PaymentRequest request){try{trans.DoPayment(request);trans.Commit();}catch (ActionFailedException){trans.Rollback();}Console.WriteLine();}}public class ActionFailedException : Exception{}public class PaymentRequest{double m_Amount;public double Amount{get { return m_Amount; }set { m_Amount = value; }}}public interface IPaymentCommand{void DoPayment(PaymentRequest request);void Rollback();void Commit();}public class DoPaymentAction : IPaymentCommand{private PaymentProcessor m_Receiver;public DoPaymentAction(PaymentProcessor receiver){m_Receiver = receiver;}public void DoPayment(PaymentRequest arg){m_Receiver.Action(arg);}public void Rollback(){m_Receiver.RollBack();}public void Commit(){m_Receiver.Commit();}}public class PaymentTransaction{private IPaymentCommand m_task;public PaymentTransaction(IPaymentCommand task){m_task = task;}public void DoPayment(PaymentRequest arg){m_task.DoPayment(arg);}public void Rollback(){m_task.Rollback();}public void Commit(){m_task.Commit();}}public class PaymentProcessor{double m_OriginalAmount;double m_CurrentAmount;double m_ProposedAmount;public void Action(PaymentRequest arg){m_OriginalAmount = arg.Amount;m_ProposedAmount = m_OriginalAmount * 2.5245;Console.WriteLine("Calculated result: {0} * ? = {1} ", m_OriginalAmount, m_ProposedAmount);if (m_ProposedAmount < 0) throw new ActionFailedException();}public void RollBack(){m_CurrentAmount = m_OriginalAmount;Console.WriteLine("RollBack, result = {0}", m_CurrentAmount);}public void Commit(){m_CurrentAmount = m_ProposedAmount;Console.WriteLine("Commit,result = {0}", m_CurrentAmount);}}
This post is part of my series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern and look at simplified real-world C# code that implements the pattern.
-
Comments