软件设计模式之行为模式.ppt_第1页
软件设计模式之行为模式.ppt_第2页
软件设计模式之行为模式.ppt_第3页
软件设计模式之行为模式.ppt_第4页
软件设计模式之行为模式.ppt_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章,行为模式,课程目标,Observer模式 Iterator模式 Strategy模式 Template模式 Visitor模式 Chain of Responsibility模式 Command模式 其他模式,如Interpreter模式、Mediator模式等,体验项目,本章体验项目的主要功能是使用Command模式实现窗体中鼠标画图功能,该程序主要由以下几个部分组成:,程序运行完成后,拖动鼠标在窗体上画出“Hello”字符,(1)命令接口Command,定义命令方法。,(2)具体命令角色MacroCommand和DrawCommand类,这两个类都实现Command接口,DrawCommand实现画图命令,MacroCommand类定义对命令的新增、执行和删除等方法。,(3)请求接口Drawable,DrawCanvas类实现Drawable接口,定义与具体请求相关的操作。,(4)客户端,继承JFrame并实现ActionListener和MouseMotionListener接口,创建窗体界面和各种事件,行为模式概述,行为模式涉及到算法和对象间职责的分配,行为模式描述了对象和类的模式,以及它们之间的通信模式,这些模式刻划了在程序运行时难以跟踪的复杂的控制流。,可分为行为类模式和行为对象模式两种:,(1)行为类模式使用继承机制在类间分派行为。,(2)行为对象模式使用对象复合而不是继承。一些行为对象模式描述了一组对等的对象怎样相互协作以完成其中任何一个对象都无法单独完成的任务。这里一个重要的问题是对等对象如何互相了解对方。对等对象可以保持显式的对对方的引用,但那会增加它们的耦合度。在极端情况下,每一个对象都要了解所有其他的对象。,Chain of Responsibility模式,Chain of Responsibility模式即职责链模式,在有不止一个对象可以处理或实现客户请求的时候,责任链模式(CoR)会顺序地给每一个对象一次处理请求的机会。一个较好的例子就是Java的异常处理机制,当程序中发生异常时,将会比较与catch所捕捉的异常是否相符合,如果符合就执行所设定的处理,如果都没有对比到适当的异处理,就会将异常丢出try catch程序块之外。,模式介绍,主要适用于以下情况:,有多个对象可以处理一个请求,但哪个对象来处理该请求是在运行时刻自动确定的。,想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。,希望动态的指定处理某个请求的对象集合。,Chain of Responsibility模式结构图,职责链模式结构图如下:,Handler:定义一个处理请求的接口。,ConcreteHandler:处理它所负责的请求,并可访问在该链中它的后继者。如果可处理该请求,就处理;否则将该请求转发给它的后继者。,Client:向链上的具体处理者即ConcreteHandler对象提交请求。,Chain of Responsibility模式示例,public interface Handler public void handleRequest(char c); public class CharacterHandler implements Handler private Handler successor; public CharacterHandler(Handler successor) this.successor = successor; public void handleRequest(char c) if(Character.isLetter(c) System.out.println(“CharacterHandler类处理请求,返回结果:你输入的是字元“); else successor.handleRequest(c); public class NumberHandler implements Handler private Handler successor; public NumberHandler(Handler successor) this.successor = successor; public void handleRequest(char c) if(Character.isDigit(c) System.out.println(“NumberHandler类处理请求,返回结果:你输入的是数字“); else successor.handleRequest(c); public class SymbolHandler implements Handler public void handleRequest(char c) if (Character.isDefined(c) System.out.println(“SymbolHandler类处理请求,返回结果:你输入的是符号“); else System.out.println(“请求未被处理“); ,处理字元,处理数字,处理符号,职责链模式优势和不足,职责链模式主要有以下几个优点:,降低耦合度,职责链模式不足:,效率低 ,一个请求的完成可能要遍历到最后才可能完成。,扩展性差,在该模式中,一定要有一个统一的Handler接口。,增强了给对象指派职责的灵活性,Command模式,Command模式即命令模式,该模式把一个请求或者操作封装到一个对象中,并将发出命令的责任和执行命令的责任分割开,委派给不同的对象。允许请求的一方和发送的一方独立开来 。,模式介绍,主要适用于以下情况:,抽象出待执行的动作以参数化某对象,你可用过程语言中的回调(callback)函数表达这种参数化机制。,在不同的时刻指定、排列和执行请求。一个Command对象可以有一个与初始请求无关的生存期。,支持取消操作。,支持修改日志。,用构件在原语操作上的高层操作构造一个系统。,Command模式结构图,命令模式结构图如下:,Command:声明执行操作的接口。,ConcreteCommand:将一个接收者对象绑定于一个动作,调用接收者相应的操作,以实现execute()方法。,Receiver:知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者。,Invoker:如果该命令可执行,则要求该命令执行这个请求,并存储ConcreteCommand对象。,Client:创建一个具体命令对象并设定它的接收者。,Command模式示例,Command模式在界面设计中得到了广泛的应用,比如以下的示例:在窗体中添加四个按钮和一个文本框,其中三个按钮用于改变文本框的颜色,第四个按钮用于关闭窗体。具体实现如下:,interface CommandInterface public void processEvent( ); import javax.swing.JButton; class Blue extends JButton implements CommandInterface public void processEvent( ) Client.tf1.setBackground(Color.BLUE); public Blue(String name) super(name); class buttonHandler implements ActionListener public void actionPerformed(ActionEvent e) CommandInterface CommandObj = (CommandInterface)e.getSource( ); CommandOcessEvent( ); ,自定义四个按钮类,分别继承JButton并实现CommandInterface接口。,Blue类改变文本框的颜色为“BLUE”, Cyan类改变文本框的颜色为“cyan”, Red类改变文本框的颜色为“red”, ExitButton类实现关闭窗体的操作。都很类似所以只给出了Blue类的参考代码。,Command模式优势和不足,不足: 使用Command模式会导致系统有过多具体的 Command类。某些系统可能需要几十个,几百个甚至几千个具体Command类,这会使Command模式在这样的系统里变得不实际。,Command模式将“进行操作请求”的对象和“知道如何执行操作”的对象分离开来。,多个command可以被组装成一个复合command。,很容易增加新的command,因为不需要修改现有的类。,Command模式具有以下优点:,Command对象可以像任何其它对象一样被使用和继承。,Iterator模式,Iterator模式即迭代器模式,用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构,模式介绍,主要适用于以下情况:,访问一个聚合对象的内容而无需暴露它的内部表示,多个对象聚在一起形成的总体称之为聚合,聚合对象是能够包容一组对象的容器对象。,支持对聚合对象的多种遍历。,为遍历不同的聚合结构提供一个统一的接口(即支持多态迭代)。,Iterator模式结构图,迭代器模式结构图如下:,Iterator:定义访问和遍历元素的接口。,ConcreteIterator:实现了Iterator接口的具体迭代器,用于对聚合对象遍历时跟踪当前的位置。,Aggregate:定义创建相应迭代器的接口。,ConcreteAggregate:实现了Aggregate接口的聚合对象,实现了返回一个ConcreteIterator实例的方法。,Iterator模式示例,public interface MyIterator public boolean hasNext(); public Object next(); import java.util.List; public class ListIterator implements MyIterator private List list = null; private int index; public ListIterator(List l) index=-1; this.list=l; public boolean hasNext() return indexlist.size()-1; public Object next() +index; return list.get(index); import java.util.List; public interface MyList extends List public MyIterator getIterator( ); public MyIterator getReverseIterator( ); import java.util.Vector; public class MyVector extends Vector implements MyList public MyIterator getIterator() return new ListIterator(this); public MyIterator getReverseIterator() return new ReverseListIterator(this); ,Iterator模式优势和不足,使用迭代抽象:使得访问一个聚合对象的内容而无需暴露它的内部表示。,提供迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。,主要缺点在与迭代器的健壮性问题:遍历的同时更改迭代器所在的集合结构,会导致问题出现。,Iterator模式优点和不足:,Observer模式,Observer模式实现了表示层和数据逻辑层的分离,使其允许独立的改变目标和观察者。你可以单独复用目标对象而无需同时复用其观察者,反之亦然。它也使你可以在不改动目标和其他观察者的前提下增加观察者。,模式介绍,主要适用于以下情况:,当一个抽象模型存在两个方面,其中一个方面依赖于另一方面,将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。,当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变时。,当一个对象必须通知其它对象,而它又不能假定其它对象是谁。也就是说你不希望这些对象是紧密耦合的。,Observer模式结构图,观察者模式结构图如下:,Subject(目标):提供注册、删除和通知观察者对象的抽象类(或接口)。,Observer(观察者):为那些在目标发生改变时需要获得通知的具体观察者对象定义一个更新的接口。,ConcreteSubject(具体目标):当它的状态发生变化时,向它的各个观察者发出通知。,ConcreteObserver(具体观察者):实现Observer接口,维护一个ConcreteSubject对象,存储有关状态,随时更新这些状态使得这些状态与目标的状态一致。,Observer模式示例,使用Observer模式,根据取得的随机数来打印不同个数的“*”和“”,具体实现如下 :,interface Observer public abstract void update(NumberObject object); class DigitObserver implements Observer public void update(NumberObject object) System.out.print(“DigitObserver:“); int count = object.getNumber(); for (int i = 0; i count; i+) System.out.print(“); System.out.println( ); try Thread.sleep(100); catch (InterruptedException e) System.out.println(e); ,DigitObserver类根据目标对象的随机数,来打印该随机数个数的“”。 GraphObserver类根据目标对象的随机数,来打印该随机数个数的“*”。 DigitObserver类和GraphObserver类的实现过程类似,,import java.util.*; abstract class NumberObject /储存Observer private Vector observers = new Vector( ); /新增Observer public void addObserver(Observer observer) observers.add(observer); /删除Observer public void deleteObserver(Observer observer) observers.remove(observer); /通知Observer public void notifyObservers( ) Iterator it = observers.iterator( ); while (it.hasNext() Observer o = (Observer) it.next( ); o.update(this); /取得数值 public abstract int getNumber( ); /产生数值 public abstract void execute( ); class RandomNumberObject extends NumberObject private Random random = new Random( ); / 随机数生成器 private int number; public int getNumber( ) / 取得数值 return number; public void execute() for (int i = 0; i 10; i+) number = random.nextInt(30); notifyObservers(); /通知Observer ,Observer模式优势和不足,该设计模式的优点主要体现在:目标和观察者间的抽象耦合。,因为一个观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。在目标上一个看似无误的操作可能会引起一系列对观察者以及依赖于这些观察者的那些对象的更新。另外,如果依赖准则的定义或维护不当,也常常会引起错误的更新,而这种错误通常很难捕捉。,该设计模式的缺点主要体现在:意外的更新可能会导致错误。,一个目标所知道的仅仅是它有一系列观察者,并不知道任何一个观察者属于哪一个具体的类。这样目标和观察者之间的耦合是抽象的和最小的。因为目标和观察者不是紧密耦合的,它们可以属于一个系统中的不同抽象层次。一个处于较低层次的目标对象可与一个处于较高层次的观察者通信并通知它,这样就保持了系统层次的完整性。,Strategy模式,Strategy模式使得算法与算法的使用者相分离,同时减少了二者间的耦合度,使得算法可独立于使用它的客户而变化;同时,由于设计粒度的减小,程序的复用性也得到了进一步提高,分离出来的算法可以更好地适应复用的需要。,模式介绍,主要适用于以下情况:,如果在一个系统中有许多类,它们之间的区别仅在于它们的行为.,一个系统需要动态地在几种算法中选择一种。,一个系统的算法使用的数据不可以让客户端知道.,如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。,Strategy模式结构图,策略模式结构图如下:,Strategy(抽象策略):这是一个抽象角色,通常由一个接口或抽象类实现。并给出所有的具体策略类所需的接口。,Context(环境):维护一个Strategy类的对象,并定义一个方法供Strategy对象来访问它的数据。,ConcreteStrategy(具体策略):包装了相关的算法或行为。,Strategy模式示例,abstract class Compositor public abstract int compute(int a ); class MaxCompositor extends Compositor public int compute(int a ) int t; for(int i=0;iai+1) t=ai;ai=ai+1;ai+1=t; return aa.length-1; class CompositorSolve Compositor compositor; public CompositorSolve(Compositor compositor) positor = compositor; public void result(int a ) System.out.println(pute(a); public void setCompositor(Compositor compositor) positor=compositor; public class Client public static void main(String args) int a =10,45,20,10; CompositorSolve cs = new CompositorSolve(new MaxCompositor(); cs.result(a); cs.setCompositor(new MinCompositor(); cs.result(a); ,MaxCompositor封装用于获取数组最大值的方法,MinCompositor封装用于获取数组最小值的方法,实现过程类似。,Strategy模式优势和不足,策略模式的优点主要体现在以下几点:,策略模式提供了管理相关的算法族的办法,策略类的等级结构定义了一个算法或行为族。避免了重复的代码。,使用策略模式可以避免使用多重条件语句。,Facade模式不足,客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。,策略模式提供了可以替换继承关系的办法,从而把算法或行为的使用者和算法或行为本身分隔开。,Template Method模式,模板方法模式基本原理是:准备一个抽象类,将部分逻辑以具体方法以及具体构造子类的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。,模式介绍,该模式主要适用于以下几种情况:,一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。,各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。,控制子类扩展。模板方法只在特定点调用“钩子操作”(提供缺省的方法,子类可以在必要时进行扩展),这样就只允许在这些点进行扩展。,Template Method模式结构图,模板方法模式结构图如下:,AbstractClass(抽象类):定义一些抽象的原语操作,具体的子类重定义它们以实现一个算法步骤。,ConcreteClass(具体类):继承AbstractClass类,并实现AbstractClass中的抽象方法以完成算法中与特定子类相关的步骤。,Template Method模式示例,public abstract class AbstractRead protected String resource; public void getContent() if(open() readContent(); close(); protected abstract boolean open( ); protected abstract void readContent( ); protected abstract void close( ); public class ReadHtml extends AbstractRead private URLConnection conn; private BufferedReader in; public ReadHtml(String url) resource = url; public boolean open( ) try URL url = new URL(resource); conn = url.openConnection( ); in = new BufferedReader(new InputStreamReader(conn.getInputStream( ); catch (Exception e) System.out.println(“文件打开失败“); return false; return true; protected void readContent( ) try if(in != null) String str; while(str = in.readLine( ) != null) System.out.println(str); catch(IOException e) System.out.println(“文件读取失败“); protected void close( ) if(in != null) try in.close(); catch(IOException e) System.out.println(“IO 出错“); ,ReadHtml类封装读URL文件的具体实现,ReadFile类封装读本地文件的具体实现。实现过程类似。,Template Method模式优势和不足,Template Method模式获得一种反向控制结构的效果,这也是面向对象系统的分析和设计中一个原则依赖倒置(Dependency Inversion Principles)。其含义就是父类调用子类的操作(高层模块调用低层模块的操作),低层模块实现高层模块声明的接口。这样控制权在父类(高层模块),低层模块反而要依赖高层模块。,继承的强制性约束关系也让Template Method模式有不足的地方,我们可以看到对于各个ConcreteClass类中实现的方法,是不能被别的类复用的。,Visitor模式,Visitor模式即访问者模式,该模式的定义:作用于某个对象群中各个对象的操作,它可以使你在不改变这些对象本身的情况下,定义作用于这些对象上的新操作。,模式介绍,该模式主要适用于以下几种情况:,当该对象结构被很多应用共享时。,一个对象结构包含很多类对象,它们有不同的接口,而想对这些对象实施一些依赖于其具体类的操作。,需要对一个对象结构中的对象进行很多不同的并且不相关的操作,定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。,Visitor模式结构图,访问者模式结构图如下:,java动态代理类,Visitor(访问者):为对象结构中ConcreteElement的每一个类声明一个访问操作。使得访问者可以确定正被访问元素的具体类。这样访问者就可以通过该元素的特定接口直接访问该类。,ConcreteVisitor(具体访问者):实现Visitor接口,每个操作实现本算法的一部分,而该算法片断仍是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储它的局部状态。,Element(元素):定义一个accept()方法,并以一个访问者为参数。,ConcreteElement(具体元素):实现Element接口,并实现其accept()方法,在该方法中通过一个访问者参数来通知该访问者它是否可被访问。并将自己传递给访问者。,ObjectStructure(对象结构):提供一个高层的接口以允许该访问者访问它的元素,可以是一个复合对象或是一个集合。,Visitor模式示例,interface Visitable public void accept(Visitor visitor); class StringElement implements Visitable private String value; public StringElement(String string) value = string; public String getValue( ) return value; public void accept(Visitor visitor) visitor.visitString(this); interface Visitor public void visitString(StringElement stringE); public void visitFloat(FloatElement floatE); public void visitCollection(Collection collection); import java.util.*; class ConcreteVisitor implements Visitor /实现对Collection的元素的成功访问 public void visitCollection(Collection collection) Iterator iterator = collection.iterator( ); while (iterator.hasNext() Object o = iterator.next( ); if (o instanceof Visitable) (Visitable) o).accept(this); else System.out.println(o.toString( ); public void visitString(StringElement stringE) System.out.println(“ + stringE.getValue( ) + “); public void visitFloat(FloatElement floatE) System.out.println(floatE.getValue().toString() + “f“); ,Visitor模式优势和不足,该设计模式的优点主要有以下几种:,将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。,访问者模式可以跨过几个类的等级结构访问属于不同的等级结构中的成员类。,使得增加新的操作变的很容易,就是增加一个新的访问者类。,该设计模式的不足主要有以下几种:,visitor不能访问被访问者的私有变量。,增加一个新的ConcreteElement类很困难。,类结构必须预知自己将会在visitor模式中使用,必须依赖于visitor接口。,其他模式-Interpreter模式,Interpreter模式即解释器模式。描述怎样在有了一个简单的文法后,使用模式设计解释这些语句。在解释器模式中提到的语言是指任何解释器对象都能够解释的任何组合。在解释器模式中需要定义一个代表文法的命令类的等级结构,也就是一系列的组合规则。,public interface AbstractExpression void interpret( Context context ); public class TerminalExpression implements AbstractExpression private String stat; public TerminalExpression(String stat) stat = stat; public void interpret(Context c) /具体要实现的操作 public class NonterminalExpression implements AbstractExpression private AbstractExpression successor; public void setSuccessor(AbstractExpression successor) this.successor = successor; public AbstractExpression getSuccessor() return successor; public void interpret(Context context) /具体要实现的操作 ,Mediator模式,Mediator模式即调停者模式或中介者模式,该模式的思想是用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。,ConcreteMediator(具体中介者):具体中介者了解和维护它的各个同事,并协调各同事对象实现协作行为。,Colleague(同事类):每一个同事类都知道它的中介者对象。在需要与其他的同事通信的时候,与它的中介者通信。,Mediator(中介者):定义一个接口用于与各Colleague对象通信。,Memento模式,Memento模式即备忘录模式,该模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储时

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论