**
设计模式之命令模式详解
**
命令模式(Command Pattern 别名:动作,事务)
1,概述
命令模式是处理一个对象请求另一个对象调用其方法完成某项任务的一种成熟的模式,提出请求的对象为请求者,被请求的对象为接收者。在命令模式中,当一个对象请求另一个对象调用其方法时,不与被请求的对象直接打交道,而是吧这种“请求”封装到一个称作“命令”的对象的方法中。这样,当一个对象请求另一个对象调用方法来完成某项任务时,只需和命令打交道,即让命令对象调用封装了“请求”的那个方法即可。
2,模式的结构
- 接收者(Receiver): 接收者是一个实例,负责执行与请求相关的操作。
- 命令(Command)接口:命令是一个接口,封装“请求”的若干个方法。
- 具体命令(ConcreteCommand): 实现命令接口的类的实例。具体命令必须实现命令接口中的方法。
- 请求者(Invoker): 包含Command接口变量的类的实例。请求者中的Command接口的变量可以存放任何具体命令的引用,请求者负责调用具体命令,让具体命令执行那些封装了“请求”的方法。
3,命令模式的优点
- 请求者(Invoker)不直接与接收者(Receiver)交互,即请求者不包含接收者的引用,因此彻底消除了彼此之间的耦合。
- 满足“开-闭原则”,如果新增加了具体命令和该命令的接收者,则不必修改调用者的代码,调用者就可以使用新的命令对象,反之,如果增加了新的调用者,也不必修改现有的具体命令和接收者,新增的调用者就可以使用已有的具体命令。
- 由于请求者的请求被封装到了具体的命令中,那么就可以将具体命令保存到持久化的媒介中,需要的时候重新执行这个命令,因此,命令模式可以纪录日志。
- 用命令模式可以对请求者的“请求”进行排队,每个请求都各自对应一个具体命令,因此可以按一定的顺序执行这些具体命令。
- 程序支持撤销操作,可以在具体命令中封装一个撤销请求的方法。
4,小案例-模拟小电器
借助javax.swing包提供的组件并使用命令模式模拟一个带控制开关的小电器,该电器上有4个开关,2个一组,其中一组负责打开/关闭小电器上的照明灯,另一组负责打开/关闭小电器上的摄像头。
package com.company.learn.DesignPattern.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("/Users/hfc/IdeaProjects/src/com/company/learn/DesignPattern/CommandPattern/cameraOpen.jpg"));
}
public void off(){
label.setIcon(new ImageIcon("/Users/hfc/IdeaProjects/src/com/company/learn/DesignPattern/CommandPattern/cameraClosed.jpg"));
}
}
package com.company.learn.DesignPattern.CommandPattern;
import javax.swing.*;
public class Ligth extends JPanel {
String name;
Icon imageIcon;
JLabel label;
public Ligth(){
label = new JLabel("我是照明灯");
add(label);
}
public void on(){
label.setIcon(new ImageIcon("/Users/hfc/IdeaProjects/src/com/company/learn/DesignPattern/CommandPattern/lightOpen.jpg"));
}
public void off(){
label.setIcon(new ImageIcon("/Users/hfc/IdeaProjects/src/com/company/learn/DesignPattern/CommandPattern/lightClosed.jpg"));
}
}
package com.company.learn.DesignPattern.CommandPattern;
public interface Command {
public abstract void execute();
public abstract String getName();
}
package com.company.learn.DesignPattern.CommandPattern;
public class OffCameraCommand implements Command {
Camera camera;
public OffCameraCommand(Camera camera) {
this.camera = camera;
}
public void execute() {
camera.off();
}
public String getName() {
return "关闭摄像头";
}
}
package com.company.learn.DesignPattern.CommandPattern;
public class OffLightCommand implements Command{
Ligth light;
OffLightCommand(Ligth light){
this.light =light;
}
public void execute() {
light.off();
}
public String getName() {
return "关闭照明灯";
}
}
package com.company.learn.DesignPattern.CommandPattern;
public class OnCameraCommand implements Command{
Camera camera;
OnCameraCommand(Camera camera){
this.camera = camera;
}
public void execute() {
camera.on();
}
public String getName() {
return "打开摄像头";
}
}
package com.company.learn.DesignPattern.CommandPattern;
public class OnLightCommand implements Command{
Ligth light;
OnLightCommand(Ligth light){
this.light = light;
}
public void execute() {
light.on();
}
public String getName() {
return "打开照明灯";
}
}
package com.company.learn.DesignPattern.CommandPattern;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Invoke {
JButton jButton;
Command command;
Invoke(){
jButton = new JButton();
jButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
executeCommand();
}
});
}
public void setCommand(Command command){
this.command = command;
jButton.setText(command.getName());
}
public JButton getjButton(){
return jButton;
}
private void executeCommand(){
command.execute();
}
}
package com.company.learn.DesignPattern.CommandPattern;
import javax.crypto.Mac;
import javax.swing.;
import java.awt.;
public class Machine extends JFrame{
Invoke requestOnCarema,requestOnLight,requestOffCamera,requestOffLight;
Camera camera;
Ligth ligth;
Machine(){
setTitle(“小电器”);
requestOnCarema = new Invoke();
requestOffCamera = new Invoke();
camera = new Camera();
ligth = new Ligth();
requestOnCarema.setCommand(new OnCameraCommand(camera));
requestOffCamera.setCommand(new OffCameraCommand(camera));
requestOnLight = new Invoke();
requestOffLight = new Invoke();
requestOnLight.setCommand(new OnLightCommand(ligth));
requestOffLight.setCommand(new OffLightCommand(ligth));
initPosition();
setSize(500,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void initPosition(){
JPanel pSourth = new JPanel();
pSourth.add(requestOnCarema.getjButton());
pSourth.add(requestOffCamera.getjButton());
pSourth.add(requestOnLight.getjButton());
pSourth.add(requestOffLight.getjButton());
add(pSourth,BorderLayout.SOUTH);
JPanel pNorth = new JPanel();
pNorth.add(ligth);
add(pNorth,BorderLayout.NORTH);
JPanel pCenter = new JPanel();
pCenter.setBackground(Color.yellow);
pCenter.add(camera);
add(pCenter,BorderLayout.CENTER);
}
public static void main(String[] args) {
Machine machine = new Machine();
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201213191705847.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmN
zZG4ubmV0L2h1ZmMxMDEz,size_16,color_FFFFFF,t_70#pic_center)