资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,设计模式,Command,模式,Command,模式定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。,将“动作的请求者”从“动作的执行者”对象解耦,将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。,一、,Command,模式的适用场合:,让方法运行最常见的方式是调用之,但是在很多情况下,我们不能控制和提供方法执行的上下文和时机。这种情况下,可以把方法封装在对象中。通过在对象中存储调用方法所需的信息,就可以让客户端或者服务决定何时调用这个方法。,Command,模式的意图是把请求封装在对象中。,二、,Command,模式的经典应用:,Command,模式的经典应用就是菜单命令。如何安排才能让一个类在用户单击菜单的时候调用对应的方法呢?解决的方法就是应用多态性,具体做法如下:首先将操作的名称固定,然后针对不同的类给出不同的实现。,三、,Command,模式的简单例子:,public,interface,Command ,public,abstract,void,execute();,三、,Command,模式的简单例子:,class,Fan ,public,void,startRotate,() ,System.,out,.println(Fan,is rotating);,public,void,stopRotate,() ,System.,out,.println(Fan,is not rotating);,class,Light ,public,void,turnOn,() ,System.,out,.println(Light,is on);,public,void,turnOff,() ,System.,out,.println(Light,is off);,三、,Command,模式的简单例子:,class,Switch ,private,Command,UpCommand,DownCommand,;,public,Switch(Command,Up, Command Down) ,UpCommand,= Up;,DownCommand,= Down;,void,flipUp,() ,UpCommand.execute,();,void,flipDown,() ,DownCommand.execute,();,三、,Command,模式的简单例子:,class,LightOnCommand,implements,Command ,private,Light,myLight,;,public,LightOnCommand(Light,L) ,myLight,= L;,public,void,execute() ,myLight.turnOn,();,class,LightOffCommand,implements,Command ,private,Light,myLight,;,public,LightOffCommand(Light,L) ,myLight,= L;,public,void,execute() ,myLight.turnOff,();,三、,Command,模式的简单例子:,class,FanOnCommand,implements,Command ,private,Fan,myFan,;,public,FanOnCommand(Fan,F) ,myFan,= F;,public,void,execute() ,myFan.startRotate,();,class,FanOffCommand,implements,Command ,private,Fan,myFan,;,public,FanOffCommand(Fan,F) ,myFan,= F;,public,void,execute() ,myFan.stopRotate,();,三、,Command,模式的简单例子:,public,class,TestCommand,public,static,void,main(String,args,) ,Light,testLight,=,new,Light();,LightOnCommand,loc =,new,LightOnCommand(testLight,);,LightOffCommand,lfc,=,new,LightOffCommand(testLight,);,Switch,testSwitchLight,=,new,Switch(loc,lfc,);,testSwitchLight.flipUp,();,testSwitchLight.flipDown,();,Fan,testFan,=,new,Fan();,FanOnCommand,foc,=,new,FanOnCommand(testFan,);,FanOffCommand,ffc,=,new,FanOffCommand(testFan,);,Switch,testSwitchFan,=,new,Switch(foc,ffc,);,testSwitchFan.flipUp,();,testSwitchFan.flipDown,();,三、,Command,模式的简单例子:,运行结果:,Light is on,Light is off,Fan is rotating,Fan is not rotating,四、,Command,模式的特点:,有一个顶层的接口,用于表示“执行命令”这个抽象动作,其次该方法中往往会含有用于区分请求类型的形参。,有一至多个实现类,每个实现类实现了接口中“执行命令”这个抽象方法,提供具体的实现。,有一个用来装载、保存命令执行类的容器对象,负责加载、初始化、查找、调用内部的各个命令对象。,五、,Command,调用的顺序:,初始化命令队列,装载各个命令对象,(Command,接口的实现类,),。,接收事件,/,请求,将其作为参数传递给命令队列。,命令队列在自己内部查找合适的处理者,调用接口实现方法处理请求。,六、,Command,模式和其它模式的结合:,Command,模式和,Memento,模式结合,实现“撤销”操作:这一点需要和“备忘录模式”配合,每执行一个操作之前,先保存当前的状态。,Command,模式和,Observer,模式结合,实现“监听,-,触发”流程:在,GUI,界面中,注册一个监听器,(Observer),,监听各个组件,(Observable),,当被监听组件被激活时,向监听器传递一个信息,监听器接收信息,作为参数传递给命令队列。命令队列根据参数查找,执行命令。,Observer,模式,Observer,模式,概念:,observer,模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。,JDK,里提供的,observer,设计模式的实现由,java.util.Observable,类和,java.util.Observer,接口组成。从名字上可以清楚的看出两者在,Observer,设计模式中分别扮演的角色:,Observer,是观察者角色,,Observable,是被观察目标,(subject),角色。,Observer,模式,实例:,该实例模拟了烧水的过程,涉及三个对象,,Heater(,热水器,),Display,(显示器),Alarm(,报警器,),。,模拟过程:为了便于运行,水的初始化温度为,90,,沸点为,95,,显示器依据热水器显示温度,显示器显示温度为,95,时,报警器开始报警。明显可以看出,Heater,是,subject ,Display,是它的,Obsrver,,同时,Display,亦是,suject,,因为它要被报警器观察,所以,Alarm,是,Display,的,Observer,。,Observer,模式,Observer,模式,Observer,模式,Observer,模式,Observer,模式,运行结果:,Observer,模式,事例二:,Observer,模式,事例二:,运行结果:,Observer,模式,观察者模式的应用场景:,1,、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。,2,、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。 观察者模式的优点:,1,、,Subject,和,Observer,之间是松偶合的,分别可以各自独立改变。,2,、,Subject,在发送广播通知的时候,无须指定具体的,Observer,,,Observer,可以自己决定是否要订阅,Subject,的通知。,3,、 遵守大部分,GRASP,原则和常用设计原则,高内聚、低偶合。 观察者模式的缺陷:,1,、 松偶合导致代码关系不明显,有时可能难以理解。,2,、 如果一个,Subject,被大量,Observer,订阅的话,在广播通知的时候可能会有效率问题。(毕竟只是简单的遍历),讨论与交流,
展开阅读全文