19.命令模式
首先就是我们的 Client 想要实现一个功能,于是它就创建了一个 Command, 为了方便调用将 Command 封装在了 Invoker 中,当我们想调用的时候,Invoker 会执行内部 Command 提供的方法, Receiver 接收到 Command 的请求,为其提供底部支持。
多说无益,我将通过一个例子介绍命令模式。
实例
目前大部分的软件都支持用户自定义界面,比如说我们可以修改字体大小,背景颜色等。我们就以此为例。首先,写出两个类。
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Font {
private String fontSize = "normal";
}
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BackGround {
private String bgColor = "default color";
}
这是 Command, 修改字体大小和背景的类都继承于此。
java
public interface Command {
void execute();
}
我们只是在类中获得一个 Font 类的引用,然后调用setFontSize() 方法对字体的大小进行设置。
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LargeFontCommand implements Command {
private Font font;
@Override
public void execute() {
font.setFontSize("large");
}
}
java
@AllArgsConstructor
@NoArgsConstructor
@Data
public class NormalFontCommand implements Command {
private Font font;
@Override
public void execute() {
font.setFontSize("Normal");
}
}
background类的引用,调背景颜色
java
@NoArgsConstructor
@AllArgsConstructor
@Data
public class CustomBackGround implements Command {
private BackGround backGround;
private String color;
public CustomBackGround(BackGround backGround){
this.backGround = backGround;
}
@Override
public void execute() {
backGround.setBgColor("Custom background");
}
}
java
@AllArgsConstructor
@NoArgsConstructor
@Data
public class DefaultBackground implements Command {
private BackGround backGround;
@Override
public void execute() {
backGround.setBgColor("default color");
}
}
Invoker类存放命令
java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Invoker {
private List<Command> commands = new ArrayList<>();
public void setCommand(int i,Command command){
commands.add(i,command);
}
public void update(int i){
commands.get(i).execute();
}
}
java
public class CommandTest {
public static void main(String[] args) {
Font font = new Font();
BackGround backGround = new BackGround();
NormalFontCommand normalFontCommand = new NormalFontCommand(font);
LargeFontCommand largeFontCommand = new LargeFontCommand(font);
DefaultBackground defaultBackground = new DefaultBackground(backGround);
CustomBackGround customBackGround = new CustomBackGround(backGround);
Invoker invoker = new Invoker();
invoker.setCommand(0,normalFontCommand);
invoker.setCommand(1,largeFontCommand);
invoker.setCommand(2,defaultBackground);
invoker.setCommand(3,customBackGround);
invoker.update(3);
System.out.println(backGround.getBgColor());
}
}
我们首先把所有的命令添加到了 Invoker , 然后直接调用 update() 方法就可以了。
这么做有什么好处呢?看的出来,可以将很多命令放进 Invoker , 它并不知道功能是如何实现的,它就像一个中介, Client 请求一个功能,它就将这个请求转给 Command 去实现。这种模式有很多的用途,比如说多功能遥控器,日志打印等。
还有一点不得不说的,我们可以使用宏命令,什么是宏命令呢?就是写一个 Command ,这个 Command 可以实现多个功能。比如说我们可以同时修改背景和颜色。