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

本文详细介绍了命令模式的设计原理及其应用场景,并通过开关控制灯泡和风扇的例子,展示了如何利用命令模式实现解耦,使得请求发送者与接收者之间的交互更加灵活。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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


举例说明(例子参照《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();
	}
	@Override
	public void open() {
		// TODO Auto-generated method stub
		lamp.openLamp();
	}

	@Override
	public void close() {
		// TODO Auto-generated method stub
		lamp.closeLamp();
	}

}

风扇命令类:

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

	@Override
	public void close() {
		// TODO Auto-generated method stub
		fan.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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值