设计模式随笔-锦囊妙计 (转)

吕震宇

话说《三国演义》中,周瑜与孙权定下计谋,以孙权之妹为诱饵,骗刘备过江到东吴招亲,想趁机杀害刘备,索回荆州。诸葛亮早识破了诡计,令武将赵云随同并护卫刘备前往,并给赵云了三个锦囊,嘱咐他依次执行即可。结果,赵云按照诸葛亮的锦囊妙计行事,不仅帮助刘备将孙权之妹孙尚香夫人迎娶回来,还得到孙权之母吴国太的欢心,陪同刘备夫妇回了荆州。《三国演义》这段记叙,为后世创造了“锦囊妙计”和“赔了夫人又折兵”两个成语。

今天,我就“锦囊妙计”来说说Command模式。从面向对象的设计角度来说,锦囊妙计有以下几个特色:

1、妙计被装入锦囊后都变得一般模样,没有任何区别。

2、锦囊妙计自己是无法实施的,必须由某个人依计行事。

3、实施者有权利选择执行命令或不执行命令,也可以选择在什么时候执行。当然,在我们的故事中,赵云在合适的时间执行了合适的妙计,便为我们留下了精彩的故事。

这个故事用代码书写出来如下:

using System;
using System.Collections;

abstract class JinNang
{
  
public string message = "";

  
public void Execute()
  
{
    Console.WriteLine(message);
  }

}


class JinNang1 : JinNang
{
  
public JinNang1()
  
{
    
this.message = "ToDo:让刘备拜见岳艾乔国老,并大造声势。";
  }

}


class JinNang2 : JinNang
{
  
public JinNang2()
  
{
    
this.message = "ToDo:假报刘备:曹操起兵五十万,杀奔荆州。";
  }

}


class JinNang3: JinNang   
{
  
public JinNang3()
  
{
    
this.message = "ToDo:向孙夫人揭穿了孙权和周瑜的阴谋,请求夫人保护。";
  }

}


abstract class Receiver
{
  
protected Queue commands = new Queue();
  
  
public void SetCommand(JinNang c)
  
{
    commands.Enqueue(c);
  }


  
protected JinNang GetCommand()
  
{
    
if (this.commands.Count != 0)
    
{
      JinNang c 
= (JinNang)this.commands.Dequeue();
      
return c;
    }

    
else
      
return null;
  }


  
public bool FulfilCommand(JinNang c)
  
{
    
if(c != null)
    
{
      c.Execute();
      
return  true;
    }

    
else
    
{
      Console.WriteLine(
"惨了!无计可施了!");
      
return false;
    }

  }


  
abstract public void DoComplexJob();
}


class Zhaoyun : Receiver
{
  
public override void DoComplexJob()
  
{
    Console.WriteLine(
"护送刘备去东吴");
    Console.WriteLine(
"到达市徐");
    
if(!FulfilCommand(GetCommand())) return;

    Console.WriteLine(
"刘备娶了孙权之妹");
    Console.WriteLine(
"发现刘备全不想回荆州");
    
if(!FulfilCommand(GetCommand())) return;

    Console.WriteLine(
"被孙权追杀");
    
if(!FulfilCommand(GetCommand())) return;

    Console.WriteLine(
"安然护送刘备抵达荆州,任务完成!");
  }

}


class ZhuGeLiang
{
  
public void JinNangMiaoJi(Receiver r)
  
{
    r.SetCommand(
new JinNang1());
    r.SetCommand(
new JinNang2());
    r.SetCommand(
new JinNang3());
  }

}


public class Client
{
  
public static void Main( string[] args )
  
{
    Receiver r 
= new Zhaoyun();
    ZhuGeLiang z 
= new ZhuGeLiang();
    
    z.JinNangMiaoJi(r);
    r.DoComplexJob();
  }

}

“命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象”。通过将妙计封装成锦囊妙计,便成为可委派的妙计。由一个对象(ZhuGeLiang)创建并封装,然后传递给另一个对象(ZhaoYun),命令在此没有被立即执行,而是Enqueue了。当条件合适的时候,再将命令解开执行。另外,所有的锦囊妙计都有一个共同的特性,就是可以被执行。所以,赵云不用关心这个锦囊与那个锦囊有什么区别,只需执行便是了。

该例子仅仅取了一个Command模式的“意”,丢弃了Command模式的形。设计模式的应用无需过于死板。如果对Command模式感兴趣,可以访问《设计模式(18)-Command Pattern》

posted @ 2007-10-11 13:20  智慧园区-老朱  阅读(228)  评论(0编辑  收藏  举报