命令模式(5)

命令模式定义:将请求,命令,动作等封装成对象,这样可以让项目使用这些对象来参数化其他对象。是的命令的请求者和执行者解耦。


以下是一个遥控器的例子,如果按照传统OO思想,我们一般会直接让遥控器去调用硬件提供的API,但是这种写法,会导致遥控器与特定的硬件API强耦合。当我们的需要接入新的设备,修改按钮所绑定硬件命令,这时候就会相当不便。我们有个准则是,原来已经测试好的代码,尽量不去改动。而使用命令模式就可以达到这个效果。将命令抽象成接口,所有硬件命令实现该接口,当需要调用某个硬件api,就直接调用接口的api,这样就可以实现控制器与硬件的解耦。


代码示例如下:

1
2
3
4
5
6
7
8
9
//命令接口
public  interface  Command {
 
     //执行命令
     public  void  execute();
     
     //回退命令
     public  void  undo();
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public  class  LightOffCommand  implements  Command {
     private  String name;
     public  LightOffCommand(String name) {
         super ();
         this .name = name;
     }
 
     @Override
     public  void  execute() {
         System.out.println( "关闭--" +name+ "--的灯" );
     }
 
     @Override
     public  void  undo() {
         System.out.println( "打开--" +name+ "--的灯" );
     }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public  class  LightOnCommand  implements  Command {
     private  String name;
     public  LightOnCommand(String name) {
         super ();
         this .name = name;
     }
 
     @Override
     public  void  execute() {
         System.out.println( "打开--" +name+ "--的灯" );
     }
 
     @Override
     public  void  undo() {
         System.out.println( "关闭--" +name+ "--的灯" );
     }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
//空命令类的作用是,防止初始化的按钮,没有绑定导致空指针异常
public  class  NoCommand  implements  Command {
 
     @Override
     public  void  execute() {
         System.out.println( "没有绑定任何电器,所以无反应" );
     }
 
     @Override
     public  void  undo() {
         // TODO Auto-generated method stub
     }
}


控制器类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//遥控器App对象
public  class  TeleController {
     private  NoCommand noCommand =  new  NoCommand();
     //初始遥控器只有三对命令
     private  List<Command> leftButtonList;
     private  List<Command> rightButtonList;
     //遥控器操作记录
     private  Stack<Command> records =  new  Stack<Command>();
     
     public  TeleController(){
         leftButtonList =  new  ArrayList<Command>( 3 );
         rightButtonList =  new  ArrayList<Command>( 3 );
         leftButtonList.add(noCommand);
         leftButtonList.add(noCommand);
         leftButtonList.add(noCommand);
         rightButtonList.add(noCommand);
         rightButtonList.add(noCommand);
         rightButtonList.add(noCommand);
     }
     
     public  void  clickButton( int  index,  boolean  left){
         if (left){
             leftButtonList.get(index).execute();
             records.push(leftButtonList.get(index));
         } else {
             rightButtonList.get(index).execute();
             records.push(rightButtonList.get(index));
         }
     }
     
     public  void  backButton(){
         if (!records.isEmpty()){
             records.pop().undo();
         } else  {
             System.out.println( "已无更多操作记录,回退失败" );
         }
     }
     
     public  void  setCommand( int  index,  boolean  left, Command command){
         if (left){
             leftButtonList.set(index, command);
         }
         else {
             rightButtonList.set(index, command);
         }
     }
     
     public  void  addButton( boolean  left){
         if (left){
             leftButtonList.add(noCommand);
         } else  {
             rightButtonList.add(noCommand);
         }
     }
     
}


1
2
3
4
5
6
7
8
9
10
11
12
13
//扫地机器人---逻辑相同,可跳过该代码
public  class  RoombaOnCommand  implements  Command {
     
     @Override
     public  void  execute() {
         System.out.println( "扫地机器人--开始--打扫" );
     }
 
     @Override
     public  void  undo() {
         System.out.println( "扫地机器人--停止--打扫" );
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
public  class  RoombaOffCommand  implements  Command {
     
     @Override
     public  void  execute() {
         System.out.println( "扫地机器人--停止--打扫" );
     }
 
     @Override
     public  void  undo() {
         System.out.println( "扫地机器人--开始--打扫" );
     }
}


主测试函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public  class  Main {
     private  static  final  boolean  leftButton =  true ;
     private  static  final  boolean  rightButton =  false ;
 
     public  static  void  main(String[] args) {
         TeleController teleController =  new  TeleController();
         
         teleController.clickButton( 0 , leftButton);
         
         System.out.println( "左边第一栏按钮绑定卧室灯【开启】命令" );
         teleController.setCommand( 0 , leftButton,  new  LightOnCommand( "卧室灯" ));
         
         System.out.println( "右边第一栏按钮绑定卧室灯【关闭】命令" );
         teleController.setCommand( 0 , rightButton,  new  LightOffCommand( "卧室灯" ));
         
         System.out.println( "左边第二栏按钮绑定打扫机器人【开启】命令" );
         teleController.setCommand( 1 , leftButton,  new  RoombaOnCommand());
         
         System.out.println( "右边第二栏按钮绑定打扫机器人【关闭】命令" );
         teleController.setCommand( 1 , rightButton,  new  RoombaOffCommand());
         
         
         System.out.println( "按下左边第一个按钮" );
         teleController.clickButton( 0 , leftButton);
         System.out.println( "按下左边第二个按钮" );
         teleController.clickButton( 1 , leftButton);
         System.out.println( "按下回退按钮" );
         teleController.backButton();
         System.out.println( "再按下回退按钮" );
         teleController.backButton();
         System.out.println( "再按下回退按钮" );
         teleController.backButton();
         
     }
 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值