命令模式:
把封装带到一个新的境界:把方法调用封装起来。所以调用此方法的对象不需要关心事情是如何进行的,只需要知道如何使用包装形成的方法来完成它就可以了。
特点:
1. 将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。
2. 命令模式也支持可撤销的操作。
3. 命令模式可以实现请求调用者和请求接收者之间的解耦。
用例:
需求:假设现在有一个遥控器,里面有一些按钮,其中有一个设置按钮可以用来设置开关按钮控制的哪一个设备(例如点灯),然后还有一些开关按钮,可以控制设备的开和关,下面是代码设计:
1. 定义一个命令的接口:
/** * Created on 2016/11/17. * 接口方法的默认修饰符"public abstract" */ public interface Commands { void execute(); }2. 写一个初始化的实现类:
/** * Created on 2016/11/17. */ public class NoCommand implements Commands { @Override public void execute() { //空方法:表示不执行任何操作 } }3. 创建具体的相关实现类(以Light为例):
/** * Created on 2016/11/17. */ public class LightOnCommand implements Commands { private Lights lights; public LightOnCommand(Lights lights){ this.lights = lights; } @Override public void execute() { lights.on(); } }
/** * Created on 2016/11/17. */ public class LightOffCommand implements Commands { private Lights lights; public LightOffCommand(Lights lights){ this.lights = lights; } @Override public void execute() { lights.off(); } }4. 创建Lights实体类:
/** * Created on 2016/11/17. */ public class Lights { public String str = "123"; public void on(){ str = "lights is on!"; } public void off(){ str = "lights is off!"; } public String getStr(){ return str; } }5. 对开关的操作类:
/** * Created by fanghan on 2016/11/17. */ public class CommandControl { private Commands[] onCommands;//打开操作集合 private Commands[] offCommands;//关闭操作集合 public CommandControl(){ onCommands = new Commands[10];//假设有十个按钮 offCommands = new Commands[10]; NoCommand noCommand = new NoCommand(); for (int i = 0; i < 10; i++) {//初始化操作:默认不执行任何操作 onCommands[i] = noCommand; offCommands[i] = noCommand; } } public void setOnCommands(int slot , Commands onCommand , Commands offCommand){ onCommands[slot] = onCommand; offCommands[slot] = offCommand; } public void on(int slot){ onCommands[slot].execute(); } public void off(int slot){ offCommands[slot].execute(); } }6. 具体的调用者(这里是一个activity):
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); useCommand = new CommandControl(); lights = new Lights(); initView(); initListener(); }7. 这样设计的好处是不需要去管代码是具体实现的,如果想打开就调用useCommand.on(index),如果想关闭开关就直接调用 useCommand.off(index)。如果还想增加新的设备,不需要修改现有的代码,只需要增加新的Command实现类和具体实体类就可以了。@Override public void onClick(View v) { switch (v.getId()){ case R.id.bt_test: //初始化按钮 useCommand.setOnCommands(0, new LightOnCommand(lights), new LightOffCommand(lights)); break; case R.id.bt_on: useCommand.on(0); tv_test.setText(lights.getStr()); break; case R.id.bt_off: useCommand.off(0); tv_test.setText(lights.getStr()); break; } }