??xml version="1.0" encoding="utf-8" standalone="yes"?>
命o接口Q?br />
public interface Command {
public void execute();
}
public class LightOffCommand implements Command {
Light light;
public LightOffCommand(Light light) {
this.light = light;
}
public void execute() {
light.off();
}
}
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
}
public class Light {
public Light() {
}
public void on() {
System.out.println("Light is on");
}
public void off() {
System.out.println("Light is off");
}
}
public class SimpleRemoteControl {
Command slot;
public SimpleRemoteControl() {}
public void setCommand(Command command) {
slot = command;
}
public void buttonWasPressed() {
slot.execute();
}
}
public class RemoteControlTest {
public static void main(String[] args) {
SimpleRemoteControl remote = new SimpleRemoteControl();
Light light = new Light();
LightOnCommand lightOn = new LightOnCommand(light);
remote.setCommand(lightOn);
remote.buttonWasPressed();
}
}
1?分布登记l一执行Q?br />
在作E序Ӟl常到一些需求,先注册一些操作,q不马上执行Q等最l确定后l一执行。如一个具体的例子:用户定制自己的报表,可以订阅|柱,折线Q曲U图Q客户选择相应的报表组合,q样对应一个命令集合,在没定之前用户可以增删q些报表Q命令)Q等最l确定统一交给调用者根据命令执行,生成l合报表。实C命o分布提出Q确定后l一执行的功能?br />
2》Ş如流水线操作Q还是出书的例子
//先是一本空白的书:
Book book = new Book();
//扑և个作?br />
Author author1 Q?new Author();
Author author2 Q?new Author();
//把写1Q?章的名类分别l这两个作?br />
Command writeCommand = new Write1Command (author1Qbook);
Command writeCommand = new Write2Command (author2Qbook);
List commands Q?new List ();
Commands.add(writeCommand);
//调用?br />
Invoker invoker = new invoker();
Invoker.setCommands(commands);
//水写书
invoker.action()
实际上在acitonq一Ҏ中,invoker按照命oQ让两个作者流水写作这本书。(cM一个书的流水线加工工厂Q?br />
q样我们的书p水加工成功Q当然这本书只有两章Q?br />
q样q了我们一U系l设计的框架Q?br />
模型Q工P命o
客户端生命令,命o调用工具操作模型?br />
Book 相当于模?br />
Author 相当于和多工L中的一?br />
Command 命o
3》系l需要支持命令的撤消(undo)。提供redo()Ҏ【容易扩展?br />
我们可以和容易的加入undo和redoQ这个不隄?br />
4》在Invoker中我们可以实现跟t,和日志?br />
5》当pȝ需要ؓ某项复制增加形的功能的时候,命o模式使新的功能(表现ZU命令)很容易地被加入到服务U里?br />
命o联系了工Lx行类和系l逻辑Q?br />
?变化的命令模式:
命o模式的角色比较多Q在实际应用U我们可以根据所需要的功能和不需要的功能加以化?br />
1》去?调用?br />
产生命o集合后,我们可以直接在client中P代执行执行操?br />
2?变化 调用?成ؓ 跟踪?br />
//调用?br />
public class Invoker{
List commands; //已经执行完毕的命令集?br />
public void addCommand (Command command,int i){
commands.add(i,command);
}
public void action(Command command){
//执行操作
command. execute();
//
commands.add(command);
}
}
……………
//q可以有丰富的redo和undo操作Q?当然一些都l基于命令类提供的相应方?
}
q样q个cd记录了所有执行过的操作?br />
3》去?命o 用map替代
我们完全可以用map代替命oQ这h需定义各种命oc?br />
我们改进例子
Author author Q?new Author();
Publisher publisher Q?new Publisher ();
Map m = new HashMap;
m.put(author, write);
m.put(author, publisherBook);
在Invoker的actionҎQ?br />
得代map
q用java反射来调用方法;
4》去掉执行者:
直接在命令中QexecuteҎU)加业务逻辑。这样只适合于简单的的pȝ.
其他要说的内?br />
1?某些参Cl某个方发的方式很多Q除了当作方法的参数外还可以当作cȝ成员便俩变量传入Q?br />
q就为命令的抽象带来了极大的方便
abstract class Command
{
abstract public void execute();
}
当我们已l有了执行者(cTestQ方法executeQargs1Qargs2 ….argsnQ?br />
我们不必向Command加入executeQargs1Qargs2 ….argsnQ抽象方法,在说即加了Q在我们q代的时候也无法判断或十分不Ҏ判断哪个命o调用哪个executeҎ?br />
那么我们可以q样
class ConcreteCommand : Command
{
Test test;
args1
args2
…..
argsn
public override void Execute()
{
test. execute (args1Qargs2 ….argsn);
}
}
2?在想跟踪操作的时候,一般ؓ每一个操作对象分配一个调用者,操作对象在调用者中讄。(可以抽象Z个ȝ调用者,来协调调用每一个具体的调用者)
3?命o的抽象粒度我觉得是要注意的?br />
4?理解思想Q不要机械的照搬。消化成自己的,加以灉|的运用和创造在是根本出路?br />
所谓命令模式的Ҏ思想是?先Ş成命令,在根据命令执行?br />
参考:http://blog.csdn.net/baggio785/archive/2006/05/23/750513.aspx
]]>
1.public class CarFactory{
public static Car getCar(int type){
if(type == 1){
return new Car1();
} else {
return new Car2();
}
}
}
2. public class CarFactory{
public static Car getCar(String carClass){
String className = carClass;
Class c = Class.forName(className);
Car car = (Car)c.newInstance();
return car;
}
}
3. public class CarFactory{
public static Car getCar(String carJNDIName){
InitialContext ic = new InitialContext();
String className = ic.lookUp(carJNDIName);
Car car = (Car)Class.forName(className).newInstance();
return car;
}
}
方式1?适合于工厂所产生的对象都是属于同一个父cd的,而从方式1?来看Q方?无疑是最单的Q也是最Ҏ理解和接受的Q而方?和方?则相Ҏ说要高一炏V高U在哪里呢?我们可以看到Q方?中对对象的创建是使用Hardcode的Ş式,也即是程序员需要事先知道系l里面存在多个cd的对象及其对应的~号Q一旦增加或删除、修改了对象的类型,则必然引起if-else块的改变Q造成了维护的困难?br />
而方?则采用了动态类加蝲的方式,方式3在方?的基上用了JNDIQ更q了一步,其好处是不用出现HardCode的方式,即便你后面的应用增加、删除了对象的类型,我的E序q是保持现在的样子,跟进一步来_可以L那些讨厌的if-else语句?br />
2. 工厂Ҏ模式L了简单工厂模式中工厂Ҏ的静态属性,使得它可以被子类l承。这样在单工厂模式里集中在工厂方法上的压力可以由工厂Ҏ模式里不同的工厂子类来分担。?font style="background-color: #c7edcc">实质上它是让工厂实现了抽象的工厂接口Q它把具体怎么生一U东西,攑֜具体的工厂去实现了,所?#8221;延迟到子cM实现“?/span>
CZ一Q?br />
public interface Driver{
public Car driverCar();
}
public class BenzDriver implements Driver{
public Car driverCar(){
return new Benz();
}
}
public class BmwDriver implements Driver{
public Car driverCar() {
return new Bmw();
}
}
// 应该和具体品Ş成对应关p?/span> ...
// 有请暴发户先?/span>
public class Magnate
{
public static void main(String[] args)
{
try{
Driver driver = new BenzDriver();
Car car = driver.driverCar();
car.drive();
}
……
}
CZ二:
public interface Creator
{
public Prouct factory();
}
public SubCreator1 implent Creator
{
public Prouct factory()
{
return new ConcreteProduct1();
}
}
public SubCreator2 implent Creator
{
public Prouct factory()
{
return new ConcreteProduct2();
}
}
h意:q回cd是Product型的Q!
q样客户端调用是直接new 一个具体工厂的实例Q然后命令它ȝ产,而对于具体工厂的父类Q既工厂接口Q接口完全可以改成子cȝ承父cL实现Q只是这样不好,不符合OO的原则)Q它完全不知道什么品被生了,甚至它连那个具体工厂被实例化它都不知道!
3. 抽象工厂
public abstract class AbstractFactory{
public abstract Car getCar(String carClass);
public abstract Plane getPlane(String planeClass);
}
public class Factory1 extends AbstractFactory{
public Car getCar(String carClass){
// 参考上面的方式1?
return car1;
}
public Plane getPlane(String planeClass){
// 参考上面的方式1?
return plane1;
}
}
public class Factory2 extends AbstractFactory{
public Car getCar(String carClass){
// 参考上面的方式1?
return car2;
}
public Plane getPlane(String planeClass){
// 参考上面的方式1?
return plane2;
}
}