命令模式
介绍
意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。
优点:
- 降低了系统耦合度。
- 新的命令可以很容易添加到系统中去。
缺点:使用命令模式可能会导致某些系统有过多的具体命令类。
使用场景:认为是命令的地方都可以使用命令模式,比如:
- GUI 中每一个按钮都是一条命令。
- 模拟 CMD。
实现
类的组成
- Command(命令类):这是表示命令封装的抽象类。它声明了执行的抽象方法,该方法应该由所有具体命令实现。
- ConcreteCommand(具体命令类):这是命令类的实际实现。它必须执行命令并处理与每个具体命令相关的参数。它将命令委托给接收者。
- Receiver(接收者):这是负责执行与命令关联的操作的类。
- Invoker(调用者):这是触发命令的类。通常是外部事件,比如用户操作。
- Client(客户端):这是实例化具体命令对象及其接收者的实际类。
UML图
代码
public interface Command {
void exec();
}
public class Add implements Command {
private Manager receiver;
public Add(Manager receiver) {
this.receiver = receiver;
}
@Override
public void exec() {
receiver.add();
}
}
/////////////////////////////
public class Update implements Command {
private Manager receiver;
public Update(Manager receiver) {
this.receiver = receiver;
}
@Override
public void exec() {
receiver.update();
}
}
/////////////////////////////
public class Delete implements Command {
private Manager receiver;
public Delete(Manager receiver) {
this.receiver = receiver;
}
@Override
public void exec() {
receiver.delete();
}
}
public class Manager {
public void add(){
System.out.println("add");
}
public void update(){
System.out.println("update");
}
public void delete(){
System.out.println("delete");
}
}
public class Committer {
private List<Command> commandList = new ArrayList<>();
public void addCommand(Command command){
commandList.add(command);
}
public void commit(){
for (Command command : commandList)
command.exec();
commandList.clear();
}
}
public class Main {
public static void main(String[] args) {
Manager manager = new Manager();
Add add = new Add(manager);
Update update = new Update(manager);
Delete delete = new Delete(manager);
Committer committer = new Committer();
committer.addCommand(delete);
committer.addCommand(add);
committer.addCommand(update);
committer.commit();
}
}