交互模式中的命令模式,在开始记录之前,要讲些自己的感受,真真切切的感受到了悟性的瓶颈!一共十页书,需要自己细细琢磨品味,至少三四遍才大概了解了他们间的逻辑,我需要调整下自己的学习思路,我之前是先看一遍(没看懂)然后去照着代码复现一遍,然后再看,效率低的不行,两个半小时十页书籍,悟性极差哇。
开始今天的小记:
先抓一下重点!找好它们之间的关联关系,通顺了之后,就可以小小的入门了。
目的为了实现发送请求者和接收者的解耦,实现一个有限的技能页面,技能页面只能同时放五个技能,而我当前后台可能有几十个技能。后端要则么知道我前端点的哪个技能呢?做一一对应嘛?在哪儿做,有没有更好的设计模式可以实现呢,带着这个问题开始今天的小记
命令模式的本质,是对请求进行封装,一个请求对应一个命令,将发出命令的责任和执行命令的责任划分开
命令模式的关键,在于引入了抽象命令类,请求发送这针对于抽象命令类进行编程,只有实现了抽象命令类的具体命令才与请求接收者相关联
在命令模式中,发送者与接收者之间引入了新的命令对象,将发送者的请求封装在命令对象中,再通过命令对象来调用接收者的方法
一个调用者,并不需要再设计时确定其接收者,因此他只与抽象命令类之间存在关联关系,在程序运行时可以将一个具体命令对象注入其中,再调用具体命令对象的execute方法,
实现间接调用请求者的相关操作 
上面这四句话,是我摘抄书上的原话,理解了很久,终于结合代码可以梳理明白了,下面我会写出类相关的关系。
例子 FBSettingWindow是“功能键设置”界面类, FunctionButton充当请求调用者, Command充当抽象命令类, MinimizeCommand和HelpCommand充当具体命令类, WindowHandler和HelpHandler充当请求接收者。
FBSettingWindow就相当于是我们的技能页面
FunctionButton 就是那一个个技能按钮
Command就是技能实现的抽象类
MinimizeCommand和HelpCommand就是链接技能效果的中间点
WindowHandler和HelpHandler充当请求接收者。
WindowHandler和HelpHandler就是技能的效果
完整代码如下:

<?xml version = "1.0"?>
<config>
    <className>com.book.com.cor.command.test.HelpCommand</className>
    <className>com.book.com.cor.command.test.MinimizeCommand</className>
</config>
 
 
关联关系图:

package com.book.com.cor.command.test;
/**
 * @author liums
 * @date 2024/7/28 16:10
 * @description Client
 */
public class Client {
    public static void main(String[] args) {
        FBSettingWindows fb = new FBSettingWindows("功能键设置"); //
        FunctionButton fb1,fb2;
        fb1 = new FunctionButton("功能键1");
        fb2 = new FunctionButton("功能键2");
        Command command1,command2;
        // 通过读取配置文件和反射生成具体命令对象
        command1 =(Command) XMLUtil.getBean(0);
        command2 =(Command) XMLUtil.getBean(1);
        // 将命令对象注入功能键
        fb.addFunctionButton(fb1);
        fb.addFunctionButton(fb2);
        fb.display();
        // 调用功能键的业务方法
        fb1.onClick();
        fb2.onClick();
    }
}
 
package com.book.com.cor.command.test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
/**
 * @author liums
 * @date 2024/7/28 15:57
 * @description XMLUtil 该方法用于从xml文件中提取具体类类名,兵返回一个实例对象,可以通过参数的不同返回不同的实例
 */
public class XMLUtil {
    public static Object getBean(int i) {
        try {
            // 创建文档对象
            DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dfactory.newDocumentBuilder();
            Document doc;
            doc = builder.parse(new File("src/main/resources/config.xml"));
            // 获取包含类名的文本节点
            NodeList nl = doc.getElementsByTagName("className");
            Node classNode = null;
            if (0 == i){
               classNode =  nl.item(0).getFirstChild();
            }else {
                classNode =  nl.item(1).getFirstChild();
            }
            String cName = classNode.getNodeValue();
            // 通过类名生成实例对象,并且将其返回
            Class c = Class.forName(cName);
            Object o = c.newInstance();
            return o;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}
 
package com.book.com.cor.command.test;
/**
 * @author liums
 * @date 2024/7/28 15:55
 * @description WindowsHandler
 */
public class WindowsHandler {
    public void minimize(){
        System.out.println("将窗口最小化至托盘!");
    }
}
 
package com.book.com.cor.command.test;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author liums
 * @date 2024/7/28 15:54
 * @description MinimizeCommand
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class MinimizeCommand extends Command{
    private WindowsHandler whObj;
    @Override
    public void execute() {
        whObj = new WindowsHandler();
    }
}
 
package com.book.com.cor.command.test;
/**
 * @author liums
 * @date 2024/7/28 15:53
 * @description HelpHandler
 */
public class HelpHandler {
    public void display(){
        System.out.println("显示帮助文档");
    }
}
 
package com.book.com.cor.command.test;
/**
 * @author liums
 * @date 2024/7/26 22:24
 * @description 抽象命令类,请求发送者针对抽象命令类编程,只有实现了抽象命令类的具体命令才能和请求接收者相关联
 */
abstract class Command {
    public abstract void execute();
}
 
package com.book.com.cor.command.test;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.ArrayList;
/**
 * @author liums
 * @date 2024/7/28 15:44
 * @description FBSettingWindows
 */
public class FBSettingWindows {
    private String title;
    // 储存所有功能键
    private ArrayList<FunctionButton> functionButtons = new ArrayList<FunctionButton>();
    public FBSettingWindows(String title) {
        this.title = title;
    }
    public void addFunctionButton(FunctionButton button){
        functionButtons.add(button);
    }
    public void removeButton(FunctionButton button){
        functionButtons.remove(button);
    }
    public void display(){
        System.out.println("窗口显示:"+this.title);
        System.out.println("显示功能键");
        for (FunctionButton functionButton : functionButtons) {
            System.out.println(functionButton.getName());
        }
        System.out.println("-----------------------------------");
    }
}
 
 
package com.book.com.cor.command.test;
import jdk.nashorn.internal.objects.annotations.Getter;
import jdk.nashorn.internal.objects.annotations.Setter;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author liums
 * @date 2024/7/28 15:38
 * @description FunctionButton 请求发送者
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class FunctionButton {
    private Command command;
    private String name;
    public void onClick(){
        System.out.println("点击功能键:");
        command.execute();
    }
    public FunctionButton(String name) {
        this.name = name;
    }
}
 
package com.book.com.cor.command.test;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author liums
 * @date 2024/7/28 15:49
 * @description HelpCommand 帮助命令类:具体命令类
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class HelpCommand extends Command{
    private HelpHandler helpCommand;
    @Override
    public void execute() {
        helpCommand.display();
    }
}
                


















