java设计模式_命令模式 两个不同风格的实现

 

 Command模式(命令)
  Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循一定的编程模式,才能使自己的代码便于理解,易于交流,Command(命令模式)模式是比较常用的一个模式.
   Command命令模式:Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数。将一个请求封装为一个对象,从而使你不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
   优点:解耦了调用者和接受者之间联系。调用者调用一个操作,接受者接受请求执行相应的动作,因为使用Command模式解耦,调用者无需知道接受者任何接口。
   缺点:造成出现过多的具体命令类
  
  在此写了7个java类来描述说明Command设计模式的实现方式;

  1、Control.java       命令控制者对象类
  2、Tv.java            命令接收者对象类
  3、Command.java       命令接口类
  4、CommandChannel.java 频道切换命令类
  5、CommandOff.java    关机命令类
  6、CommandOn.java     开机命令类
  7、CommandTest.java   带有main方法的测试类(命令发送者)

 

===============  1、 Control.java
package command;

//命令控制者
public class Control {
  private Command onCommand, offCommand,changeChannel;

  public Control(Command on, Commandoff, Command channel) {
   onCommand = on;
   offCommand = off;
   changeChannel = channel;
  }

  public void turnOn() {
   onCommand.execute();
  }

  public void turnOff() {
   offCommand.execute();
  }

  public void changeChannel() {
   changeChannel.execute();
  }
}
===============   1end

 

===============  2、 Tv.java
package command;

//命令接收者
public class Tv {

  public int currentChannel = 0;

  public void turnOn() {
   System.out.println("The televisino is on.");
  }

  public void turnOff() {
   System.out.println("The television is off.");
  }

  public void changeChannel(int channel){
   this.currentChannel = channel;
   System.out.println("Now TV channel is " + channel);
  }
}
===============   2end

 

===============  3、 Command.java
package command;

//命令接口
public interface Command {
  void execute();
}
===============   3end

 

===============  4、 CommandChannel.java
package command;

//频道切换命令
public class CommandChannel implements Command {
  private Tv myTv;

  private int channel;

  public CommandChannel(Tv tv, intchannel) {
   myTv = tv;
   this.channel = channel;
  }

  public void execute() {
   myTv.changeChannel(channel);
  }
}
===============   4end

 

===============  5、 CommandOff.java
package command;

//关机命令
public class CommandOff implements Command {
  private Tv myTv;

  public CommandOff(Tv tv) {
   myTv = tv;
  }

  public void execute() {
   myTv.turnOff();
  }
}
===============   5end

 

===============  6、 CommandOn.java
package command;

//开机命令
public class CommandOn implements Command {
  private Tv myTv;

  public CommandOn(Tv tv) {
   myTv = tv;
  }

  public void execute() {
   myTv.turnOn();
  }
}
===============   6end

 

===============  7、 CommandTest.java
package command;

//命令发送者
public class CommandTest{
  public static void main(String[]args){
   //命令接收者
   Tv  myTv = new Tv();
   //开机命令
   CommandOn on = new CommandOn(myTv);
   //关机命令
   CommandOff off = new CommandOff(myTv);
   //频道切换命令
   CommandChannel channel = new CommandChannel(myTv, 2);
   //命令控制对象
   Control control = new Control( on, off, channel);

   //开机
   control.turnOn();
   //切换频道
   control.changeChannel();
   //关机
   control.turnOff();
  }
}
===============   7end

  Command模式通常可应用到以下场景:
  1 Multi-levelundo(多级undo操作)
   如果系统需要实现多级回退操作,这时如果所有用户的操作都以command对象的形式实现,系统可以简

   单地用stack来保存最近执行的命令,如果用户需要执行undo操作,系统只需简单地popup一个最近的

   command对象然后执行它的undo()方法既可。
 
  2 Transactionalbehavior(原子事务行为)
   借助command模式,可以简单地实现一个具有原子事务的行为。当一个事务失败时,往往需要回退到执

   行前的状态,可以借助command对象保存这种状态,简单地处理回退操作。

 

 
3
Progressbars(状态条)
   假如系统需要按顺序执行一系列的命令操作,如果每个command对象都提供一个

   getEstimatedDuration()方法,那么系统可以简单地评估执行状态并显示出合适的状态条。

 

 
4
Wizards(导航)
   通常一个使用多个wizard页面来共同完成一个简单动作。一个自然的方法是使用一个command对象来封

   装wizard过程,该command对象在第一个wizard页面显示时被创建,每个wizard页面接收用户输入并设

   置到该command对象中,当最后一个wizard页面用户按下“Finish”按钮时,可以简单地触发一个事件

   调用execute()方法执行整个动作。通过这种方法,command类不包含任何跟用户界面有关的代码,可以

   分离用户界面与具体的处理逻辑。

 

 
5
GUI buttons andmenu items(GUI按钮与菜单条等等)
   Swing系统里,用户可以通过工具条按钮,菜单按钮执行命令,可以用command对象来封装命令的执行。

 

 
6
Threadpools(线程池)
   通常一个典型的线程池实现类可能有一个名为addTask()的public方法,用来添加一项工作任务到任务

   队列中。该任务队列中的所有任务可以用command对象来封装,通常这些command对象会实现一个通用的

   接口比如java.lang.Runnable。

 

 
7
Macrorecording(宏纪录)
   可以用command对象来封装用户的一个操作,这样系统可以简单通过队列保存一系列的command对象的状

   态就可以记录用户的连续操作。这样通过执行队列中的command对象,就可以完成"Play back"操作了。

 

 
8
Networking
   通过网络发送command命令到其他机器上运行。

 

 
9
ParallelProcessing(并发处理)
   当一个调用共享某个资源并被多个线程并发处理时。

实例二:

package command2;

public class AddRequirementCommand extends Command {
     //执行增加一项需求的命令
     public void execute() {
      //找到需求组
      super.rg.find();
       
      //增加一份需求
      super.rg.add();
       
      //给出计划
      super.rg.plan();
     }
    
    }
----------------------------------------------------------

package command2;

public class Client {
     
     public static void main(String[] args) {
       
    
      //定义我们的接头人
        Invoker xiaoSan = newInvoker();  //接头人就是我小三
        
       //客户要求增加一项需求
       System.out.println("-------------客户要求增加一项需求-----------------");
       //客户给我们下命令来
        Command command = newAddRequirementCommand();
        
       //接头人接收到命令
        xiaoSan.setCommand(command);
        
       //接头人执行命令
        xiaoSan.action();
       
       
       
       
     }
    }
   ------------------------------------------------------------------
package command2;

public class CodeGroup extends Group {
  
  //客户要求代码组过去和他们谈
  public void find() {
   System.out.println("找到代码组...");
  }
 
  
  //客户要求增加一项功能
  public void add() {
   System.out.println("客户要求增加一项功能...");
  }
//客户要求修改一项功能
  public void change() {
    System.out.println("客户要求修改一项功能...");
   }
  //客户要求删除一项功能
  public void delete() {
    System.out.println("客户要求删除一项功能...");
   }
  //客户要求出变更计划
  public void plan() {
    System.out.println("客户要求代码变更计划...");
   }
}
----------------------------------------------------------------
package command2;

public abstract class Command {
     
     //把三个组都定义好,子类可以直接使用
     protected RequirementGroup rg = newRequirementGroup();  //需求组
     protected PageGroup pg = newPageGroup();  //美工组
     protected CodeGroup cg = newCodeGroup();  //代码组;
     
     //只要一个方法,你要我做什么事情
     public abstract void execute();
       
    }
------------------------------------------------------------------
package command2;

public class DeletePageCommand extends Command {
     
     //执行删除一个页面的命令
     public void execute() {
      //找到页面组
      super.pg.find();
       
      //删除一个页面
      super.rg.delete();
       
       //给出计划
      super.rg.plan();
     }
    
}
----------------------------------------------------------------------
package command2;

public abstract class Group {
    
     //甲乙双方分开办公,你要和那个组讨论,你首先要找到这个组
     public abstract void find();
     
     //被要求增加功能
     public abstract void add();
     
     //被要求删除功能
     public abstract void delete();
     
     //被要求修改功能
     public abstract void change();
     //被要求给出所有的变更计划
     public abstract void plan();
     
     
    }

---------------------------------------------------------------------
package command2;

public class Invoker {
     //什么命令
     private Command command;
     
     //客户发出命令
     public void setCommand(Command command){
       this.command= command;
     }
     
     //执行客户的命令
     public void action(){
      this.command.execute();
     }
}
-----------------------------------------------------------------------
package command2;

public class PageGroup extends Group {
     
     //首先这个美工组应该被找到吧,要不你跟谁谈?
     public void find() {
      System.out.println("找到美工组...");
     }
     
     //美工被要求增加一个页面
     public void add() {
      System.out.println("客户要求增加一个页面...");
     }
    
     //客户要求对现有界面做修改
     public void change() {
      System.out.println("客户要求修改一个页面...");
     }
     //甲方是老大,要求删除一些页面
     public void delete() {
      System.out.println("客户要求删除一个页面...");
     }
     
     //所有的增删改那要给出计划呀
     public void plan() {
      System.out.println("客户要求页面变更计划...");
     }
   } 
--------------------------------------------------------------------------------
package command2;

public class RequirementGroup extends Group {
     
     //客户要求需求组过去和他们谈
     public void find() {
      System.out.println("找到需求组...");
     }
    
     //客户要求增加一项需求
     public void add() {
      System.out.println("客户要求增加一项需求...");
     }
   //客户要求修改一项需求
     public void change() {
       System.out.println("客户要求修改一项需求...");
      }
     //客户要求删除一项需求
     public void delete() {
       System.out.println("客户要求删除一项需求...");
      }
     //客户要求出变更计划
     public void plan() {
       System.out.println("客户要求需求变更计划...");
     }
    
}

时间: 2024-10-03 01:10:12

java设计模式_命令模式 两个不同风格的实现的相关文章

Java设计模式之命令模式(Command模式)介绍_java

Command模式是最让我疑惑的一个模式,我在阅读了很多代码后,才感觉隐约掌握其大概原理,我认为理解设计模式最主要是掌握起原理构造,这样才对自己实际编程有指导作用.Command模式实际上不是个很具体,规定很多的模式,正是这个灵活性,让人有些confuse. Command定义 不少Command模式的代码都是针对图形界面的,它实际就是菜单命令,我们在一个下拉菜单选择一个命令时,然后会执行一些动作. 将这些命令封装成在一个类中,然后用户(调用者)再对这个类进行操作,这就是Command模式,换句

浅谈Java设计模式关于原型模式(Prototype)思索建议

java教程:关于Java设计模式关于原型模式(Prototype) IT信息技术http://www.52ij.com/jishu/ 首先需要弄清楚什么叫原型模式,或者说为什么要有原型模式,运用它会给我们带来什么或能解决什么问题?原型模式(Prototype)同抽象工厂模式同属于创建型模式,它主要关注于大量相同或相似对象的创建问题,应用原型模式就是先需要一个原对象,然后通过对原对象进行复制(克隆),来产生一个与原对象相同或相似的新对象.注意这里所说的对象相同不是指复制出来的副本对象与原对象是同

乐在其中设计模式(C#) - 命令模式(Command Pattern)

原文:乐在其中设计模式(C#) - 命令模式(Command Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd 介绍 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作. 示例 有一个Message实体类,某个类对它的操作有Insert()和Delete()方法.现在要求可以对之前的所有操作做撤销和重复. MessageModel using Sys

【设计模式】—— 命令模式Commond

模式意图 将一个请求封装成一个对象,从而对这个命令执行撤销.重做等操作. 典型的Eclipse开发中,编辑器的操作就需要用到这个模式,比如Undo.Redo等等. 另外这个模式使得一个命令的触发与接收解耦,这样我们就可以演变成把感兴趣的对象接收这个命令,当命令触发时,这些对象就会执行操作.这个机制也是java事件的处理方式. 应用场景 1 命令抽象成对象 2 在不同的时刻,指定或者排队命令 3 支持 Undo或者Redo等操作 4 修改日志,当系统崩溃时,利用修改日志执行撤销 5 原语操作上构造

java设计模式---prototype(原型)模式

设计 java设计模式---prototype(原型)模式 定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.      Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,      工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求      原型对象拷贝它们自己来实施创建.      适用性:当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者  为了避免创建一个与产品类层次平行的工厂类层

php设计模式之命令模式使用示例

 这篇文章主要介绍了php设计模式之命令模式使用示例,命令模式将一个请求封装为一个对象,从而你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销操作 命令类: 1.命令角色:声明了一个给所有具体命令类的抽象接口.这是一个抽象角色. 2.具体命令角色:定义一个接受者和行为之间的弱耦合:实现execute方法,负责调用接受的相应操作.execute()方法通常叫做执行方法 3.客户角色:创建一个具体命令对象并确定其接受者. 4.请求者角色:负责调用命令对象执行请求,相关的方法叫

深入理解JavaScript系列(34):设计模式之命令模式详解

 这篇文章主要介绍了深入理解JavaScript系列(34):设计模式之命令模式详解,命令模式(Command)的定义是:用于将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及执行可撤销的操作,需要的朋友可以参考下     介绍 命令模式(Command)的定义是:用于将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或者记录请求日志,以及执行可撤销的操作.也就是说改模式旨在将函数的调用.请求和操作封装成一个单一的对象,然

设计模式 ( 十三 ) 命令模式Command(对象行为型)

设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述         在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活.  例子1:电视机遥控器 : 遥控器是请求的发送者,电视机是请求的接收者,遥控器上有一些按钮如开,关,换频道等按钮就是具体命令,不同的按钮对应电视机的不

详解Java设计模式之备忘录模式的使用_java

定义与结构     备忘录(Memento)模式又称标记(Token)模式.GOF给备忘录模式的定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 在讲命令模式的时候,我们曾经提到利用中间的命令角色可以实现undo.redo的功能.从定义可以看出备忘录模式是专门来存放对象历史状态的,这对于很好的实现undo.redo功能有很大的帮助.所以在命令模式中undo.redo功能可以配合备忘录模式来实现. 其实单就实现保存一个对