您的位置:首页 > 编程语言 > Java开发

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

2012-12-11 16:20 218 查看

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("客户要求需求变更计划...");

}



}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: