java设计模式之命令模式

    命令模式(Command) ,是行为设计模式的一种。Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

解决问题:

    在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。

应用场景:

    在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。

    在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

        - 整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。

        - 调用前后需要对调用参数进行某些处理。

        - 调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等

应用实例:

    struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的Command。

命令模式UML图:

角色和职责:

    Command:ommand抽象类。

    ConcreteCommand:command的具体实现类,需要执行的所有命令都在这里声明。

    Receiver: 调用的目标对象,真正的命令执行对象,命令传到这里应该被执行。

    Invorker: invorker执行Command对象,使用命令对象的入口

实现代码示例:

/**
 * 命令接收者Receiver类
 * 小商贩
 */
public class Peddler {
  //卖苹果
  public void sailApple(){
    System.out.println("卖苹果");
  }
  
  //卖香蕉
  public void sailBanana(){
    System.out.println("卖香蕉");
  }
}

/**
 * Command抽象类
 */
public abstract class Command {
  private Peddler peddler;
  
  public Command(Peddler peddler){
    this.setPeddler(peddler);
  }

  public Peddler getPeddler() {
    return peddler;
  }

  public void setPeddler(Peddler peddler) {
    this.peddler = peddler;
  }
  
  public abstract void sail();
}

public class BananaCommand extends Command {
  public BananaCommand(Peddler peddler) {
    super(peddler);
  }

  @Override
  public void sail() {
    this.getPeddler().sailBanana();
  }
}
public class AppleCommand extends Command {
  public AppleCommand(Peddler peddler) {
    super(peddler);
  }

  @Override
  public void sail() {
    this.getPeddler().sailApple();
  }
}

/**
 * 调用者invoker类
 */
public class Waiter {
  private List<Command> commands = new ArrayList<Command>();
  
  public void setOrder(Command command){
    commands.add(command);
  }
  
  public void removeOrder(Command command){
    commands.remove(command);
  }
  
  public void sail(){
    for(Command command : commands){
      command.sail();
    }
  }
  
}

public class MainClass {

  public static void main(String[] args) {
    //创建Receiver
    Peddler peddler = new Peddler();
    
    Command appleCommand = new AppleCommand(peddler);
    Command bananaCommand = new BananaCommand(peddler);
    
    Waiter waiter = new Waiter();
    //下订单
    waiter.setOrder(appleCommand);
    waiter.setOrder(bananaCommand);
    
    //移除订单某项
//    waiter.removeOrder(appleCommand);
    
    waiter.sail();
  }
}

优点:

1、降低了系统耦合度。类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command 抽象类的方法就可以,不需要了解到底是哪个接收者执行。

2、可扩展性:Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合。

缺点:

使用命令模式可能会导致某些系统有过多的具体命令类。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值