using System.Windows.Input; using System; using System.Threading.Tasks; using System.Collections.Generic; namespace design_patterns.behavioral.command { /// /// Command is a behavioral design pattern that turns a request /// into a stand-alone object that contains all information about the request. /// This transformation lets you pass requests /// as a method arguments, delay or queue a request’s execution, /// and support undoable operations. /// /// Use when: /// - you want to parametrize objects with operations. /// - you want to queue operations, schedule their execution, /// or execute them remotely. (serialize commands) /// - you want to implement reversible operations. /// public class CommandSample { public static async Task Run() { Console.WriteLine("Behavioral - Command"); var order = new Order { ID = Guid.NewGuid().ToString() }; List operations = new List(); operations.Add(new AddOrderCommand(order)); operations.Add(new RemoveOrderCommand(order.ID)); // batch execution foreach(var cmd in operations){ cmd.Execute(); } // undo operations.Reverse(); foreach(var cmd in operations){ cmd.Undo(); } } } public interface ICommand { bool HasSucceded {get;set;} void Execute(); void Undo(); } public class AddOrderCommand : ICommand { public AddOrderCommand(Order order) => this.Order = order; public Order Order { get; private set; } public bool HasSucceded { get; set; } public void Execute() { Console.WriteLine($"Execute add order command for order {Order.ID}"); // this should be set by a command processor externally HasSucceded = true; } public void Undo() { if(HasSucceded){ Console.WriteLine($"UNDO - add order for order {Order.ID}"); } } } public class RemoveOrderCommand : ICommand { public RemoveOrderCommand(string orderId) => this.OrderID = orderId; public string OrderID { get; private set; } public bool HasSucceded { get; set; } public void Execute() { Console.WriteLine($"Execute remove order command for order {OrderID}"); // this should be set by a command processor externally // FORCE failure HasSucceded = false; } public void Undo() { if(HasSucceded){ Console.WriteLine($"UNDO - remove order for order {OrderID}"); } } } public class Order { public string ID { get; set; } } }