设计模式(14)--命令模式

来源:互联网 发布:文献查重软件 编辑:程序博客网 时间:2024/06/03 10:20

命令模式,用来对请求的发送者和请求的接收者进行解耦的一种设计模式,为什么叫命令模式呢?因为在应用该模式时,引入了一个命令对象。

命令模式有三个角色,请求发送者,命令对象,请求的接收者(处理者),谁来给请求发送者和接收者解耦呢,命令对象,所以我们一思考就知道命令模式应该是这样的:

请求发送者发送请求,为了增强扩展性,需要面向抽象编程,所以首先有一个抽象命令对象,当然,还要有具体命令对象来对应具体接收者,从而使不同命令得到不同处理。


举例说明(例子参照《C#设计模式 刘伟 胡志刚 阎朝坤》开关示例):隔壁老王帮隔壁邻居修开关,隔壁也是倒霉,风扇开关和电灯泡开关都坏了,隔壁老王上街买开关,要买两个,然而他不用特意买两个不同的开关,他只需买两个一模一样的开关就行,修的时候,使用不同电线连接不同电器,灯泡和风扇自然都能正常工作。

 在上面例子中,开关(请求发送者,发送通电,断电请求),电线(命令对象)封装请求,灯泡或风扇(请求接收者处理者)处理请求。通过电线,很好的将请求发送者和接受者进行了解耦,这样好处很大,灯泡坏了只换灯泡,开关坏了只换开关即可。

命令模式UML类图:


LampCommand和Lamp是同生共死关系,所以是组合关系。

示例代码:

请求发送者:

/**** * 请求发送者(开关) * @author wjw * */public class Sender {private AbstractCommand ac;public Sender(AbstractCommand ac){this.ac = ac;}/*** * 开关开 */public void open(){ac.open();}/*** * 开关关 */public void close(){ac.close();}}

抽象命令类:


/***** * 抽象命令类 * @author wjw * */public abstract class AbstractCommand {public abstract void open();public abstract void close();}

电灯命令类:


/**** * 电灯命令对象,封装电灯(命令接收者) * @author wjw * */public class LampCommand extends AbstractCommand{private Lamp lamp;public LampCommand(){lamp = new Lamp();}@Overridepublic void open() {// TODO Auto-generated method stublamp.openLamp();}@Overridepublic void close() {// TODO Auto-generated method stublamp.closeLamp();}}

风扇命令类:

public class FanCommand extends AbstractCommand{private Fan fan;public FanCommand(){fan = new Fan();}@Overridepublic void open() {// TODO Auto-generated method stubfan.openFan();}@Overridepublic void close() {// TODO Auto-generated method stubfan.closeFan();}}


电灯类:


/**** * 电灯(请求接收者) * @author wjw * */public class Lamp {public void openLamp(){System.out.println("开灯!");}public void closeLamp(){System.out.println("关灯!");}}

风扇类:


/**** * 风扇类(请求处理者) * @author wjw * */public class Fan {public void openFan(){System.out.println("开风扇!");}public void closeFan(){System.out.println("关风扇!");}}

Main类:


public class Main {public static void main(String[] args) {AbstractCommand lampCommand = new LampCommand();AbstractCommand fanCommand = new FanCommand();Sender lampSwitcher = new Sender(lampCommand);Sender fanSwitcher = new Sender(fanCommand);lampSwitcher.open();lampSwitcher.close();fanSwitcher.open();fanSwitcher.close();}}


运行结果:

开灯!
关灯!
开风扇!
关风扇!


通过以上示例代码可以看出,我们开关和灯泡或者风扇没有耦合,相同的开关,既可以用在灯泡上,又可以用在风扇上,一个电灯泡,可以使用A型开关,也可以使用B型开关,其中的原理就是多了一个中间件,用来给他俩解耦,转发请求。


说明:命令模式就是将一个具体的请求封装成一个对象,将请求的发送者与接收者解耦。

我们为什么要用命令模式这个设计模式呢?设想这样一个场景,某厂家生产的电灯,开关和灯泡是连在一起的,灯泡10000元,开关10块,某天开关坏了,厂家说要把灯泡一起换了,你同意吗?正常人估计会把厂家踹一边,自己在家找个风扇不用的开关给电灯换上,继续使用。所以只要有正常人的思维理解命令模式不难。


如有错误,欢迎指正

end