首页 > 代码库 > 3.4 命令模式(5.2)

3.4 命令模式(5.2)

1. 引子

假定电视机/TV有方法open()、close()和changeChannel()用于打开、关闭和切换电视频道,而遥控器/Controller对TV的操作,通常使用消息传递/方法调用表达式。

package method.command;
/**
 * @author yqj2065
 * @version 0.1
 */
public class Controller1{
    public static void foo(){
		TV tv = new TV();
		tv.open();
		tv.changeChannel();
		tv.close();
	}
}
面向对象中的服务请求,或者说消息传递表达式如

tv.open();

与命令式语言如C的函数调用的最大不同,是消息传递表达式包含消息接收者tv,另外再加上open()。

命令模式则是追求一种千秋万代一统江湖的服务请求方式。

  •  Controller不愿意记住方法名。open()、close()、changeChannel()这些东西?以后有没有更多的方法可以调用,或者说更多的服务可以请求呢?所以,我不愿意被方法名限制,我以exe ()作为普适的方法名,exe()被“方法对象化”为Command——使用Command封装exe ()。
  • Controller不愿意知道消息接收者是谁。司令员下命令打下这个山头,他会不会考虑要那个连长去带人攻打呢。管你谁谁,打下这个山头才是司令员关心的。

 学习命令模式稍有难度,毕竟一统江湖的事情,总得有点难度。

package method.command;
public interface Command{
	public void exe();
}

下面,是直接给出命令模式,让大家死记硬背地理解呢?还是从0开始,研究一下Controller如何才能够忘记/无视被调的方法名?

2. 命令与执行

先直接给出命令模式的例子吧。

既然有了Command,按照多态也好,难度系数为0的策略模式也罢,tv的open()演变成Command的子类OpenCommand

OpenCommand有私有成员TV tv,而OpenCommand的exe()干什么?显然只需要一条语句tv.open()。代码自己顺便写吧。

因为我们拥有依赖注入工具tool.God,(注意:在我的博客的很多的文章中,都使用了该工具,但是类名用过FromPropertyFile、IoC、God,包也有所变化,懒得逐一修改相关博文了。代码的意思很清楚,读者自己对应修改一下),因而代码

package method.command; 
import tool.God;
public class Controller{
	public static void test()	{
	    Command c1 = (Command)God.create("open");
	    c1.exe();
	}
}
Controller仅仅知道Command对象,Controller下的命令为字符串"open",God根据字符串"open"创建method.command.OpenCommand对象。

忽略一切细节,Controller仅依赖Command,对照的,Controller1依赖TV,和TV的现有操作/方法名



3.4 命令模式(5.2)