命令模式模拟房间开关
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档命令模式一、问题描述二、问题分析1.分析思路2.类图三、命令模式简介1.命令模式的优点2.命令模式的缺点3.应用场景四、代码及结果一、问题描述 房间中的开关就是命令模式的一个实现,试用命令模式来模拟开关的功能,可控制对象包括电灯和电风扇,绘制相应的类图并使用对应的语言编程模拟。二、问题分析1.分析思路 本题之所以把lighton和
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、问题描述
房间中的开关就是命令模式的一个实现,试用命令模式来模拟开关的功能,可控制对象包括电灯和电风扇,绘制相应的类图并使用对应的语言编程模拟。
二、问题分析
1.分析思路
本题之所以把lighton和lightoff分开,这样虽然多增加了类,但是符合了开闭原则,因为若将on方法和off方法放在一个具体命令类里面,那么这样抽象命令类里面的接口就会改变,这样如果新加一个功能则会修改很多,非常麻烦。而如果设计成如下图所示的类图,新加一个功能则只需要再加几个类即可。
2.类图
三、命令模式简介
命令模式(Command Pattern):将一个请求封装为一个对象,从而你可以用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销操作。上述类图符合了开闭原则、里氏代换原则、依赖倒转原则等等。
1.命令模式的优点
(1)降低了系统耦合度。
(2)命令模式的封装性很好:每个命令都被封装起来,对于客户端来说,需要什么功能就去调用相应的命令,而无需知道命令具体是怎么执行的。比如有一组文件操作的命令:新建文件、复制文件、删除文件。如果把这三个操作都封装成一个命令类,客户端只需要知道有这三个命令类即可,至于命令类中封装好的逻辑,客户端则无需知道。
(3)命令模式的扩展性很好,在命令模式中,在接收者类中一般会对操作进行最基本的封装,命令类则通过对这些基本的操作进行二次封装,当增加新命令的时候,对命令类的编写一般不是从零开始的,有大量的接收者类可供调用,也有大量的命令类可供调用,代码的复用性很好。比如,文件的操作中,我们需要增加一个剪切文件的命令,则只需要把复制文件和删除文件这两个命令组合一下就行了,非常方便。
(4)可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
(5)方便实现 Undo 和 Redo 操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复。
(6)增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足“开闭原则”,对扩展比较灵活。
2.命令模式的缺点
(1)使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
3.应用场景
(1)struts1中的action核心控制器ActionServlet只有一个,相当于Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的Command。
(2)系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
(3)系统需要在不同的时间指定请求、将请求排队和执行请求。
(4)系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
(5)系统需要将一组操作组合在一起,即支持宏命令。
四、代码及结果
项目目录:
Command接口类:
public interface Command {
void excute();
}
具体命令类——LightOffCommand:
public class LightOffCommand implements Command{
private Light light;
LightOffCommand(Light light)
{
this.light = light;
}
@Override
public void excute() {
light.off();
}
}
具体命令类——ElectricFanOnCommand:(其他具体命令类类似)
public class ElectricFanOnCommand implements Command{
private ElectricFan electricFan;
ElectricFanOnCommand(ElectricFan electricFan)
{
this.electricFan = electricFan;
}
@Override
public void excute() {
electricFan.on();
}
}
接收者类——Light(ElectriFan类似):
public class Light {
private boolean on = false ;
public void on()
{
System.out.println("开灯");
on = true;
}
public void off()
{
System.out.println("关灯");
on = false ;
}
public boolean Ison()
{
return on;
}
}
发送者类——RemoteController:
public class RemoteController {
Command[] oncommand;
Command[] offcommand;
RemoteController(int commandsize)
{
oncommand = new Command[commandsize];
offcommand = new Command[commandsize];
}
public void setCommand(int i, Command onCommand, Command offCommand) {
oncommand[i] = onCommand;
offcommand[i] = offCommand;
}
public void onButtonPressed(int i)
{
oncommand[i].excute();
}
public void offButtonPressed(int i)
{
offcommand[i].excute();
}
}
Client类:
public class Clint {
public static void main(String[]args) {
Light light = new Light();
ElectricFan electricFan = new ElectricFan();
Command electricFanOnCommand = new ElectricFanOnCommand(electricFan);
Command electricFanOffCommand = new ElectricFanOffCommand(electricFan);
Command lightOnCommand = new LightOnCommand(light);
Command lightOffCommand = new LightOffCommand(light);
RemoteController remoteController = new RemoteController(2);
remoteController.setCommand(0,electricFanOnCommand,electricFanOffCommand);
remoteController.setCommand(1,lightOnCommand,lightOffCommand);
remoteController.offButtonPressed(1);
remoteController.offButtonPressed(0);
remoteController.onButtonPressed(0);
remoteController.onButtonPressed(1);
}
}
运行结果:
更多推荐
所有评论(0)