浅学设计模式之命令<command>模式
2012-05-25 22:51
495 查看
概念
在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)
关系图:
看下命令模式是有哪些角色来组成的吧。
1) 命令角色(Command):声明执行操作的接口。有java接口或者抽象类来实现。
2) 具体命令角色(Concrete Command):将一个接收者对象绑定于一个动作;调用接收者相应的操作,以实现命令角色声明的执行操作的接口。
3) 客户角色(Client):创建一个具体命令对象(并可以设定它的接收者)。
4) 请求者角色(Invoker):调用命令对象执行这个请求。
5) 接收者角色(Receiver):知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
代码小例子
物联网是未来一个卖点之一,实现物联网以后,我们可以随便遥控家里电器的情况,在这里,设计一个遥控器,具有遥控电视和洗衣机的功能。当然,你也可以添加很多遥控其他电器的功能,如果要编写这么一个类,如何更好的实现解耦呢?命令模式是个不错的选择:
首先:先建立一个Command接口:
public interface ICommand {
//执行
void execute();
//撤销
void undo();
}
再者,得有电视和洗衣机,才可以遥控:
public class TV {
public void turnOnTV(){
System.out.println("打开电视");
}
public void turnOffTV(){
System.out.println("关闭电视");
}
}
实现ConcreteCommand(具体的Command):
public class TVCommand implements ICommand {
TV tv = null;
public TVCommand(TV tv){
this.tv = tv;
}
@Override
public void execute() {
// TODO Auto-generated method stub
tv.turnOnTV();
}
@Override
public void undo() {
// TODO Auto-generated method stub
tv.turnOffTV();
}
}
最后,实现遥控器类:
public class RemoteControl {
ICommand iCommand = null;
public void setCommand(ICommand iCommand){
this.iCommand = iCommand;
}
public void startCommand() {
iCommand.execute();
}
public void stopCommand(){
iCommand.undo();
}
}
看一下,遥控器只是把command传出去,而它丝毫不关心打开和关闭电器是如何实现的,就这样实现了解耦。
测试类:
public class CommandTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//先得到家电
TV tv = new TV();
Washer washer = new Washer();
//生成命令
TVCommand tvCommand = new TVCommand(tv);
WasherCommand washerCommand = new WasherCommand(washer);
RemoteControl remoteControl = new RemoteControl();
//遥控器发出命令
remoteControl.setCommand(tvCommand);
remoteControl.startCommand();
remoteControl.stopCommand();
remoteControl.setCommand(washerCommand);
remoteControl.startCommand();
remoteControl.stopCommand();
}
}
测试结果:
打开电视
关闭电视
打开洗衣机
关闭洗衣机
想想一下,往后,如果我们在遥控器想加入遥控电风扇、空调、冰箱等等功能是不是特别清晰。
2.新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起,即支持宏命令。
在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)
关系图:
看下命令模式是有哪些角色来组成的吧。
1) 命令角色(Command):声明执行操作的接口。有java接口或者抽象类来实现。
2) 具体命令角色(Concrete Command):将一个接收者对象绑定于一个动作;调用接收者相应的操作,以实现命令角色声明的执行操作的接口。
3) 客户角色(Client):创建一个具体命令对象(并可以设定它的接收者)。
4) 请求者角色(Invoker):调用命令对象执行这个请求。
5) 接收者角色(Receiver):知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
代码小例子
物联网是未来一个卖点之一,实现物联网以后,我们可以随便遥控家里电器的情况,在这里,设计一个遥控器,具有遥控电视和洗衣机的功能。当然,你也可以添加很多遥控其他电器的功能,如果要编写这么一个类,如何更好的实现解耦呢?命令模式是个不错的选择:
首先:先建立一个Command接口:
public interface ICommand {
//执行
void execute();
//撤销
void undo();
}
再者,得有电视和洗衣机,才可以遥控:
public class TV {
public void turnOnTV(){
System.out.println("打开电视");
}
public void turnOffTV(){
System.out.println("关闭电视");
}
}
public class Washer { public void turnOnWasher(){ System.out.println("打开洗衣机"); } public void turnOffWasher(){ System.out.println("关闭洗衣机"); } }
实现ConcreteCommand(具体的Command):
public class TVCommand implements ICommand {
TV tv = null;
public TVCommand(TV tv){
this.tv = tv;
}
@Override
public void execute() {
// TODO Auto-generated method stub
tv.turnOnTV();
}
@Override
public void undo() {
// TODO Auto-generated method stub
tv.turnOffTV();
}
}
public class WasherCommand implements ICommand{ Washer washer = null; public WasherCommand(Washer washer){ this.washer=washer; } @Override public void execute() { // TODO Auto-generated method stub washer.turnOnWasher(); } @Override public void undo() { // TODO Auto-generated method stub washer.turnOffWasher(); } }
最后,实现遥控器类:
public class RemoteControl {
ICommand iCommand = null;
public void setCommand(ICommand iCommand){
this.iCommand = iCommand;
}
public void startCommand() {
iCommand.execute();
}
public void stopCommand(){
iCommand.undo();
}
}
看一下,遥控器只是把command传出去,而它丝毫不关心打开和关闭电器是如何实现的,就这样实现了解耦。
测试类:
public class CommandTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//先得到家电
TV tv = new TV();
Washer washer = new Washer();
//生成命令
TVCommand tvCommand = new TVCommand(tv);
WasherCommand washerCommand = new WasherCommand(washer);
RemoteControl remoteControl = new RemoteControl();
//遥控器发出命令
remoteControl.setCommand(tvCommand);
remoteControl.startCommand();
remoteControl.stopCommand();
remoteControl.setCommand(washerCommand);
remoteControl.startCommand();
remoteControl.stopCommand();
}
}
测试结果:
打开电视
关闭电视
打开洗衣机
关闭洗衣机
想想一下,往后,如果我们在遥控器想加入遥控电风扇、空调、冰箱等等功能是不是特别清晰。
模式优点
1.降低系统的耦合度。2.新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令。
模式缺点
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。适用环境
1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起,即支持宏命令。
相关文章推荐
- JAVA设计模式(18) —<行为型>命令模式(Command)
- (Boolan)C++设计模式 <十二> ——命令模式(Command)和访问器(Visitor)
- 浅学设计模式之装饰者<Decorator>模式
- 浅学设计模式之策略<Strategy>模式及在android中的使用
- 浅学设计模式之单例<singleton>模式
- 《大话设计模式》--烤羊肉串引来的思考--命令模式<Command>(23)
- 浅学设计模式之模板<Template>方法模式及在android中的应用
- 浅学设计模式之装饰者<Decorator>模式 .
- <Head First 设计模式>:命令模式:Command
- 学习笔记——JAVA设计模式<15>命令模式
- 浅学设计模式之状态<state>模式
- 浅学设计模式之观察者<Observer>模式及在android中的应用 .
- 浅学设计模式之状态<state>模式
- 浅学设计模式之桥接<bridge>模式
- 浅学设计模式之观察者<Observer>模式及在android中的应用
- 浅学设计模式之迭代器<Iterator>模式
- 浅学设计模式之策略<Strategy>模式及在android中的使用
- 浅学设计模式之观察者<Observer>模式及在android中的应用
- 浅学设计模式之外观<Facade>模式