using System;   
  
///1.容易设计命令队列   
///2.需要的情况下,可以很容易的将命令记入日志   
///3.很容易的实现命令的撤销和重做   
///   
/// 命令模式:   
/// 将请求一个操作的对象与知道怎么执行一个操作的对象分割开。   
/// 注:一般的方法调用方法,是直接通过对象调用或者类调用,这样的调用方式,   
/// 行为请求者和行为实现者之间的是紧耦合的关系即 A和B的调用关系)   
/// 比如你需要对系列的动作调用实现记录,撤销,重做等操作的时候,   
/// 就需要对这些行为请求者和行为实现者之间实现解耦。   
/// 那么command模式给你一个思路:抽象,引入第三者,实现解耦。   
/// 这也是许多设计模式的一个比较通行的解耦思路。   
///    
  
namespace CommandPattern   
{   
    
class Program   
    {   
        
static void Main(string[] args)   
        {   
            Document doc 
= new Document();   
  
            Command doCmd 
= new DoCommand(doc);   
            Command unDoCmd 
= new UnDoCommand(doc);   
            Command reDoCmd 
= new ReDoCommand(doc);   
  
            CmdInvoke invoke 
= new CmdInvoke();   
  
            invoke.AddCmd(doCmd);   
            invoke.AddCmd(unDoCmd);   
            invoke.AddCmd(reDoCmd);   
  
            invoke.Execute();   
  
            Console.Read();   
        }   
    }   
  
    
public abstract class Command   
    {   
        
public Document doc;   
        
public Command(Document doc)   
        {   
            
this.doc = doc;   
        }   
  
        
public abstract void ExecuteCommand();   
    }   
  
    
public class DoCommand : Command   
    {   
        
public DoCommand(Document doc) : base(doc) { }   
  
        
public override void ExecuteCommand()   
        {   
            doc.Do();   
        }   
    }   
  
    
public class UnDoCommand : Command   
    {   
        
public UnDoCommand(Document doc) : base(doc) { }   
  
        
public override void ExecuteCommand()   
        {   
            doc.UnDo();   
        }   
    }   
  
    
public class ReDoCommand : Command   
    {   
        
public ReDoCommand(Document doc) : base(doc) { }   
  
        
public override void ExecuteCommand()   
        {   
            doc.ReDo();   
        }   
    }   
  
    
public class CmdInvoke   
    {   
        List
<Command> cmdList = new List<Command>();   
  
        
public void AddCmd(Command cmd)   
        {   
            cmdList.Add(cmd);   
        }   
  
        
public void UndoCmd(Command cmd)   
        {   
            cmdList.Remove(cmd);   
        }   
  
        
public void Execute()   
        {   
            
foreach (Command cmd in cmdList)   
            {   
                cmd.ExecuteCommand();   
            }   
        }   
    }   
  
  
    
public class Document   
    {   
        
public string info { setget; }   
  
        
public void Do()   
        {   
            Console.WriteLine(
"Do Something");   
        }   
  
        
public void UnDo()   
        {   
            Console.WriteLine(
"UnDo something");   
        }   
  
        
public void ReDo()   
        {   
            Console.WriteLine(
"Redo Something");   
        }   
    }   
}