总纲
- 设计原则:遵循迪米特、开闭原则
- 常用场景:行为的请求者与行为的处理者耦合度过高
- 使用概率:20%
- 复杂度:中高
- 变化点:命令的种类
- 选择关键点:请求者是否不需要关心命令的执行只知道接受者
- 逆鳞:命令的种类无限制增长
- 相关设计模式
- 职责链模式:容易将二者关联在一起的原因是,二者都是为了处理请求或者命令而存在的,而且二者都是为了将请求者与响应者解耦,不同的是命令模式中,客户端需要知道一个命令的接受者,在创建命令的时候就把接受者与命令绑定在一起发送给调用者,而职责链模式中,客户端并不关心最终处理请求的对象是谁,客户端只是封装一个请求对象,随后交给职责链的头部而已,也正因为这样,二者的实现方式,有着很大的区别
命令模式
-
命令模式, 例子举的蛮好。
在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。例子中有类保持takeOrder,takeOrder中可以记录command, 也可以有方法撤销命令。最终执行是placeOrders。解耦
uml类图
![](https://img.haomeiwen.com/i15057487/048d74adace07c1b.png)
命令模式.png
对应代码
public interface Task {
void handle();
}
public class Demand implements Task{
private Programmer programmer;
public Demand(Programmer programmer) {
super();
this.programmer = programmer;
}
public void handle() {
programmer.handleDemand();
}
public String toString() {
return "Demand [programmer=" + programmer.getName() + "]";
}
}
public class Bug implements Task{
private Programmer programmer;
public Bug(Programmer programmer) {
super();
this.programmer = programmer;
}
public void handle() {
programmer.handleBug();
}
public String toString() {
return "Bug [programmer=" + programmer.getName() + "]";
}
}
public class Problem implements Task{
private Programmer programmer;
public Problem(Programmer programmer) {
super();
this.programmer = programmer;
}
public void handle() {
programmer.handleProblem();
}
public String toString() {
return "Problem [programmer=" + programmer.getName() + "]";
}
}
public class ProductManager {
private static final int TASK_NUMBER_IN_DAY = 4;//一天最多分派掉四个任务,多了推到第二天
private List<Task> taskList;
private List<Programmer> programmerList;//产品经理应该认识所有的程序猿
private int currentIndex;
public ProductManager(Programmer... programmers) {
super();
if (programmers == null || programmers.length == 0) {
throw new RuntimeException("产品经理手下没有程序员,任务分配不出去,无法正常工作!");
}
taskList = new ArrayList<Task>();
programmerList = Arrays.asList(programmers);
}
//接受一个任务
public void receive(Task task){
taskList.add(task);
}
public void assign(){
Task[] copy = new Task[taskList.size() > TASK_NUMBER_IN_DAY ? taskList.size() - TASK_NUMBER_IN_DAY : 0];
for (int i = 0; i < TASK_NUMBER_IN_DAY && i < taskList.size(); i++) {
taskList.get(i).handle();
}
System.arraycopy(taskList.toArray(), TASK_NUMBER_IN_DAY > taskList.size() ? taskList.size() : TASK_NUMBER_IN_DAY, copy, 0, copy.length);
taskList = Arrays.asList(copy);
}
//产品经理可以选择程序猿,简单的循环选取。
public Programmer chooseProgrammer(){
return programmerList.get(currentIndex == programmerList.size() ? 0 : currentIndex++);
}
public void printTaskList(){
if (taskList == null || taskList.size() == 0) {
System.out.println("----------当前无任务--------");
return;
}
System.out.println("---------当前剩下的任务列表--------");
for (Task task : taskList) {
System.out.println(task);
}
System.out.println("----------------------------------");
}
}
public class Salesman {
private String name;
private ProductManager productManager;
public Salesman(String name) {
super();
this.name = name;
}
public Salesman(String name, ProductManager productManager) {
super();
this.name = name;
this.productManager = productManager;
}
public void putDemand(){
System.out.println( "业务员" + name + "提出新需求");
productManager.receive(new Demand(productManager.chooseProgrammer()));
}
public void putBug(){
System.out.println( "业务员" + name + "提出bug");
productManager.receive(new Bug(productManager.chooseProgrammer()));
}
public void putProblem(){
System.out.println( "业务员" + name + "提出线上问题");
productManager.receive(new Problem(productManager.chooseProgrammer()));
}
public String getName() {
return name;
}
public ProductManager getProductManager() {
return productManager;
}
public void setProductManager(ProductManager productManager) {
this.productManager = productManager;
}
}
public class Work {
public static void main(String[] args) {
Programmer xiaozuo = new Programmer("小左");
ProductManager productManager = new ProductManager(xiaozuo);
Salesman salesmanA = new Salesman("A",productManager);
Salesman salesmanB = new Salesman("B",productManager);
Salesman salesmanC = new Salesman("C",productManager);
Salesman salesmanD = new Salesman("D",productManager);
salesmanA.putDemand();
salesmanB.putDemand();
salesmanB.putBug();
salesmanC.putDemand();
salesmanC.putProblem();
salesmanD.putDemand();
System.out.println("第一天产品经理分配任务");
productManager.assign();
productManager.printTaskList();
System.out.println("第二天产品经理分配任务");
productManager.assign();
productManager.printTaskList();
}
}
- 最大的优点,就是将行为请求者和行为实现者解耦。
- 命令的添加特别方便,并且可以方便的制定各种命令和利用现有命令组合出新的命令。
网友评论