软件设计模式sdp-第4章.pptx

上传人(卖家):三亚风情 文档编号:3219406 上传时间:2022-08-07 格式:PPTX 页数:69 大小:898.23KB
下载 相关 举报
软件设计模式sdp-第4章.pptx_第1页
第1页 / 共69页
软件设计模式sdp-第4章.pptx_第2页
第2页 / 共69页
软件设计模式sdp-第4章.pptx_第3页
第3页 / 共69页
软件设计模式sdp-第4章.pptx_第4页
第4页 / 共69页
软件设计模式sdp-第4章.pptx_第5页
第5页 / 共69页
点击查看更多>>
资源描述

1、软件设计模式第4章 GoF创建型模式结构型(Creational)模式 GoF创建型模式的意图是解决对象创建的一类设计问题 比如,需要保证某个类型的对象在运行时只有一个实例,并共享给所有使用该对象的客户端 将一类对象的创建行为复用 保证产品簇不同类型产品对象的创建一致性等提纲 单例模式 原型模式 模式 构造器模式 抽象工厂模式 工厂方法模式单例(Singleton)模式 单例(单例(Singleton)是指目标类()是指目标类(Class)只)只有一个实例对象(有一个实例对象(Object),并且向使用该),并且向使用该对象的客户端提供访问单例的全局方对象的客户端提供访问单例的全局方法法 使用

2、单例模式的场景有 当一个类只能有一个实例,并且客户端需要访问该实例 当一个类的实例化代价很大,且向所有客户端提供无状态的服务(实例状态在程序中通常使用变量或域表达)或不因客户端变化而改变实例状态的服务单例类结构单例类结构使用单例的练习 COS系统的配置信息使用XML格式文件保存,COS启动后,需要向所有客户端(Client)程序共享该配置信息,并提供配置信息访问的接口 需要单独设计一个配置信息类,负责封装配置信息,并向客户端提供服务 配置信息类初始化时,需要将配置信息从XML数据源文件中读取并解析,这属于耗时操作;多次初始化会降低程序性能Configuration单例类图 public cla

3、ss Configuration/cosConfig是静态域,在Configuration类首次加载时初始化private static Configuration cosConfig=createInstance();private Configuration()/私有构造方法/*创建和初始化Configuration对象*/private static Configuration createInstance()Configuration c=new Configuration();/解析XML数据源,初始化creturn c;/*向客户端提供访问c的公共方法*/public static

4、 Configuration getInstance()return cosConfig;/*向客户端提供配置信息访问的接口 */public Result service(Parameter p)/服务实现 /return语句 使用单例时,需要注意以下问题 编程语言中反射和序列化编程语言中反射和序列化/反序列化可能会反序列化可能会破坏单例特破坏单例特性性 多客户端并发访问单多客户端并发访问单例时例时,也可能会破坏,也可能会破坏单例特单例特性性 在软件系统中使用过多的单例对象,会导在软件系统中使用过多的单例对象,会导致使程序性能下致使程序性能下降降 设计单例类时,并不一定要完全遵守设计单例类时

5、,并不一定要完全遵守GoF理理论形式论形式使用单例模式的行业案例1 JDK的Runtime单例类 JDK中的java.lang.Runtime即是一个标准的单例类 java.lang.Runtime定义了许多实例方法,通过对象调用向客户端提供接口 每一个Java应用都有唯一一个Runtime实例,用来与应用的运行时环境交互 public class Runtime /静态私有域 private static Runtime currentRuntime=new Runtime();/*全局静态访问方法 */public static Runtime getRuntime()return cur

6、rentRuntime;/*私有无参构造方法 */private Runtime()/其他代码 使用单例模式的行业案例2 Hibernate框架SessionFactory对象的单例构造 程序员一般在使用Java ORM框架Hibernate时,会将org.hibernate.SessionFactory的实例在自己的应用中构造为单例 org.hibernate.SessionFactory的单例向所有客户端程序共享持久化存储的配置信息和其他 public class HibernateUtil /静态私有域private static final SessionFactory session

7、Factory=buildSessionFactory();/*实例构造方法 */private static SessionFactory buildSessionFactory()try /通过xml配置构建SessionFactory实例 return new Configuration().configure().buildSessionFactory(new StandardServiceRegistryBuilder().build();catch(Throwable ex)/异常处理 /*全局静态访问方法 */public static SessionFactory getSes

8、sionFactory()return sessionFactory;原型(Prototype)模式 原型(原型(Prototype)是指通过复制自己达到构)是指通过复制自己达到构造目标对象新实例的对造目标对象新实例的对象象 使用原型设计模式的场景有 当一个类的实例状态只能是不同组合中的一种时,而不想通过平行类或子类的方式区分不同的状态组合 当业务代码中不能静态引用目标类的构造器来创建新的目标类的实例 当目标类实例化代价昂贵,不同的客户端需要单独使用一个目标类的对象时原型模式类结构使用原型的练习 COS的通知子系统负责发送多种类型的通知,如,订单通知、系统通知、会员通知等。不同种类通知,会有不

9、同的标题、内容和尾注。同一种类的通知,又有不同的子类型通知,子类型通知标题、内容等不同,尾注、背景等相同;如,订单通知分成不同订单状态(订单已生成,订单已支付等)的子类型通知,系统通知分成不同消息级别(紧急,普通等)的子类型通知。如果为每个的通知类型或子类型单独设计一个类或子类,设计类的数量将会急剧增加原型Notification的类结构public class Notification implements Cloneable private String title;/通知标题private String content;/通知内容private NotificationFooter fo

10、oter;/通知尾注 /*setters,getters方法省略 */Notification(NotificationFooter foo)footer=foo;/*克隆Notification对象(浅拷贝-shallow copy,共享footer)*/Overridepublic Notification clone()try return(Notification)super.clone();catch(CloneNotSupportedException e)/异常处理e.printStackTrace();return null;public class NotificationP

11、rotoManager private static HashMap manager=n e w H a s h M a p();/原型管理器static/初始化订单通知的尾注对象N o t i f i c a t i o n F o o t e r o r d e r F o o t e r =n e w NotificationFooter();/订单通知原型构造manager.put(order,new Notification(orderFooter);/其他原型构造 /*根据通知类型获取原型对象 */public static Notification getNotification

12、Proto(String type)return manager.get(type);public class NotificationSender/存储通知的发送队列 private Queue sendQueue=new LinkedBlockingQueue();/*通过通知原型对象复制,完成新通知对象创建*/public void sendNotification(String title,String content ,Employee receiver,String type)Notification notification=NotificationProtoManager.ge

13、tNotificationProto.clone();/生成新通知对象notification.setContent(content);/设置通知内容notification.setTitle(title);/设置通知标题 notification.setReceiver(receiver);/设置通知接收者 send(notification);/发送通知/*发送通知*/private void send(Notification noti)sendQueue.add(noti);/其他操作使用原型模式时需要注意的问题 对象拷贝在不同的编程语言中有深度拷贝对象拷贝在不同的编程语言中有深度拷贝

14、(Deep Copy,也翻译成深度复制、深拷贝,也翻译成深度复制、深拷贝等)和浅拷贝(等)和浅拷贝(Shallow Copy,也翻译成影,也翻译成影子拷贝、影子复制、浅度复制、浅复制等)子拷贝、影子复制、浅度复制、浅复制等)的区的区别别 如果原型类之间有循环引用的作用域,则如果原型类之间有循环引用的作用域,则无法实现深度拷贝无法实现深度拷贝使用原型模式的行业案例1 JDK的Vector原型类 JDK中使用了大量的原型类 java.util.Vector是一个动态数组 java.util.Vector实现java.lang.Cloneable接口,并重写clone()方法java.util.Ve

15、ctor的类图 public class Vector extends AbstractListimplements List,RandomAccess,Cloneable,java.io.Serializable/*对象拷贝方法 */public synchronized Object clone()try SuppressWarnings(unchecked)Vector v=(Vector)super.clone();/使用Object的clone()方法 /*手动实现元素拷贝 *如果Vector对象元素不是引用类型数据,则为深度拷贝 *否则,为浅拷贝 */v.elementData=A

16、rrays.copyOf(elementData,elementCount);v.modCount=0;return v;catch(CloneNotSupportedException e)/异常处理 /省略的代码 使用原型模式的行业案例1 JDK的HttpCookie原型类 .HttpCookie是一个使用Object的clone()方法实现浅拷贝的原型类 .HttpCookie负责构造HTTP协议的Cookie,常被用于创建有状态的会话(Session)public final class HttpCookie implements Cloneable /*实现浅拷贝 */Overrid

17、e public Object clone()try return super.clone();/使用Object的clone()方法 catch(CloneNotSupportedException e)throw new RuntimeException(e.getMessage();/其他代码 构造器(Builder)模式 构造器(Builder)是指为构造一个复杂的产品对象,进行产品组成元素构建和产品组装的对象 使用构造器的场景有 需要将复杂产品对象的构造过程(或算法)封装在独立的代码中 对不同的产品表示复用同一个构造过程(或算法)构造器模式类结构构造器模式对象协作时序使用构造器的练习

18、 COS菜单数据存储在MySQL数据库表中,服务器程序通过网络向不同的客户端提供菜单数据;浏览器客户端需要的菜单数据文本格式为XML,Android和iOS客户端需要的菜单数据文本格式为JSON 由于COS菜单数据表结构不变,结构化的菜单数据转换为XML或JSON文本的过程或算法相同 XML与JSON是不同的文本对象表示使用构造器构造文本对象的类结构 public interface TextBuilder/*将菜单项类型转换为文本*/public void convertmType(int mType);/*将菜单项名称转换为文本*/public void convertmName(Stri

19、ng mName);/*将菜单项价格转换为文本 */public void convertmPrice(float mPrice);public class JSONBuilder implements TextBuilder private JSONText json;/json文本对象private String jsonElement;/json元素public JSONBuilder()json=new JSONText();/*获取构造好的JSON文本对象*/public JSONText getJsonText()return json;Overridepublic void co

20、nvertmType(int mType)jsonElement=nMType:+mType+;jsonElement+=,;Overridepublic void convertmName(String mName)jsonElement+=MName:+mName+;jsonElement+=,;/省略的代码 public class BuilderDirector private TextBuilder builder;/构造器/*调用构造器,构造目标文本对象的组合元素*/public void construct(List data)/构造算法 for(MenuItem mi:data

21、)builder.convertmType(mi.getmType();builder.convertmName(mi.getmName();builder.convertmPrice(mi.getmPrice();/省略的代码使用构造器模式需要注意的问题 如果产品构造过程(或算法)不需要复用或独立封装,可以去除Director类,减少设计类的数量;Director类的职责由使用Builder的客户端实现 不同的产品表示需要由不同的不同的产品表示需要由不同的Builder实现实现进行构造和装配进行构造和装配使用构造器模式的案例1 JDK的AbstractStringBuilder构造器类 JD

22、K中的java.lang.StringBuffer和java.lang.StringBuilder都是继承抽象类java.lang.AbstractStringBuilder的子类,负责构造可变的字符串 JDK并没有单独实现构造器模式中的Director类,字符串的构造过程(或算法)由使用java.lang.StringBuffer或java.lang.StringBuilder的客户端代码实现Java文本构造器的类结构 public final class StringBuffer extends AbstractStringBuilderimplements java.io.Seriali

23、zable,CharSequence /*向字符序列聚合体中添加boolean类型元素*/Override public synchronized StringBuffer append(boolean b)toStringCache=null;super.append(b);return this;/*装配和生成完整的String对象*/Override public synchronized String toString()if(toStringCache=null)toStringCache=Arrays.copyOfRange(value,0,count);return new St

24、ring(toStringCache,true);/省略的代码使用构造器模式的行业案例2 Android SDK的AlertDialog.Builder构造器类 Android SDK中的android.support.v7.app.AlertDialog.Builder就是用于复杂产品表示android.support.v7.app.AlertDialog对象的构造器 android.support.v7.app.AlertDialog是个聚合体,由title、message、button等元素组成Android对话框与构造器的类关系/*外部类AlertDialog*/public clas

25、s AlertDialog extends AppCompatDialog implements DialogInterface final AlertController mAlert;/对话框控制器/*静态嵌入类Builder*/public static class Builder private final AlertController.AlertParams P;/对话框参数 private final int mTheme;/对话框主题 /*设置对话框标题 */public Builder setTitle(StringRes int titleId)P.mTitle=P.mCo

26、ntext.getText(titleId);return this;/*装配并生成完整的AlertDialog对象 */public AlertDialog create()final AlertDialog dialog=new AlertDialog(P.mContext,mTheme);P.apply(dialog.mAlert);/代码省略 return dialog;抽象工厂(Abstract Factory)模式 抽象工厂(抽象工厂(Abstract Factory)指在不指定具体)指在不指定具体产品类的情况下,为相互关联的产品簇或产品产品类的情况下,为相互关联的产品簇或产品集(

27、集(Families of Products)提供创建接口,并)提供创建接口,并向客户端隐藏具体产品创建的细节或表示的对向客户端隐藏具体产品创建的细节或表示的对象象 抽象工厂使用场景有 需要实现产品簇样式的可扩展性,并向客户端隐藏具体样式产品簇的创建细节或表示 向客户端保证产品簇对象的一致性,但只提供产品对象创建接口 使用产品簇实现软件的可配置性抽象工厂模式类结构抽象工厂模式对象协作时序使用抽象工厂的练习 COS系统需要实现订单数据统计展示功能,数据展示的图表类型有饼状图、柱状图和线状图。图表风格在COS 1.0版本中需实现水晶和扁平样式,但COS 2.0或后续迭代版本中,还需实现3-D样式

28、饼状图、柱状图和线状图共同构成图表产品簇 COS进行数据展示时,需要保持图表展示体验的一致使用抽象工厂创建图表对象的类结构 public class ChartDrawer private ChartFac chartFac;/工厂对象public ChartDrawer(ChartFac fac)chartFac=fac;/*绘制饼状图元素*/public void drawPie(Data data)Pie pie=chartFac.createPie(data);pie.draw();/*绘制线状图元素*/public void drawLine(Data data)Line line=

29、chartFac.createLine(data);line.draw();/其他代码省略 public abstract class ChartFac/*创建线状图*/public abstract Line createLine(Data data);/*创建饼状图*/public abstract Pie createPie(Data data);/*创建柱状图*/public abstract Bar createBar(Data data);public class CrystalChartFac extends ChartFac/*创建水晶样式的线状图对象 */Overridepu

30、blic Line createLine(Data data)CrystalLine line=new CrystalLine();line.setData(data);return line;/*创建水晶样式的饼状图对象 */Overridepublic Pie createPie(Data data)CrystalPie pie=new CrystalPie();pie.setData(data);return pie;/*创建水晶样式的柱状图对象 */Overridepublic Bar createBar(Data data)CrystalBar bar=new CrystalBar(

31、);bar.setData(data);return bar;使用抽象工厂模式需要注意的问题 产品簇中抽象产品类型的增加或减少会导产品簇中抽象产品类型的增加或减少会导致已有代码的大量修致已有代码的大量修改改 产品簇样式的增加,会导致设计产品簇样式的增加,会导致设计类类的数量的数量急急剧增剧增加加 由于工厂对象提供无状态服务,可以设计由于工厂对象提供无状态服务,可以设计成单例成单例使用抽象工厂模式的行业案例 JDK实现AWT(Abstract Window Toolkit,抽象窗口工具集)时,使用了抽象工厂模式 抽象工厂类有:java.awt.Toolkit、sun.awt.SunToolkit

32、、sun.awt.UNIXToolkit 产品簇中的抽象产品类型有:java.awt.peer.ButtonPeer、java.awt.peer.CanvasPeer、java.awt.peer.DialogPeerAWT使用工厂模式的类结构 public abstract class Toolkit/创建ButtonPeer对象protected abstract ButtonPeer createButton(Button target)throws HeadlessException;/创建DialogPeer对象protected abstract DialogPeer createD

33、ialog(Dialog target)throws HeadlessException;/省略其他代码public final class XToolkit extends UNIXToolkit implements Runnable/*创建XButtonPeer对象*/public ButtonPeer createButton(Button target)ButtonPeer peer=new XButtonPeer(target);targetCreatedPeer(target,peer);return peer;/*创建XLabelPeer对象*/public LabelPeer

34、 createLabel(Label target)LabelPeer peer=new XLabelPeer(target);targetCreatedPeer(target,peer);return peer;/省略其他代码工厂方法(Factory Method)模式 工厂方法(工厂方法(Factory Method)类定义了产品)类定义了产品对象创建接口,但由子类实现具体产品对对象创建接口,但由子类实现具体产品对象的创象的创建建 工厂方法模式使用的场景有 当业务类处理产品对象时,无法知道产品对象的具体类型,或不需要知道产品对象的具体类型(产品具有不同的子类型)当业务类处理不同的产品子类型

35、对象业务时,希望由自己的子类实现产品子类型对象的创建工厂方法模式类结构工厂方法模式对象协作时序使用工厂方法模式的练习 COS 1.0系统向客户提供订单导出功能,订单导出时可以选择导出文件类型是Html或Pdf,将来的COS 2.0升级版本中需要添加Office Excel导出功能 导出文件过程(或算法)的业务代码可以复用 文件对象具有不同的子类型(文件格式或文件编码)将来会添加新类型文件的导出功能,设计方案必须具备可扩展性使用工厂方法导出不同类型文件对象的类结构 public abstract class DocumentCreator/*文件导出过程(或算法)*/public boolean

36、 exportDocument(String fileName)boolean result=true;/导出结果Document doc=createDocument(fileName);/调用子类实现的方法创建Document对象try FileOutputStream fos=new FileOutputStream(doc.getFileName();/创建输出流doc.writeFileContent(fos);/写文件内容至输出流fos.close();/关闭输出流 catch(FileNotFoundException e)result=false;e.printStackTra

37、ce();catch(IOException e)result=false;e.printStackTrace();return result;/*创建Document对象*/public abstract Document createDocument(String fileName);public abstract class Document protected String filename;/文档名称/*将文件内容写到目标输出流 */public abstract void writeFileContent(FileOutputStream fos);public class Pdf

38、DocumentCreator extends DocumentCreator/*实现PdfDocument对象的创建 */Overridepublic Document createDocument(String fileName)PdfDocument pdf=new PdfDocument();Data fileData=new Data();pdf.setFileName(fileName+.pdf);pdf.setPdfFileFormatData(fileData);return pdf;使用工厂方法模式需要注意的问题 当增加新的产品对象子类型时,设计类会当增加新的产品对象子类型时

39、,设计类会成倍增成倍增加加 工厂方法类操作所有类型产品对象的业务工厂方法类操作所有类型产品对象的业务行为模板一致行为模板一致使用工厂方法模式的行业案例1 JDK的AbstractCollection工厂方法类 java.util.AbstractCollection是定义了抽象工厂方法iterator()的抽象类,并在remove()等方法中使用iterator()工厂方法创建的java.util.Iterator类型的产品对象实现业务操作 java.util.ArrayList是java.util.AbstractCollection的实现子类,实现了iterator()工厂方法,创建Itr

40、类型的产品对象java.util.AbstractCollection工厂方法类的结构使用工厂方法模式的行业案例2 Apache Struts的TagModel工厂方法类 Apache Struts框架实现标签模型时,通过org.apache.struts2.views.freemarker.tags.TagModel抽象类定义了抽象工厂方法getBean()由子类org.apache.struts2.views.freemarker.tags.TextFiedModel、org.apache.struts2.views.freemarker.tags.LabelModel等实现,创建ponents.Component产品对象Apache Struts框架使用工厂方法模式实现标签模型的类结构总结 不同的创建型模式具有不同的使用场景及优缺点 在使用每个模式解决软件设计问题时,需要注意:模式是提供一个面向一类问题的、可行的解决方案,而不一定是最优的设计方案

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(软件设计模式sdp-第4章.pptx)为本站会员(三亚风情)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|