设计模式学习----命令模式
GOF的定义:
命令模式(别名:动作,事物)
将一个请求封装成一个对象,从而使用户可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销操作.
在许多设计中, 经常涉及到一个对象请求另一个对象调用其方法达到某种目的. 如果请求者不希望或无法直接和被请求者打交到, 即不希望或无法含有被请求者的引用,那么就可以使用命令模式.
提出请求的对象为请求者, 被请求的对象为接收者. 在命令模式中, 当一个对象请求另一个对象调用其方法时, 不和被请求的对象直接打交道, 而是把这种"请求"封装到一个称作"命令"的对象中, 其封装手段是将"请求"封装在"命令"对象的一个方法中.
命令模式的核心就是使用命令对象来封装方法调用, 即将请求者的请求, 接收者调用方法封装到命令对象的一个方法中, 这样, 当一个对象请求另一个对象调用方法来完成某项任务时,只需和命令对象打交道, 即让命令对象调用封装了"请求"的那个方法即可.
命令模式的优点:
1. 在命令模式中, 请求者不直接与接收者交互, 即请求者不包含接收者的引用, 因此彻底消除了彼此之间的耦合.
2. 命令模式满足"开-闭"原则. 如果增加新的具体命令和该命令的接收者, 不必修改调用者的代码, 调用者就可以使用新的命令对象; 反之, 如果增加新的调用者, 不必修改现有的具体命令和接收者, 新增加的调用者就可以使用自己已有的具体命令
3.由于请求者被封装到了具体命令中, 那么就可以将具体命令保存到持久化的媒介中, 在需要的时候, 重新执行这个具体命令. 因此使用命令模式可以记录日志.
4.使用命令模式可以对请求者的"请求"进行排队. 每个请求都各自对应一个具体命令,因此可以按照一定的顺序执行这些命令.
package CommandPattern;import javax.swing.*;public class Camera extends JPanel{ String name; Icon imageIcon; JLabel label; public Camera(){ label=new JLabel("我是摄像头"); add(label); } public void on(){ label.setIcon(new ImageIcon("cameraOpen.jpg")); } public void off(){ label.setIcon(new ImageIcon("cameraOff.jpg")); }}
package CommandPattern;import javax.swing.*;public class Light extends JPanel{ String name; Icon imageIcon; JLabel label; public Light(){ label=new JLabel("我是照明灯"); add(label); } public void on(){ label.setIcon(new ImageIcon("lightOpen.jpg")); } public void off(){ label.setIcon(new ImageIcon("lightOff.jpg")); }}
package CommandPattern;public class OnCameraCommand implements Command{ Camera camera; OnCameraCommand(Camera camera){ this.camera=camera; } public void execute(){ camera.on(); } public String getName(){ return "打开摄像头!"; }}
package CommandPattern;public class OffCameraCommand implements Command{ Camera camera; OffCameraCommand(Camera camera){ this.camera=camera; } public void execute(){ camera.off(); } public String getName(){ return "关闭摄像头!"; }}
package CommandPattern;public class OnLightCommand implements Command{ Light light; OnLightCommand(Light light){ this.light=light; } public void execute(){ light.on(); } public String getName(){ return "打开 照明灯!"; }}
package CommandPattern;public class OffLightCommand implements Command{ Light light; OffLightCommand(Light light){ this.light=light; } public void execute(){ light.off(); } public String getName(){ return "关闭 照明灯!"; }}
package CommandPattern;public interface Command { public abstract void execute(); public abstract String getName();}
package CommandPattern;import java.awt.*;import java.awt.event.*;import javax.swing.*;public class Invoke { JButton button; Command command; Invoke(){ button=new JButton(); button.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ executeCommand(); } }); } public void setCommand(Command command){ this.command=command; button.setText(command.getName()); } public JButton getButton(){ return button; } private void executeCommand(){ command.execute(); }}
package CommandPattern;import java.awt.*;import java.awt.event.*;import javax.swing.*;public class Machine extends JFrame{ Invoke requestOnCamera,requestOffCamera,requestOnLight,requestOffLight; Camera camera; Light light; Machine(){ setTitle("小电器"); requestOnCamera=new Invoke(); requestOffCamera=new Invoke(); camera=new Camera(); light=new Light(); requestOnCamera.setCommand(new OnCameraCommand(camera)); requestOffCamera.setCommand(new OffCameraCommand(camera)); requestOnLight=new Invoke(); requestOffLight=new Invoke(); requestOnLight.setCommand(new OnLightCommand(light)); requestOffLight.setCommand(new OffLightCommand(light)); initPosition(); setSize(200,300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } private void initPosition(){ JPanel pSourth=new JPanel(); pSourth.add(requestOnCamera.getButton()); pSourth.add(requestOffCamera.getButton()); pSourth.add(requestOnLight.getButton()); pSourth.add(requestOffLight.getButton()); add(pSourth,BorderLayout.SOUTH); JPanel pNorth=new JPanel(); pNorth.add(light); add(pNorth,BorderLayout.NORTH); JPanel pCenter=new JPanel(); pCenter.setBackground(Color.yellow); pCenter.add(camera); add(pCenter,BorderLayout.CENTER); } public static void main(String agrs[]){ Machine macine=new Machine(); }}