《设计模式-精品文档资料整理.pptx》由会员分享,可在线阅读,更多相关《设计模式-精品文档资料整理.pptx(135页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、设 计 模 式设计模式设计模式GOF23将设计者的思维融入大家的学习和工作中,更高层次的思考!创建型模式:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。单例模式单例模式核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。常见应用场景:Windows的TaskManager(任务管理器)就是很典型的单例模式windows的RecycleBin(回收
2、站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,每次new一个对象去读取。网站的计数器,一般也是采用单例模式实现,否则难以同步。应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。Application也是单例的典型应用(Servlet编程中会涉及到)在Sp
3、ring中,每个Bean默认就是单例的,这样做的优点是Spring容器可以管理在servlet编程中,每个Servlet也是单例在springMVC框架/struts1框架中,控制器对象也是单例单例模式单例模式单例模式的优点:由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决单例模式可以在系统设置全局的访问点,优化环共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理常见的五种单例模式实现方式:主要:饿汉式(线程安全,调用效率高。但是,不能延时加载
4、。)懒汉式(线程安全,调用效率不高。但是,可以延时加载。)其他:双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题。不建议使用)静态内部类式(线程安全,调用效率高。但是,可以延时加载)枚举单例(线程安全,调用效率高,不能延时加载)单例模式单例模式饿汉式实现(单例对象立即加载)饿汉式单例模式代码中,static变量会在类装载时初始化,此时也不会涉及多个线程对象访问该对象的问题。虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题。因此,可以省略synchronized关键字。问题:如果只是加载本类,而不是要调用getInstance(),甚至永远没有调用,则会造成资源浪费!public c
5、lass SingletonDemo02 private static /*final*/SingletonDemo02 s=new SingletonDemo02();private SingletonDemo02()/私有化构造器私有化构造器 public static/*synchronized*/SingletonDemo02 getInstance()return s;public class Client public static void main(String args)SingletonDemo02 s=SingletonDemo02.getInstance();Singl
6、etonDemo02 s2=SingletonDemo02.getInstance();System.out.println(s=s2);/结果为true单例模式单例模式懒汉式实现(单例对象延迟加载)要点:lazyload!延迟加载,懒加载!真正用的时候才加载!问题:资源利用率高了。但是,每次调用getInstance()方法都要同步,并发效率较低。public class SingletonDemo01 private static SingletonDemo01 s;private SingletonDemo01()/私有化构造器私有化构造器 public static synchroni
7、zed SingletonDemo01 getInstance()if(s=null)s=new SingletonDemo01();return s;单例模式单例模式双重检测锁实现这个模式将同步内容下方到if内部,提高了执行的效率不必每次获取对象时都进行同步,只有第一次才同步创建了以后就没必要了。问题:由于编译器优化原因和JVM底层内部模型原因,偶尔会出问题。不建议使用。public class SingletonDemo03 private static SingletonDemo03 instance=null;public static SingletonDemo03 getInsta
8、nce()if(instance=null)SingletonDemo03 sc;synchronized(SingletonDemo03.class)sc=instance;if(sc=null)synchronized(SingletonDemo03.class)if(sc=null)sc=new SingletonDemo03();instance=sc;return instance;private SingletonDemo03()单例模式单例模式静态内部类实现方式(也是一种懒加载方式)要点:外部类没有static属性,则不会像饿汉式那样立即加载对象。只有真正调用getInstanc
9、e(),才会加载静态内部类。加载类时是线程安全的。instance是staticfinal类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性.兼备了并发高效调用和延迟加载的优势!public class SingletonDemo04 private static class SingletonClassInstance private static final SingletonDemo04 instance=new SingletonDemo04();public static SingletonDemo04 getInstance()return Singl
10、etonClassInstance.instance;private SingletonDemo04()单例模式单例模式问题:反射可以破解上面几种(不包含枚举式)实现方式!(可以在构造方法中手动抛出异常控制)反序列化可以破解上面几种(不包含枚举式)实现方式!可以通过定义readResolve()防止获得不同对象。反序列化时,如果对象所在类定义了readResolve(),(实际是一种回调),定义返回哪个对象。public class SingletonDemo01 implements Serializable private static SingletonDemo01 s;private
11、SingletonDemo01()throws Exceptionif(s!=null)throw new Exception(只能创建一个对象只能创建一个对象);/通过手动抛出异常,避免通过反射创建多个单例对象!通过手动抛出异常,避免通过反射创建多个单例对象!/私有化构造器 public static synchronized SingletonDemo01 getInstance()throws Exceptionif(s=null)s=new SingletonDemo01();return s;/反序列化时,如果对象所在类定义了反序列化时,如果对象所在类定义了readResolve()
12、,(实际是一种回调),定义返回哪个对象。,(实际是一种回调),定义返回哪个对象。private Object readResolve()throws ObjectStreamException return s;单例模式单例模式使用枚举实现单例模式优点:实现简单枚举本身就是单例模式。由JVM从根本上提供保障!避免通过反射和反序列化的漏洞!缺点:无延迟加载public enum SingletonDemo05 /*定义一个枚举的元素,它就代表了定义一个枚举的元素,它就代表了Singleton的一个实例。的一个实例。*/INSTANCE;/*单例可以有自己的操作单例可以有自己的操作 */publi
13、c void singletonOperation()/功能处理功能处理 public static void main(String args)SingletonDemo05 sd=SingletonDemo05.INSTANCE;SingletonDemo05 sd2=SingletonDemo05.INSTANCE;System.out.println(sd=sd2);单例模式单例模式常见的五种单例模式在多线程环境下的效率测试大家只要关注相对值即可。在不同的环境下不同的程序测得值完全不一样CountDownLatch同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程
14、一直等待。countDown()当前线程调此方法,则计数减一(建议放在finally里执行)await(),调用此方法会一直阻塞当前线程,直到计时器的值为0饿汉式饿汉式22ms懒汉式636ms静态内部类式28ms枚举式32ms双重检查锁式65ms单例模式单例模式使用myeclipse的UML插件画出类图大家也可以使用:rationalrose、metamill等。单例模式单例模式常见的五种单例模式实现方式主要:饿汉式(线程安全,调用效率高。但是,不能延时加载。)懒汉式(线程安全,调用效率不高。但是,可以延时加载。)其他:双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题。不建议使用)静态内
15、部类式(线程安全,调用效率高。但是,可以延时加载)枚举式(线程安全,调用效率高,不能延时加载。并且可以天然的防止反射和反序列化漏洞!)如何选用?单例对象占用资源少,不需要延时加载:枚举式好于饿汉式单例对象占用资源大,需要延时加载:静态内部类式好于懒汉式工厂模式工厂模式工厂模式:实现了创建者和调用者的分离。详细分类:简单工厂模式工厂方法模式抽象工厂模式面向对象设计的基本原则:OCP(开闭原则,Open-ClosedPrinciple):一个软件的实体应当对扩展开放,对修改关闭。DIP(依赖倒转原则,DependenceInversionPrinciple):要针对接口编程,不要针对实现编程。Lo
16、D(迪米特法则,LawofDemeter):只与你直接的朋友通信,而避免和陌生人通信。工厂模式工厂模式核心本质:实例化对象,用工厂方法代替new操作。将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。工厂模式:简单工厂模式用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码)工厂方法模式用来生产同一等级结构中的固定产品。(支持增加任意产品)抽象工厂模式用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)工厂模式工厂模式不使用简单工厂的情况public class Client01 /调用者调用者 public static void
17、 main(String args)Car c1=new Audi();Car c2=new Byd();c1.run();c2.run();简单工厂模式简单工厂模式要点:简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。对于增加新产品无能为力!不修改代码的话,是无法扩展的。package com.bjsxt.simpleFactory;public class CarFactory public static Car createCar(String type)Car c=null;if(奥迪.equals(type)c =new Audi
18、();else if(奔驰.equals(type)c=new Benz();return c;public class CarFactory public static Car createAudi()return new Audi();public static Car createBenz()return new Benz();工厂方法模式工厂方法模式工厂方法模式要点:为了避免简单工厂模式的缺点,不完全满足OCP。工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。工厂模式工厂模式简单工厂模
19、式和工厂方法模式PK:结构复杂度从这个角度比较,显然简单工厂模式要占优。简单工厂模式只需一个工厂类,而工厂方法模式的工厂类随着产品类个数增加而增加,这无疑会使类的个数越来越多,从而增加了结构的复杂程度。代码复杂度代码复杂度和结构复杂度是一对矛盾,既然简单工厂模式在结构方面相对简洁,那么它在代码方面肯定是比工厂方法模式复杂的了。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。客户端编程难度工厂方法模式虽然在工厂类结构中引入了接口从而满足了OCP,但是在客户端编码中需要对工厂类进行实例化。而简单工厂模式的工厂类是个静态类,在客户
20、端无需实例化,这无疑是个吸引人的优点。管理上的难度这是个关键的问题。我们先谈扩展。众所周知,工厂方法模式完全满足OCP,即它有非常良好的扩展性。那是否就说明了简单工厂模式就没有扩展性呢?答案是否定的。简单工厂模式同样具备良好的扩展性扩展的时候仅需要修改少量的代码(修改工厂类的代码)就可以满足扩展性的要求了。尽管这没有完全满足OCP,但我们不需要太拘泥于设计理论,要知道,sun提供的java官方工具包中也有想到多没有满足OCP的例子啊。然后我们从维护性的角度分析下。假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号
21、入座已经是个问题了)。反而简单工厂没有这些麻烦,当多个产品类需要修改是,简单工厂模式仍然仅仅需要修改唯一的工厂类(无论怎样都能改到满足要求吧?大不了把这个类重写)。根据设计理论建议:工厂方法模式。但实际上,我们一般都用简单工厂模式。抽象工厂模式抽象工厂模式抽象工厂模式用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。抽象工厂模式抽象工厂模式类图工厂模式工厂模式工厂模式要点:简单工厂模式(静态工厂模式)虽然某种程度不符合设计原则,但实际使用最多。工厂
22、方法模式不修改已有类的前提下,通过增加新的工厂类实现扩展。抽象工厂模式不可以增加产品,可以增加产品族!应用场景JDK中Calendar的getInstance方法JDBC中Connection对象的获取Hibernate中SessionFactory创建Sessionspring中IOC容器创建管理bean对象XML解析时的DocumentBuilderFactory创建解析器对象反射中Class对象的newInstance()建造者模式建造者模式场景:我们要建造一个复杂的产品。比如:神州飞船,Iphone。这个复杂的产品的创建。有这样一个问题需要处理:装配这些子组件是不是有个步骤问题?实际开
23、发中,我们所需要的对象构建时,也非常复杂,有很多步骤需要处理时。建造模式的本质:分离了对象子组件的单独构造(由Builder来负责)和装配(由Director负责)。从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况下使用。由于实现了构建和装配的解耦。不同的构建器,相同的装配,也可以做出不同的对象;相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。建造者模式建造者模式构建“尚学堂牌”神舟飞船的示例建造者模式建造者模式开发中应用场景:StringBuilder类的append方法SQL中的PreparedStatemen
24、tJDOM中,DomBuilder、SAXBuilder原型模式原型模式prototype场景:思考一下:克隆技术是怎么样的过程?克隆羊多利大家还记得吗?javascript语言中的,继承怎么实现?那里面也有prototype,大家还记得吗?原型模式:通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。就是java中的克隆技术,以某个对象为原型,复制出新的对象。显然,新的对象具备原型对象的特点优势有:效率高(直接克隆,避免了重新执行构造过程步骤)。克隆类似于new,但是不同于new。new创建新的对象属性采用的是默认值。克隆出的对象的属性值完全和原型对象相同。并且克隆出
25、的新对象改变不会影响原型对象。然后,再修改克隆对象的值。原型模式实现:Cloneable接口和clone方法Prototype模式中实现起来最困难的地方就是内存复制操作,所幸在Java中提供了clone()方法替我们做了绝大部分事情。注意用词:克隆和拷贝一回事!原型模式原型模式prototype浅克隆存在的问题被复制的对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。深克隆如何实现?深克隆把引用的变量指向复制过的新对象,而不是原有的被引用的对象。深克隆:让已实现Clonable接口的类中的属性也实现Clonable接口基本数据类型和String能够自动实现
26、深度克隆(值的复制)原型模式原型模式prototype利用序列化和反序列化技术实现深克隆!Date date=new Date(12312321331L);Sheep s1=new Sheep(少利少利,date);System.out.println(s1);System.out.println(s1.getSname();System.out.println(s1.getBirthday();/使用序列化和反序列化实现深复制使用序列化和反序列化实现深复制ByteArrayOutputStream bos=new ByteArrayOutputStream();ObjectOutputStr
27、eam oos=new ObjectOutputStream(bos);oos.writeObject(s1);byte bytes=bos.toByteArray();ByteArrayInputStream bis=new ByteArrayInputStream(bytes);ObjectInputStream ois=new ObjectInputStream(bis);Sheep s2=(Sheep)ois.readObject();/克隆好的对象!克隆好的对象!System.out.println(修改原型对象的属性值);date.setTime(23432432423L);Sys
28、tem.out.println(s1.getBirthday();s2.setSname(多利);System.out.println(s2);System.out.println(s2.getSname();System.out.println(s2.getBirthday();原型模式原型模式prototype短时间大量创建对象时,原型模式和普通new方式效率测试开发中的应用场景原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。spring中bean的创建实际就是两种:单例模式和原型模式。(当然,原型模式需要和工厂模式搭配起来
29、)创建型模式的总结创建型模式的总结创建型模式:都是用来帮助我们创建对象的!单例模式保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。工厂模式简单工厂模式用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码)工厂方法模式用来生产同一等级结构中的固定产品。(支持增加任意产品)抽象工厂模式用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)建造者模式分离了对象子组件的单独构造(由Builder来负责)和装配(由Director负责)。从而可以构造出复杂的对象。原型模式通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式结构型模
30、式结构型模式结构型模式:核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题。分类:适配器模式、代理模式、桥接模式、装饰模式、组合模式、外观模式、享元模式结构型模式总结结构型模式总结结构型模式汇总代理模式为真实对象提供一个代理,从而控制对真实对象的访问适配模式使原本由于接口不兼容不能一起工作的类可以一起工作桥接模式处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联。组合模式将对象组合成树状结构以表示”部分和整体”层次结构,使得客户可以统一的调用叶子对象和容器对象装饰模式动态地给一个对象添加额外的功能,比
31、继承灵活外观模式为子系统提供统一的调用接口,使得子系统更加容易使用享元模式运用共享技术有效的实现管理大量细粒度对象,节省内存,提高效率适配器适配器adapter模式模式生活中的场景适配器适配器adapter模式模式什么是适配器模式?将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。模式中的角色目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。需要适配的类(Adaptee):需要适配的类或适配者类。适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。适配器适配器a
32、dapter模式模式下面的场景,如何解决?适配器模式解决方案:适配器适配器adapter模式模式类适配器对象适配器class Adapter extends Adaptee implements Target public void request()super.specificRequest();class Adapter implements Target private Adaptee adaptee;public Adapter(Adaptee adaptee)this.adaptee=adaptee;public void request()this.adaptee.specific
33、Request();适配器适配器adapter模式模式工作中的场景经常用来做旧系统改造和升级如果我们的系统开发之后再也不需要维护,那么很多模式都是没必要的,但是不幸的是,事实却是维护一个系统的代价往往是开发一个系统的数倍。我们学习中见过的场景java.io.InputStreamReader(InputStream)java.io.OutputStreamWriter(OutputStream)代理模式代理模式代理模式(Proxy pattern):核心作用:通过代理,控制对对象的访问!可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。(即:AOP的
34、微观实现!)AOP(AspectOrientedProgramming面向切面编程)的核心实现机制!从而实现将统一流程代码放到代理类中处理1.面谈2.合同起草3.签字,收预付款4.安排机票和车辆5.唱歌6.收尾款1.面谈2.合同起草3.签字,收预付款4.安排机票和车辆5.安排唱歌6.收尾款唱歌代理模式代理模式代理模式(Proxy pattern):核心角色:抽象角色定义代理角色和真实角色的公共对外方法真实角色实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。关注真正的业务逻辑!代理角色实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。将
35、统一的流程控制放到代理角色中处理!代理模式代理模式应用场景:安全代理:屏蔽对真实角色的直接访问。远程代理:通过代理类处理远程方法调用(RMI)延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有100MB,在打开文件时不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用proxy来进行大图片的打开。分类:静态代理(静态定义代理类)动态代理(动态生成代理类)JDK自带的动态代理javaassist字节码操作库实现CGLIBASM(底层使用指令,可维护性较差)静态代理(静态代理(static proxy
36、)静态代理(静态定义代理类)动态代理动态代理(dynamic proxy)动态代理(动态生成代理类)JDK自带的动态代理javaassist字节码操作库实现CGLIBASM(底层使用指令,可维护性较差)动态代理的优点动态代理的优点动态代理相比于静态代理的优点抽象角色中(接口)声明的所以方法都被转移到调用处理器一个集中的方法中处理,这样,我们可以更加灵活和统一的处理众多的方法。动态代理动态代理(JDK自带的实现自带的实现)JDK自带的动态代理java.lang.reflect.Proxy作用:动态生成代理类和对象java.lang.reflect.InvocationHandler(处理器接口)
37、可以通过invoke方法实现对真实角色的代理访问。每次通过Proxy生成代理类对象对象时都要指定对应的处理器对象Star realStar=new RealStar();StarHandler handler=new StarHandler(realStar);Star proxy=(Star)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new ClassStar.class,handler);proxy.sing();代理模式代理模式开发框架中应用场景:struts2中拦截器的实现数据库连接池关闭处理Hibernate中
38、延时加载的实现mybatis中实现拦截器插件AspectJ的实现spring中AOP的实现日志拦截声明式事务处理webserviceRMI远程方法调用.实际上,随便选择一个技术框架都会用到代理模式!面向切面编程面向切面编程AOP介绍介绍AOP(Aspect-OrientedProgramming,面向切面的编程)它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。它是一种新的方法论,它是对传统OOP编程的一种补充。1.面谈2.合同起草3.签字,收预付款4.安排机票和车辆5.安排唱歌6.收尾款客户面谈 合同起草 签字,收款 安排唱歌 客户客户面向切面
39、编程面向切面编程AOP介绍介绍常用术语:切面(Aspect):其实就是共有功能的实现。通知(Advice):是切面的具体实现。连接点(Joinpoint):就是程序在运行过程中能够插入切面的地点。切入点(Pointcut):用于定义通知应该切入到哪些连接点上。目标对象(Target):就是那些即将切入切面的对象,也就是那些被通知的对象代理对象(Proxy):将通知应用到目标对象之后被动态创建的对象。织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。开源的AOP框架AspectJ桥接模式桥接模式(bridge)场景商城系统中常见的商品分类,以电脑为类,如何良好的处理商品
40、分类销售的问题?我们可以用多层继承结构多层继承结构实现右图的关系。问题:扩展性问题(类个数膨胀问题):如果要增加一个新的电脑类型:智能手机,则要增加各个品牌下面的类。如果要增加一个新的品牌,也要增加各种电脑类型的类。违反单一职责原则:一个类:联想笔记本,有两个引起这个类变化的原因电脑台式机(Desktop)联想台式机戴尔台式机神舟台式机笔记本Laptop联想笔记本戴尔笔记本神舟笔记本平板电脑pad联想pad戴尔pad神舟pad桥接模式桥接模式场景分析商城系统中常见的商品分类,以电脑为类,如何良好的处理商品分类销售的问题?这个场景中有两个变化的维度:电脑类型、电脑品牌。品牌维度类型维度台式机笔记
41、本平板电脑联想神舟戴尔华硕桥接模式桥接模式桥接模式核心要点:处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联。桥接模式桥接模式桥接模式总结:桥接模式可以取代多层继承的方案。多层继承违背了单一职责原则,复用性较差,类的个数也非常多。桥接模式可以极大的减少子类的个数,从而降低管理和维护的成本。桥接模式极大的提高了系统可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有的系统,符合开闭原则。就像一个桥,将两个变化维度连接起来。各个维度都可以独立的变化。故称之为:桥模式桥接模式桥接模式桥接模式实际开发中应用场景JDBC驱动程序AW
42、T中的Peer架构银行日志管理:格式分类:操作日志、交易日志、异常日志距离分类:本地记录日志、异地记录日志人力资源系统中的奖金计算模块:奖金分类:个人奖金、团体奖金、激励奖金。部门分类:人事部门、销售部门、研发部门。OA系统中的消息处理:业务类型:普通消息、加急消息、特急消息发送消息方式:系统内消息、手机短信、邮件组合组合模式模式(composite)使用组合模式的场景:把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理部分对象和整体对象。组合模式核心:抽象构件(Component)角色:定义了叶子和容器构件的共同点叶子(Leaf)构件角色:无子节点容器(Composite
43、)构件角色:有容器特征,可以包含子节点组合组合模式模式(composite)组合模式工作流程分析:组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子。当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员,并调用执行。其中,使用了递归调用的机制对整个结构进行处理。使用组合模式,模拟杀毒软件架构设计组合组合模式模式开发中的应用场景:操作系统的资源管理器GUI中的容器层次图XML文件解析OA系统中,组织结构的处理Junit单元测试框架底层设计就是典型的组合模式,TestCase(叶子)、TestUnite(
44、容器)、Test接口(抽象)组合组合模式模式Junit单元测试框架底层设计底层设计就是典型的组合模式,TestCase(叶子)、TestUnite(容器)、Test接口(抽象)装饰装饰模式模式(decorator)职责:动态的为一个对象增加新的功能。装饰模式是一种用于代替继承的技术,无须通过继承增加子类就无须通过继承增加子类就能扩展对象的新功能能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀同时避免类型体系的快速膨胀。装饰装饰模式模式(decorator)实现细节:Component抽象构件角色:真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与
45、真实对象相同的方式同装饰对象交互。ConcreteComponent具体构件角色(真实对象):io流中的FileInputStream、FileOutputStreamDecorator装饰角色:持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能。ConcreteDecorator具体装饰角色:负责给构件对象增加新的责任。装饰装饰模式模式(decorator)简单案例说明增加人工智能,自动驾驶,汽车人增加浮沉箱,水上汽车增加翅膀,飞行汽车车装饰装饰模式模式(decorator)开发中使用的场景:IO中输入流和输出流的设计
46、Swing包中图形界面构件功能ServletAPI中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper类,增强了request对象的功能。Struts2中,request,response,session对象的处理装饰装饰模式模式(decorator)IO流实现细节:Component抽象构件角色:io流中的InputStream、OutputStream、Reader、WriterConcreteComponent具体构件角色:io流中的FileInputStream、Fi
47、leOutputStreamDecorator装饰角色:持有一个抽象构件的引用:io流中的FilterInputStream、FilterOutputStreamConcreteDecorator具体装饰角色:负责给构件对象增加新的责任。Io流中的BufferedOutputStream、BufferedInputStream等。装饰装饰模式模式(decorator)总结:装饰模式(Decorator)也叫包装器模式(Wrapper)装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。优点扩展对象功能
48、,比继承灵活,不会导致类个数急剧增加可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类。缺点产生很多小对象。大量小对象占据内存,一定程度上影响性能。装饰模式易于出错,调试排查比较麻烦。装饰装饰模式模式(decorator)装饰模式和桥接模式的区别:两个模式都是为了解决过多子类对象问题。但他们诱因不一样。桥模式是对象自身现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能。装饰装饰模式模式(decorator)装饰模式和桥接模式的区别:两个模式都是为了解决过多子类对象
49、问题。但他们诱因不一样。桥模式是对象自身现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能。装饰装饰模式模式(decorator)装饰模式和桥接模式的区别:两个模式都是为了解决过多子类对象问题。但他们诱因不一样。桥模式是对象自身现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能。外观外观模式模式 facade迪米特法则(最少知识原则):一个软件实体应当尽可能少的与其他实体发生相互作用。外观外观模式模式 facade外观模式核心:为子系统提供统一的入口。封装子系统的复杂性,便于客户端调用。外观外观模式模式 facade基本案例注册公司流程(不使用外观模式)
50、外观外观模式模式 facade基本案例注册公司流程(使用外观模式)外观外观模式模式 facade开发中常见的场景频率很高。哪里都会遇到。各种技术和框架中,都有外观模式的使用。如:JDBC封装后的,commons提供的DBUtils类,Hibernate提供的工具类、SpringJDBC工具类等享元模式享元模式(FlyWeight)场景:内存属于稀缺资源,不要随便浪费。如果有很多个完全相同或相似的对象,我们可以通过享元模式,节省内存。核心:享元模式以共享的方式高效地支持大量细粒度对象的重用。享元对象能做到共享的关键是区分了内部状态和外部状态。内部状态:可以共享,不会随环境变化而改变外部状态:不可