设计模式
=============================================================================创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 ==单例模式(Singleton) 单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处: 1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。 2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。 3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。 ==工厂模式 -0、简单工厂模式:01、普通 02、多个方法 03、多个静态方法 1、工厂方法模式(Factory Method) 主要类有:1产品实现类,产品类,工厂实现类的接口,工厂实现类;2工厂接口只生产一种产品(方法只有一个); 对应需求:新增生产的产品:则新增产品实现类,和工厂实现类; 2、抽象工厂模式 主要类有:1产品实现类,产品类,工厂实现类的接口,工厂实现类;2工厂接口生产多种产品(方法有多个); 对应需求:a新增工厂:新增工厂实现类(如某个品牌工厂)实现工厂实现类的接口,重写所有方法(生产某品牌工厂对应的产品); b新增生产的产品:则新增产品实现类,增加工厂类接口的方法,重写所有工厂所对应该产品的方法; ==建造者模式 使用建造模式的场合: 1.创建一些复杂的对象时,这些对象的内部组成构件间的建造顺序是稳定的,但是对象的内部组成构件面临着复杂的变化。 2.要创建的复杂对象的算法,独立于该对象的组成部分,也独立于组成部分的装配方法时。 优缺点: 优点:低耦合。在建造者模式中, 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦。每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。 符合“开闭原则”。指挥者类针对抽象建造者类编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便。 缺点:使用范围有限。如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。 适用环境:产品结构复杂,创建对象过程复杂 使用场景:游戏角色。 问题:建造者模式和抽象工厂模式的比较 返回的产品个数不同。建造者模式只能返回一个复杂产品;而抽象工厂模式可以返回很多产品。 ==原型模式=============================================================================结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 ==适配器模式 对象的适配器模式是各种结构型模式的起源。 适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。 主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。 类的适配器模式:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。 对象的适配器模式:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Wrapper类,持有原类的一个实例,在Wrapper类的方法中,调用实例的方法就行。 接口的适配器模式:当不希望实现一个接口中所有的方法时,可以创建一个抽象类Wrapper,实现所有方法,我们写别的类的时候,继承抽象类即可。 ==装饰者模式 --装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例(增加成员属性,构造方法或setter方法注入实力对象,装饰类中增加新功能方法)。 --装饰器模式的应用场景: 1、需要扩展一个类的功能。 2、动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。) 缺点:产生过多相似的对象,不易排错!实例:数据库连接池,java io流 ==代理模式 现实需求:原有业务不动,需要添加额外的功能 用代理设计模式可实现原有的源代码能够正常执行,也没有修改源代码,通过代理设计模式能够实现在原有功能前或后添加新功能 代理步骤:针对方式二 1.必须有能够正常运行的业务源代码 2.必须有要额外添加的功能代码 3.必须有一个类把原有业务跟新业务耦合(组合),即把新功能横切或织入到需要的业务类的前或后。 --静态代理 新功能类 原功能业务类 新耦合类,实现原功能业务类的接口,重写业务方法;成员属性,新功能类和原业务类,提供属性setter方法或构造方法。 从编码的角度来说,代理模式分为静态代理和动态代理,上面的例子是静态代理,在代码运行前就已经存在了代理类的class编译文件,而动态代理则是在代码运行时通过反射来动态的生成代理类的对象,并确定到底来代理谁。也就是我们在编码阶段不需要知道代理谁,代理谁我们将会在代码运行时决定。 --动态代理 Java提供了动态的代理接口InvocationHandler,实现该接口需要重写invoke()方法。 jdk动态代理:jdk自带,不需要第三方jar支撑,代理实现类有需要接口类; cglib动态代理:需要第三方jar支撑,不需要接口类; ------------------------------------------------------ 原有业务功能 新功能类 新旧功能耦合类对象工厂,定义类加载器,原有业务功能的接口,重写接口类invoke方法(参数targetObject)。 新旧功能耦合类对象的方法调用将会调用重写接口的方法; ------------------------------------------------------ ==外观模式 ==桥接模式 ==组合模式 ==享元模式=============================================================================行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 ==策略模式 -应用场景:将具体的实现方法交给子类去选择实现,原有基础上增加功能,但子类不一定需要该功能; -主要类元素: Context:用来操作策略的上下文环境。(构造策略实例,调用策略方法) Stragety:策略的抽象。 ConcreteStragetyA、ConcreteStragetyB:具体的策略实现。 -缺点 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。 ==模板方法模式 ==观察者模式 ==迭代子模式 ==责任链模式(Chain of Responsibility Pattern) 责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。 -servlet中的Filter:servlet中分别定义了一个 Filter和FilterChain的接口 -Dubbo中的Filter:Dubbo在创建Filter的时候是另外一个方法,通过把Filter封装成 Invoker的匿名类,通过链表这样的数据结构来完成责任链 -Mybatis中的Plugin:Mybatis可以配置各种Plugin,无论是官方提供的还是自己定义的,Plugin和Filter类似,就在执行Sql语句的时候做一些操作。Mybatis的责任链则是通过动态代理的方式,使用Plugin代理实际的Executor类。(这里实际还使用了组合模式,因为Plugin可以嵌套代理) ==命令模式 ==备忘录模式 ==状态模式 ==访问者模式 ==中介者模式 ==解释器模式