目录
- 1. 简介
- 2. 代码
- 2.1 Order (命令接口)
- 2.2 Stock (接收者类)
- 2.3 Buy (具体命令类)
- 2.4 Sell (具体命令类)
- 2.5 Broker (调用者类)
- 2.6 Test (测试)
- 2.7 运行结果
- 3. 使用场景
- 4. 优缺点
- 5. 总结
1. 简介
命令模式(Command Pattern) 是一种行为设计模式,它将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。
命令模式的结构
命令(Command)接口
这是所有具体命令类都要实现的接口,它声明了一个执行命令的方法。
具体命令(Concrete Command)类
这些类实现了命令接口,在其中包含了接收者对象,并在执行方法中调用接收者的相应方法来完成具体的操作。
接收者(Receiver)类
接收者是实际执行命令的对象。
调用者(Invoker)类
调用者负责设置命令对象,并在需要的时候调用命令对象的执行方法。
2. 代码
2.1 Order (命令接口)
public interface Order {public void execute();
}
2.2 Stock (接收者类)
public class Stock {private String name = "ABC";private int quantity = 10;public void buy(){System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] bought");}public void sell(){System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] sold");}
}
2.3 Buy (具体命令类)
public class Buy implements Order{private Stock stock;public Buy(Stock stock) {this.stock = stock;}@Overridepublic void execute() {stock.buy();}
}
2.4 Sell (具体命令类)
public class Sell implements Order{private Stock stock;public Sell(Stock stock){this.stock = stock;}@Overridepublic void execute(){stock.sell();}
}
2.5 Broker (调用者类)
import java.util.ArrayList;
import java.util.List;public class Broker {List<Order> orderList = new ArrayList<Order>();public void takeOrder(Order order){orderList.add(order);}public void placeOrders(){for (Order order : orderList){order.execute();}orderList.clear();}
}
2.6 Test (测试)
public class Test {public static void main(String[] args) {Broker broker = new Broker();Stock stock = new Stock();broker.takeOrder(new Buy(stock));broker.takeOrder(new Sell(stock));broker.placeOrders();}
}
2.7 运行结果
Stock [ Name: ABC, Quantity: 10 ] bought
Stock [ Name: ABC, Quantity: 10 ] sold
3. 使用场景
- 解耦请求发送者和接收者:命令模式可以有效地将请求的发起者(调用者)与接收者(执行者)解耦合。例如,在GUI应用中,用户点击按钮时,命令模式可以将按钮的操作封装为命令对象,从而使得按钮的功能独立于具体的实现逻辑。这样,用户界面元素如按钮可以不直接依赖于具体的业务逻辑,从而提高了代码的可维护性和可扩展性。
- 支持撤销和重做操作:命令模式非常适合需要实现撤销和重做功能的场景。通过记录每个操作的历史状态,命令模式可以轻松地实现这些功能。例如,在文本编辑器中,用户可以撤销或重做之前的操作。
- 命令队列和任务调度:命令模式可以用于构建命令队列或任务调度器,允许将命令对象排队并按顺序执行,或者根据需要对它们进行调度。这在多线程编程中尤其有用,因为命令对象可以在不同的线程中执行。
- 日志记录和审计:命令模式可以用于记录操作日志,这对于事务系统中的操作日志记录非常有用。通过命令对象的执行历史,可以方便地进行审计和回溯。
- 宏命令和批处理脚本:命令模式支持宏命令,即组合多个命令为一个操作,这在批处理脚本或复合操作中非常常见。
- 抽象设备控制:在需要控制不同设备的场景中,命令模式可以简化设备控制逻辑。例如,使用一个通用的遥控器来控制不同类型的相机,每个相机有不同的串行协议,但可以通过统一的命令接口进行操作。
- 事务管理:在需要管理多个操作的系统中,命令模式可以用来记录每个操作,并在需要时执行或撤销这些操作。例如,在事务处理系统中,可以使用命令模式来实现事务的提交、回滚操作。
- 游戏设计:在游戏设计中,命令模式常用于解耦行为请求者与行为执行者之间的关系,支持复杂的任务调度和管理。
- Web开发:在Web开发中,命令模式可以用于简化用户界面按钮功能的实现,例如在网页设计中通过命令模式来处理用户点击事件。
命令模式通过封装请求为对象,实现了请求与执行的解耦,提高了系统的灵活性和可扩展性。它适用于需要灵活处理请求、支持撤销和重做、以及需要解耦请求发送者和接收者的场景。
4. 优缺点
-
命令模式的优点:
- 降低系统耦合度:命令模式通过将请求封装成命令对象,使得请求的发送者和接收者之间不再直接交互,从而降低了系统的耦合度。
- 易于扩展:命令模式允许在不修改现有代码的情况下添加新的命令,符合开闭原则。因此,可以方便地扩展系统功能。
- 支持撤销和重做操作:命令模式可以轻松实现撤销(Undo)和重做(Redo)功能,这对于需要回溯操作的应用场景非常有用。
- 支持命令队列和日志记录:命令对象可以被序列化、存储,从而支持请求的排队和日志记录,这有助于系统的跟踪和调试。
- 组合命令:多个命令可以组合成一个复合命令,通过调用一个复合命令来依次执行多个操作,方便管理多个命令的执行。
- 灵活性和可维护性:由于每个命令都是独立的,因此可以在不影响其他部分的情况下进行维护和调试。
-
命令模式的缺点:
- 类数量增加:使用命令模式可能会导致系统中出现过多的具体命令类,这会增加系统的复杂性。
- 性能开销:由于每个命令都需要创建一个实例,这可能会增加内存消耗,并且在高频率操作中可能会影响性能。
- 调试难度增加:命令的执行过程可能涉及多个对象之间的交互,调试时需要跟踪多个类的状态和行为,这可能会增加调试的复杂性。
- 系统复杂性增加:如果业务场景中命令比较多,那么对应命令类和命令对象的数量也会增加,这样系统会膨胀得很大。
- 理解上的困难:为了以命令的形式进行架构,解耦请求与实现,引入了额外类型接口(引入了请求方与抽象命令接口),增加了理解上的困难。
5. 总结
我觉得有点像代理,将类的方法包装成一列,执行代码,将会执行一系列的代码。