java

位置:IT落伍者 >> java >> 浏览文章

java设计模式之Command(菜单命令)


发布日期:2022年06月12日
 
java设计模式之Command(菜单命令)

Command模式是最让我疑惑的一个模式我在阅读了很多代码后才感觉隐约掌握其大概原理我认为理解设计模式最主要是掌握起原理构造这样才对自己实际编程有指导作用Command模式实际上不是个很具体规定很多的模式正是这个灵活性让人有些confuse

Command定义

不少Command模式的代码都是针对图形界面的它实际就是菜单命令我们在一个下拉菜单选择一个命令时然后会执行一些动作

将这些命令封装成在一个类中然后用户(调用者)再对这个类进行操作这就是Command模式换句话说本来用户(调用者)是直接调用这些命令的如菜单上打开文档(调用者)就直接指向打开文档的代码使用Command模式就是在这两者之间增加一个中间者将这种直接关系拗断同时两者之间都隔离基本没有关系了

显然这样做的好处是符合封装的特性降低耦合度Command是将对行为进行封装的典型模式Factory是将创建进行封装的模式

从Command模式我也发现设计模式一个通病:好象喜欢将简单的问题复杂化 喜欢在不同类中增加第三者当然这样做有利于代码的健壮性 可维护性 还有复用性

如何使用?

具体的Command模式代码各式各样因为如何封装命令不同系统有不同的做法下面事例是将命令封装在一个Collection的List中任何对象一旦加入List中实际上装入了一个封闭的黑盒中对象的特性消失了只有取出时才有可能模糊的分辨出:

典型的Command模式需要有一个接口接口中有一个统一的方法这就是将命令/请求封装为对象:

public interface Command {

public abstract void execute ( );

}

具体不同命令/请求代码是实现接口Command下面有三个具体命令

public class Engineer implements Command {

public void execute( ) {

//do Engineers command

}

}

public class Programmer implements Command {

public void execute( ) {

//do programmers command

}

}

public class Politician implements Command {

public void execute( ) {

//do Politicians command

}

}

按照通常做法我们就可以直接调用这三个Command但是使用Command模式我们要将他们封装起来扔到黑盒子List里去:

public class producer{

public static List produceRequests() {

List queue = new ArrayList();

queueadd( new DomesticEngineer() );

queueadd( new Politician() );

queueadd( new Programmer() );

return queue;

}

}

这三个命令进入List中后已经失去了其外表特征以后再取出也可能无法分辨出谁是Engineer 谁是Programmer了看下面如何调用Command模式:

  1. public class TestCommand {

    public static void main(String[] args) {

    List queue = ProducerproduceRequests();

    for (Iterator it = erator(); ithasNext(); )

    //取出List中东东其他特征都不能确定只能保证一个特征是%正确

    // 他们至少是接口Command的儿子所以强制转换类型为接口Command

    ((Command)itnext())execute();

    }

    }

由此可见调用者基本只和接口打交道不合具体实现交互这也体现了一个原则面向接口编程这样以后增加第四个具体命令时就不必修改调用者TestCommand中的代码了

理解了上面的代码的核心原理在使用中就应该各人有自己方法了特别是在如何分离调用者和具体命令上有很多实现方法上面的代码是使用从List过一遍的做法这种做法只是为了演示

使用Command模式的一个好理由还因为它能实现Undo功能每个具体命令都可以记住它刚刚执行的动作并且在需要时恢复               

上一篇:Java多线程编程基础之线程对象

下一篇:Java Swing多线程死锁问题解析