23种设计模式
2020-09-22 21:24:57 1 举报
AI智能生成
23钟设计模式
作者其他创作
大纲/内容
设计模式总结:
装饰者模式、命令模式、代理模式区别?
命令模式:叫你干啥就干啥
代理模式:叫你干啥你还干了点别的啥
装饰者模式:让你能多干点啥,但不马上干
适配器模式:复用老接口,暴露新接口
状态模式:当前状态业务执行完,会流转到下一个状态
抽象工厂模式:创造一系列统一接口的对象工厂
原型模式:clone/创建一个一摸一样的对象,分深浅拷贝
建造者模式:创造一系列对象,通过他们最后构建成目标对象
模板模式:控制核心逻辑,扩展交给实现类
命令模式:叫你干啥就干啥
代理模式:叫你干啥你还干了点别的啥
装饰者模式:让你能多干点啥,但不马上干
适配器模式:复用老接口,暴露新接口
状态模式:当前状态业务执行完,会流转到下一个状态
抽象工厂模式:创造一系列统一接口的对象工厂
原型模式:clone/创建一个一摸一样的对象,分深浅拷贝
建造者模式:创造一系列对象,通过他们最后构建成目标对象
模板模式:控制核心逻辑,扩展交给实现类
创建型模式(6种)
简单工厂方法模式(Simple Factory)
定义:是指由一个工厂对象决定创建出哪一种产品类的实例,但它不属于23种设计模式,
简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,
对于如何创建对象的逻辑不需要关心
简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,
对于如何创建对象的逻辑不需要关心
通俗理解:FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,
虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory
虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory
源码中的应用:在JDK源码中无处不在:
1:Calendar类,Calendar.getInstance();
2: logback LoggerFactory有多个重载方法getLogger()
1:Calendar类,Calendar.getInstance();
2: logback LoggerFactory有多个重载方法getLogger()
类结构图
抽象工厂模式(Abstract Factory)
定义:提供一个创建一系列相关活相互依赖对象的接口,无序指定他们具体的类,客户端(应用层)不依赖与产品类实现如何被创建,实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用常见对象需要大量重复的代码,需要提供一个产品类的库,所有的产品已同样的接口出现,从而使客户端不依赖与具体实现;
通俗理解:同一类产品在一个工厂内处理,因为有相同的属性
源码中的应用:
使用场景:根据不同的支付类型处理
优缺点:
1:规定了所有可能被常见的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂接口,
2:增加了系统的抽象性和理解难度
1:规定了所有可能被常见的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂接口,
2:增加了系统的抽象性和理解难度
类结构图:
工厂方法模式(Factory Method)
定义:是指定义一个创建对象的接口,但让实现这个接口的类来界定实例化那个类,
工厂方法让类的实例化推迟到子类中进行,在工厂方法模式中用户只需要关心所需产品对应的工厂,
无序关心创建细节,而且加入新的产品符合开闭原则
工厂方法让类的实例化推迟到子类中进行,在工厂方法模式中用户只需要关心所需产品对应的工厂,
无序关心创建细节,而且加入新的产品符合开闭原则
通俗理解:根据单一职责,工厂方法可认为专人干专事
源码中的应用:logback中工厂方法 ILoggerFactory(接口)
实现有:LoggerContext(),SubstituteLoggerFactory(),NOPLoggerFactory()
实现有:LoggerContext(),SubstituteLoggerFactory(),NOPLoggerFactory()
使用场景:
1:创建对象需要大量重复的代码,
2:客户端(应用层)不依赖与产品类实列对河被创建,实现等细节
3:一个类通过其子类来指定创建那个对象
1:创建对象需要大量重复的代码,
2:客户端(应用层)不依赖与产品类实列对河被创建,实现等细节
3:一个类通过其子类来指定创建那个对象
优缺点:
1:类的个数容易过多,增加复杂度
2:增加了系统的抽象性和理解难度
1:类的个数容易过多,增加复杂度
2:增加了系统的抽象性和理解难度
类结构图:
建造者模式(Builder)
定义:
将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,
使用创建者模式对于用户而言只需要指定需要建造的类型就可以获得对象,建造过程及细节不需要了解
或者
将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。
建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。
将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,
使用创建者模式对于用户而言只需要指定需要建造的类型就可以获得对象,建造过程及细节不需要了解
或者
将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。
建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。
通俗理解:BUILDER—MM最爱听的就是“我爱你”这句话了,见到不同地方的MM,要能够用她们的方言跟她说这句话哦,我有一个多种语言翻译机,上面每种语言都有一个按键,见到MM我只要按对应的键,它就能够用相应的语言说出“我爱你”这句话了,国外的MM也可以轻松搞掂,这就是我的“我爱你”builder。
优缺点:
1:封装性好,创建与使用分离;
2:扩展性好,建造类之间独立,一定程度上解耦了;
1:产生多余的Builder对象;
2:产品内部发生变化,建造者都要修改,成本大
1:封装性好,创建与使用分离;
2:扩展性好,建造类之间独立,一定程度上解耦了;
1:产生多余的Builder对象;
2:产品内部发生变化,建造者都要修改,成本大
源码中的应用:
1:JDK的StringBuilder 提供append()方法
2:MyBatis中, CacheBuilder cacheBuilder.build()
3:在MyBatis中,SqlSessionFactoryBuilder 通过调用build()方法获得的是一个SqlSessionFactory类
4:Spring中,BeanDefinitionBuilder通过调用getBeanDefinition()方法获得一个BeanDefinition对象
5:还有个主要的应用,就是链式编程,也是java8的新特性
1:JDK的StringBuilder 提供append()方法
2:MyBatis中, CacheBuilder cacheBuilder.build()
3:在MyBatis中,SqlSessionFactoryBuilder 通过调用build()方法获得的是一个SqlSessionFactory类
4:Spring中,BeanDefinitionBuilder通过调用getBeanDefinition()方法获得一个BeanDefinition对象
5:还有个主要的应用,就是链式编程,也是java8的新特性
与工厂模式的区别:
1:建造者模式更加关注方法的调用顺序,工厂更加注重与创建对象。
2:创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的都一样。
3:关注重点不一样,工厂迷失只需要把对象创建出来就可以了,而建造者模式中不仅要创建出这个对象,还要知道这个对象由哪些部件组成。
4:建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也不一样。
1:建造者模式更加关注方法的调用顺序,工厂更加注重与创建对象。
2:创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的都一样。
3:关注重点不一样,工厂迷失只需要把对象创建出来就可以了,而建造者模式中不仅要创建出这个对象,还要知道这个对象由哪些部件组成。
4:建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也不一样。
类结构图:
原型模式(Prototype)
定义:是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,属于创建型模式
通俗理解 :
PROTOTYPE—跟MM用QQ聊天,一定要说些深情的话语了,我搜集了好多肉麻的情话,
需要时只要copy出来放到QQ里面就行了,这就是我的情话prototype了
PROTOTYPE—跟MM用QQ聊天,一定要说些深情的话语了,我搜集了好多肉麻的情话,
需要时只要copy出来放到QQ里面就行了,这就是我的情话prototype了
原型模式
浅克隆
深克隆
源码中的应用
JDK中Cloneable,
ArrayList clone()
JDK中Cloneable,
ArrayList clone()
优缺点:
1:性能优良,Java 自带的原型模式,是基于内存二进制流的拷贝,比直接new一个对象性能上提升了许多
2:可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用,可辅助实现撤销操作
3:需要为没一个类配置一个克隆方法
4:克隆方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违法了开闭原则
5:在实现深克隆时需要编写较为复杂的代码,
1:性能优良,Java 自带的原型模式,是基于内存二进制流的拷贝,比直接new一个对象性能上提升了许多
2:可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用,可辅助实现撤销操作
3:需要为没一个类配置一个克隆方法
4:克隆方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违法了开闭原则
5:在实现深克隆时需要编写较为复杂的代码,
单例模式(Singleton)
定义:是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点,单列模式在实现生活中应用也非常广泛,
ServletContext ,ServletContextConfig ,Sring 框架应用中ApplicationContext,数据库的连接池也都是单例形式;
ServletContext ,ServletContextConfig ,Sring 框架应用中ApplicationContext,数据库的连接池也都是单例形式;
通俗理解:SINGLETON—A有6个漂亮的老婆,她们的老公都是A,A就是他们家里的老公Sigleton,她们只要说道“老公”,都是指的同一个人,那就是A
单列模式
饿汉式单列模式
项目初始化。类加载的时候就立即初始化,并且创建单例对象线程安全的,
在线程还没出现以前就实例化了,不可能存在访问安全问题
在线程还没出现以前就实例化了,不可能存在访问安全问题
优缺点:可以保证线程安全,但是导致内存浪费,
懒汉式单列模式
单列对象在被使用时才会初始化
优缺点:在多线程环境下,就会出现线程安全问题
注册式单列模式
1:枚举式单例模式
2:容器式单例
线程单例实现ThreadLocal
ThreadLocal不能保证其创建的对象是全局唯一的,但是能保证在单个线程中是唯一的,天生是线程安全的,
给方法上锁,以时间换空间,ThreadLocal将所有的对象全部放在ThreadLocalMap中,为每个线程都提供一个对象,
实际上是以空间换时间来实现线程隔离的
给方法上锁,以时间换空间,ThreadLocal将所有的对象全部放在ThreadLocalMap中,为每个线程都提供一个对象,
实际上是以空间换时间来实现线程隔离的
源码中的应用:JDK 中的 RunTime类
结构型模式(7种)
适配器模式(Adapter)
定义 把一个类的接口变成客户端所期待的另一种接口,从而是原本因接口原因不匹配二无法一起工作的两个类能够一起工作,
适配类可以根据参数返还一个合适的实列给客户端。
也可理解为: 当前系统存在两种接口 A 跟B ,客户只支持访问A 接口,但是当前系统没有A接口对象,但是有B接口对象,但客户无法识别B接口,因此需要通过一个适配器C,将B接口内转换成A接口,从而使得客户能够从A接口获取得到B接口内容
适配类可以根据参数返还一个合适的实列给客户端。
也可理解为: 当前系统存在两种接口 A 跟B ,客户只支持访问A 接口,但是当前系统没有A接口对象,但是有B接口对象,但客户无法识别B接口,因此需要通过一个适配器C,将B接口内转换成A接口,从而使得客户能够从A接口获取得到B接口内容
通俗理解 在朋友聚会上碰到了一个美女Sarah,从香港来的,可我不会说粤语,她不会说普通话,只好求助于我的朋友kent了,
他作为我和Sarah之间的Adapter,让我和Sarah可以相互交谈了
他作为我和Sarah之间的Adapter,让我和Sarah可以相互交谈了
优缺点
优点:1:能提高类的透明性和复用,现有的类复用但不需要改变
2:目标类和适配器解耦,提高程序的扩展性
3:在很多业务场景中符合开闭原则
2:目标类和适配器解耦,提高程序的扩展性
3:在很多业务场景中符合开闭原则
缺点:
1:适配器编写过程需要全面考虑,可能会增加系统的复杂性
2:增加代码阅读难度, 降低代码可读性,过多使用适配器会是系统代码变的凌乱
1:适配器编写过程需要全面考虑,可能会增加系统的复杂性
2:增加代码阅读难度, 降低代码可读性,过多使用适配器会是系统代码变的凌乱
源码中的应用 SpringAOP 中的 AdvisorAdapter类 有三个实现类,MethodBeforeAdviceAdapter, AfterReturningAdviceAdapter 和 ThrowsAdviceAdapter
SpringMVC 中的HandlerAdapter类 也有多个子类 关键适配主要在DispatcherServlet 的doDisPatch();
SpringMVC 中的HandlerAdapter类 也有多个子类 关键适配主要在DispatcherServlet 的doDisPatch();
类结构图
桥接模式(Bridge)
定义:桥接模式也称为桥梁模式,接口模式或柄体模式,是将首相部分与它的具体实现部分分离,是他们都可以独立的变化
倩姐模式主要目的是通过组合的方式建立两个类之间的联系,而不是继承,但有类似于多重继承方案,但是多重继承方案往往
违背了类的单一职责原则,器复用性比较差,掐季节模式是必多重继承更好的替代方案,
桥接模式的核心在于解耦抽象和实现 完全代替继承
遵循了里氏替换原则与依赖倒置原则,最终实现了开闭原则
倩姐模式主要目的是通过组合的方式建立两个类之间的联系,而不是继承,但有类似于多重继承方案,但是多重继承方案往往
违背了类的单一职责原则,器复用性比较差,掐季节模式是必多重继承更好的替代方案,
桥接模式的核心在于解耦抽象和实现 完全代替继承
遵循了里氏替换原则与依赖倒置原则,最终实现了开闭原则
通俗理解 :早上碰到MM,要说早上好,晚上碰到MM,要说晚上好;碰到MM穿了件新衣服,要说你的衣服好漂亮哦,碰到MM新做的发型,要说你的头发好漂亮哦。不要问我“早上碰到MM新做了个发型怎么说”这种问题,自己用BRIDGE组合一下不就行了
优缺点
优点:
1:分离抽象部分及具体实现部分
2:提高了系统的扩展性
3:符合开闭原则
4:符合合成复用原则
1:分离抽象部分及具体实现部分
2:提高了系统的扩展性
3:符合开闭原则
4:符合合成复用原则
缺点:
1:增加了系统的理解与设计难度
2:需要正确地识别系统中的两个独立变化的维度
1:增加了系统的理解与设计难度
2:需要正确地识别系统中的两个独立变化的维度
源码中的应用 JDBC API 有个Driver 就是桥接模式,Class.forName()方法 driverManager 连接 数据库无关 ~ 与数据库有关
类结构图
组合模式(Composite)
定义 也称为整体—部分模式,它的宗旨是通过将单个对象(叶子节点)和组合对象(树枝节点)用相同的接口进行标示,
是的客户对单个对象和组合对象的使用具有一致性,
强调的是整体与部分的关系,他讲对象组织到树形结构中,最顶层的节点称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又包含树枝节点和叶子节点
是的客户对单个对象和组合对象的使用具有一致性,
强调的是整体与部分的关系,他讲对象组织到树形结构中,最顶层的节点称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又包含树枝节点和叶子节点
通俗理解 :COMPOSITE—Mary今天过生日。“我过生日,你要送我一件礼物。”“嗯,好吧,去商店,你自己挑。”“这件T恤挺漂亮,买,这条裙子好看,买,这个包也不错,买。”“喂,买了三件了呀,我只答应送一件礼物的哦。”“什么呀,T恤加裙子加包包,正好配成一套呀,小姐,麻烦你包起来。
与聚合模式的区别 1: 组合模式:在古代皇帝三宫六院,贵妃很多,但是每个贵妃只属于皇帝(具有相同的生命周期)
2:聚合关系: 一个老师有很多个学生,但是每一个学生又属于多个老师(具有不同的生命周期)
2:聚合关系: 一个老师有很多个学生,但是每一个学生又属于多个老师(具有不同的生命周期)
优缺点 1:清楚的定义分层次的复杂对象,表示对象的全部或部分层次
2:让客户端忽略了层次的差异,方便对整个层次结构进行控制
3:简化客户端代码
4:符合开闭原则
2:让客户端忽略了层次的差异,方便对整个层次结构进行控制
3:简化客户端代码
4:符合开闭原则
源码中的应用 1: HashMap putAll()
2:ArrayList addAll()
3:Mybatis 中的 Mapping sql 其中有个 sqlNode类
2:ArrayList addAll()
3:Mybatis 中的 Mapping sql 其中有个 sqlNode类
类结构图
装饰器模式(Decorator)
定义:装饰器模式以对客户端透明的方式扩展对象功能,是继承关系的一个替代方案,提供继承更多的灵活性,
动态给一个对象增加功能,这些功能可以在动态撤销,增加有一些基本功能的排列组合而产生的非常大的功能
动态给一个对象增加功能,这些功能可以在动态撤销,增加有一些基本功能的排列组合而产生的非常大的功能
通俗理解:Mary过完轮到Sarly过生日,还是不要叫她自己挑了,不然这个月伙食费肯定玩完,拿出我去年在华山顶上照的照片,
在背面写上“最好的的礼物,就是爱你的Fita”,再到街上礼品店买了个像框(卖礼品的MM也很漂亮哦),再找隔壁搞美术设
计的Mike设计了一个漂亮的盒子装起来……,我们都是Decorator,最终都在修饰我这个人呀
在背面写上“最好的的礼物,就是爱你的Fita”,再到街上礼品店买了个像框(卖礼品的MM也很漂亮哦),再找隔壁搞美术设
计的Mike设计了一个漂亮的盒子装起来……,我们都是Decorator,最终都在修饰我这个人呀
优缺点
优点:装饰器是继承的有力补充,比继承还要灵活,不改变原有对象的情况下动态地给一个对象扩展功能,
即插即用,通过使用不同的装饰器自己这些装饰类的排列组合,尅实现不同的效果
即插即用,通过使用不同的装饰器自己这些装饰类的排列组合,尅实现不同的效果
缺点:会出现更多的代码,更多的类,增加程序的复杂性
动态装饰时,多层装饰时会更复杂
动态装饰时,多层装饰时会更复杂
源码中的应用 :JDK中BUfferedReader, INputStream, OutputStream,
Spring中的 TransactionAwareCacheDecorator 主要是处理事务缓存的
myBatis 中 TransactionlCache
Spring中的 TransactionAwareCacheDecorator 主要是处理事务缓存的
myBatis 中 TransactionlCache
比较 : 与代理模式的区别:
代理模式 :强调对代理过程的控制,简单的理解,就是所有的事情都是在代理类中完成的,简单理解为一个人,或者平台干了
装饰器 :主要是每个类都去干了,平台上的每个人甚至与自己也算在里面都要去做
代理模式 :强调对代理过程的控制,简单的理解,就是所有的事情都是在代理类中完成的,简单理解为一个人,或者平台干了
装饰器 :主要是每个类都去干了,平台上的每个人甚至与自己也算在里面都要去做
类结构图
门面模式(Facade)
定义:又叫做外观模式,提供了一个统一的接口,用来访问子系统中的一群接口,器主要特征是蒂尼了一个高层接口,让子系统更容易使用。
外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。每一个子系统只有一个门面类,
而且此门面类只有一个实例,也就是说它是一个单例模式。但整个系统可以有多个门面类
外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。每一个子系统只有一个门面类,
而且此门面类只有一个实例,也就是说它是一个单例模式。但整个系统可以有多个门面类
通俗理解:我有一个专业的Nikon相机,我就喜欢自己手动调光圈、快门,这样照出来的照片才专业,但MM可不懂这些,教了半天也不会。幸好相机有Facade设计模式,把相机调整到自动档,只要对准目标按快门就行了,一切由相机自动调整,这样MM也可以用这个相机给我拍张照片了
优缺点
优点:
简化了调用过程,无需深入了解子系统,以防给子系统带来风险;
减少系统依赖,松散耦合
更好地规划访问层次,提高了安全性
遵循迪米特法则,即最少知道原则;
简化了调用过程,无需深入了解子系统,以防给子系统带来风险;
减少系统依赖,松散耦合
更好地规划访问层次,提高了安全性
遵循迪米特法则,即最少知道原则;
缺点:
当增加子系统和扩展子系统行为时,可能容易带来未知风险
不符合开闭原则
某些情况下可能违背单一职责原则;
当增加子系统和扩展子系统行为时,可能容易带来未知风险
不符合开闭原则
某些情况下可能违背单一职责原则;
源码中的应用: 1:Spring JDBC jdbcUtils 封装了和JDBC相关的所有操作,
2:MyBatis中的Configuration
3:Tomact 中RequestFacade 封装了非常多的request的操作
2:MyBatis中的Configuration
3:Tomact 中RequestFacade 封装了非常多的request的操作
类结构图
享元模式(Flyweight)
定义:称为轻量级模式,是对象池的一种实现,类似于线程池,线程池可以避免不停的创建和销毁多个对象,
消耗性能,提供了减少对象数量从而改善应用所需的对象结构的方式,其宗旨是共享细粒度对象,将多个同一对象的访问几种起来,不必为每个访问着创建一个单独的对象,以此来降低内存的消耗,
消耗性能,提供了减少对象数量从而改善应用所需的对象结构的方式,其宗旨是共享细粒度对象,将多个同一对象的访问几种起来,不必为每个访问着创建一个单独的对象,以此来降低内存的消耗,
通俗理解 每天跟MM发短信,手指都累死了,最近买了个新手机,可以把一些常用的句子存在手机里,要用的时候,直接拿出来,在前面加上MM的名字就可以发送了,再不用一个字一个字敲了。共享的句子就是Flyweight,MM的名字就是提取出来的外部特征,根据上下文情况使用。
状态区分: 1:内部状态 是不变化的,
2:外部状态:是变化的 通过共享不变的部分,达到减少对象数量并节约内存的目的
比如:连接池中的连接对象,保存在连接对象中的用户名,密码,连接信息URL,在创建对象的时候就设置好了,不会随环境的改变而改变,这些为内部状态,而每个连接要会后利用时,我们需要给它标记为可用状态,这些为外部状态
2:外部状态:是变化的 通过共享不变的部分,达到减少对象数量并节约内存的目的
比如:连接池中的连接对象,保存在连接对象中的用户名,密码,连接信息URL,在创建对象的时候就设置好了,不会随环境的改变而改变,这些为内部状态,而每个连接要会后利用时,我们需要给它标记为可用状态,这些为外部状态
优缺点 优点:1:减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率
2:减少内存之外的其他资源占用
缺点:1:关注内,外部状态,关注线程安全问题
2:使系统,程序的逻辑复杂化
2:减少内存之外的其他资源占用
缺点:1:关注内,外部状态,关注线程安全问题
2:使系统,程序的逻辑复杂化
源码中的应用 一般是有缓存的使用
Java 中 String final
Integer 中 目标值在 -128 ~ 127 之间
Long
Apache Commons Pool2 中的享元模式
Java 中 String final
Integer 中 目标值在 -128 ~ 127 之间
Long
Apache Commons Pool2 中的享元模式
类结构图
代理模式(Proxy)
定义 : 是指为其他对象提供一种代理,以控制对这个对象的访问,在某种情况下,
一个对象不适合或者不能直接引用另外一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用
一个对象不适合或者不能直接引用另外一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用
通俗理解: 跟MM在网上聊天,一开头总是“hi,你好”,“你从哪儿来呀?”“你多大了?”“身高多少呀?”这些话,
真烦人,写个程序做为我的Proxy吧,凡是接收到这些话都设置好了自动的回答,接收到其他的话时再通知我回答,
真烦人,写个程序做为我的Proxy吧,凡是接收到这些话都设置好了自动的回答,接收到其他的话时再通知我回答,
代理模式分类
静态代理:
子主题
类结构图
动态代理 :
子主题
类结构图
优缺点 1:代理模式能将代理对象与真实被调用目标对象分离
2:在一定程度上降低了系统的耦合性,扩展性好
3:可以起到保护目标对象的作用
4:可以增强目标对象的功能
缺点 ; 1;代理模式会造成系统设计中的类的数量增加
2:在客户端和目标对象中增加一个代理对象,会导致请求处理速度变慢
3:增加了系统的复杂性
2:在一定程度上降低了系统的耦合性,扩展性好
3:可以起到保护目标对象的作用
4:可以增强目标对象的功能
缺点 ; 1;代理模式会造成系统设计中的类的数量增加
2:在客户端和目标对象中增加一个代理对象,会导致请求处理速度变慢
3:增加了系统的复杂性
源码中的应用 基于SPring生态中 SpringAOP
行为型模式(11种)【委派模式不包含】
策略模式(Strategy)
定义 :幼教政策模式,它是将定义的算法家族,分别封装起来,让他们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户
策略模式使用的就是面向对象的继承和多态机制,从而实现同一行为在不同场景下具备不同的实现。主要解决if()else.switch()等
策略模式使用的就是面向对象的继承和多态机制,从而实现同一行为在不同场景下具备不同的实现。主要解决if()else.switch()等
通俗理解 :跟不同类型的MM约会,要用不同的策略,有的请电影比较好,有的则去吃小吃效果不错,
有的去海边浪漫最合适,单目的都是为了得到MM的芳心,追MM锦囊中有好多Strategy哦
有的去海边浪漫最合适,单目的都是为了得到MM的芳心,追MM锦囊中有好多Strategy哦
优点 1:符合开闭原则
2:避免使用多重条件转移语句,如if...else....语句,switch 语句
3:可以提高算法的保密性和安全性
缺点 : 1:客户端必须知道所有的策略,并且紫荆解决使用哪一个策略
2:代码中会产生非常多的策略类,增加维护难度
2:避免使用多重条件转移语句,如if...else....语句,switch 语句
3:可以提高算法的保密性和安全性
缺点 : 1:客户端必须知道所有的策略,并且紫荆解决使用哪一个策略
2:代码中会产生非常多的策略类,增加维护难度
源码中的应用 1:JDk中的Comparator Compare(),会传入Arrays, parallelSort
2:TreeMap 的构造方法
3:Spring中Resource的子类,有两种策略 SimplelnstantiationStrategy 与 CglibSubclassingInstantiationStrategy
2:TreeMap 的构造方法
3:Spring中Resource的子类,有两种策略 SimplelnstantiationStrategy 与 CglibSubclassingInstantiationStrategy
类结构图
模板方法模式(Template Method)
定义:是指定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤,
固定一个模板。如果要修改就让他的子类去实现,去修改 ,但是模板
固定一个模板。如果要修改就让他的子类去实现,去修改 ,但是模板
通俗理解 :准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。
优缺点 1:利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性
2:将不同的代码放到不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性
3:吧不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则
缺点: 1:类数据的增加,每一个手续类都需要一个子类来实现,导致类的个数增加
2:类的数量增加,见解的增加了系统实现的复杂度
3:继承关系自身缺点,如果父类添加新的抽象方法,所有的子类都要改一遍
2:将不同的代码放到不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性
3:吧不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则
缺点: 1:类数据的增加,每一个手续类都需要一个子类来实现,导致类的个数增加
2:类的数量增加,见解的增加了系统实现的复杂度
3:继承关系自身缺点,如果父类添加新的抽象方法,所有的子类都要改一遍
源码中的应用 mybatis中 的连接信息
子主题
类结构图
责任链模式(Chain of Responsibility)
定义 是将链中的没一个节点看作是一个对象,每个节点处理的请求均不同,且内部自动维护一个下一节点对象,当一个请求从链式的首段发出时,会沿着链的路径依次传递给没一个节点对象,直至有对象处理这个请求为止
通俗理解 :晚上去上英语课,为了好开溜坐到了最后一排,哇,前面坐了好几个漂亮的MM哎,找张纸条,写上“Hi,可以做我的女朋友吗?如果不愿意请向前传”,
纸条就一个接一个的传上去了,糟糕,传到第一排的MM把纸条传给老师了,听说是个老处女呀,快跑!
纸条就一个接一个的传上去了,糟糕,传到第一排的MM把纸条传给老师了,听说是个老处女呀,快跑!
优点 1:将请求与处理解耦
2:请求处理这只需关注自己感兴趣的请求进行处理即可,对于不感兴趣的请求,直接转发给下一个节点
3:具备链式传递请求功能,请求发送者无需知晓链路结构,只需要等待请求处理结果
4:链路结构灵活,可以通过改变链路结构动态地新增或者删减责任
5:易于扩展新的请求处理类,符合开闭原则
缺点:1:责任链太长或者处理时间过长,会影响整体性能
2:如果节点对象存在循环引用时,或造成死循环,导致系统崩溃
2:请求处理这只需关注自己感兴趣的请求进行处理即可,对于不感兴趣的请求,直接转发给下一个节点
3:具备链式传递请求功能,请求发送者无需知晓链路结构,只需要等待请求处理结果
4:链路结构灵活,可以通过改变链路结构动态地新增或者删减责任
5:易于扩展新的请求处理类,符合开闭原则
缺点:1:责任链太长或者处理时间过长,会影响整体性能
2:如果节点对象存在循环引用时,或造成死循环,导致系统崩溃
应用场景:
源码中的应用 1:JDK j2ee Filter
2:netty 中的Pipeline ChannelHandler
3:
2:netty 中的Pipeline ChannelHandler
3:
类结构图
命令模式(Command)
定义 : 命令模式把一个请求或者操作封装到一个对象中。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。命令模式允许请求的一方和发送的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否执行,何时被执行以及是怎么被执行的。系统支持命令的撤消。
通俗理解 : 俺有一个MM家里管得特别严,没法见面,只好借助于她弟弟在我们俩之间传送信息,她对我有什么指示,就写一张纸条让她弟弟带给我。这不,她弟弟又传送过来一个COMMAND,为了感谢他,我请他吃了碗杂酱面,哪知道他说:“我同时给我姐姐三个男朋友送COMMAND,就数你最小气,才请我吃面 -> 叫你干啥就干啥
优缺点 : 1:通过引入中间件(抽象接口)姐耦了命令请求与实现;
2:扩展性能好,可以很容易的增减新命令
3:支持组合命令,支持命令队列
4:可以在现有命令的基础上,增加额外功能
2:扩展性能好,可以很容易的增减新命令
3:支持组合命令,支持命令队列
4:可以在现有命令的基础上,增加额外功能
源码中的应用 1: JDK 中的Runnable 接口, 实际上Runnable 就相当于是命令的抽象,只要是实现了Runnable接口的类都被认为是一个线程
2:junit.framework.Test接口 Test 接口中有两个方法,第一个是countTestCases()方法用来统计当前需要执行的测试用例总数
2:junit.framework.Test接口 Test 接口中有两个方法,第一个是countTestCases()方法用来统计当前需要执行的测试用例总数
类结构图
迭代器模式(Iterator)
定义 :他提供一直顺序访问集合/容器对象元素的方法,而又无序暴露集合内部表示,迭代器模式可以为不同的容器提供一致的遍历行为,
而不尬不系容器内容元素组成结构,本质是抽离集合迭代行为到迭代器中,提供一致访问接口
而不尬不系容器内容元素组成结构,本质是抽离集合迭代行为到迭代器中,提供一致访问接口
通俗理解 :按照顺序执行
优缺点 1:多态迭代:为不同的聚合接口提供一个的遍历接口,即一个迭代接口可以访问不同的集合对象
2:简化集合对象接口:迭代器模式将集合对象本身应该提供的元素迭代接口收取到了迭代器中,使集合对象无须关心具体迭代行为
3:元素迭代功能多样化:每个集合对象都可以提供一个或多个不同的迭代器,使的同种元素聚合结合可以有不同的迭代行为
4:解耦迭代与集合:迭代器模式封装了具体的迭代算法,迭代算法的变化,不会影响到集合对象的架构;
缺点:1: 对于简单的遍历,使用迭代器方式遍历变得复杂繁琐
2:日常开发中不需要写迭代器,除非我们自己定制实现的数据结构对应的迭代器,
2:简化集合对象接口:迭代器模式将集合对象本身应该提供的元素迭代接口收取到了迭代器中,使集合对象无须关心具体迭代行为
3:元素迭代功能多样化:每个集合对象都可以提供一个或多个不同的迭代器,使的同种元素聚合结合可以有不同的迭代行为
4:解耦迭代与集合:迭代器模式封装了具体的迭代算法,迭代算法的变化,不会影响到集合对象的架构;
缺点:1: 对于简单的遍历,使用迭代器方式遍历变得复杂繁琐
2:日常开发中不需要写迭代器,除非我们自己定制实现的数据结构对应的迭代器,
源码中的应用 1:JDK中的迭代源码实现 Iterator ;有两个主要的方法定义hasNext()和next()方法,
2:ArrayList中有个内部实现类 Iterator 也是有两个主要的方法 hasNext()和next()方法
2:ArrayList中有个内部实现类 Iterator 也是有两个主要的方法 hasNext()和next()方法
子主题
类结构图
备忘录模式(Memento)
定义:是指在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态,这样以后就可将对象恢复到原先保存的状态,也就是说可以 从而可以在将来合适的时候把这个对象还原到存储起来的状态。
通俗理解 : 同时跟几个MM聊天时,一定要记清楚刚才跟MM说了些什么话,不然MM发现了会不高兴的哦,幸亏我有个备忘录,刚才与哪个MM说了什么话我都拷贝一份放到备忘录里面保存,这样可以随时察看以前的记录啦
优缺点 优点:
1:简化发起人实体类职责,隔离状态存储与获取,实现了信息的封装,客户端无需关心状态的保存细节
2:提供状态回滚功能
缺点:
1:消耗资源
1:简化发起人实体类职责,隔离状态存储与获取,实现了信息的封装,客户端无需关心状态的保存细节
2:提供状态回滚功能
缺点:
1:消耗资源
源码中的应用: 很少用到这个设计模式 Spring 中的 webflow StateManageableMessageContext接口
子主题
类结构图
观察者模式(Obserber)
定义 :观察者模式定义了一种一队多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
通俗理解 :想知道咱们公司最新MM情报吗?加入公司的MM情报邮件组就行了,tom负责搜集情报,他发现的新情报不用一个一个通知我们,直接发布给邮件组,我们作为订阅者(观察者)就可以及时收到情报啦
优缺点 1:观察这和被观察这是松耦合的,符合依赖倒置原则
2:分离了表示层(观察者)和数据逻辑层(被观察者),并且建立了一套处方机制,使得数据的变化可以响应到多个表示层
3:实现了一对多的通讯机制,支持事件注册机制,支持兴趣分发机制,当被观察这触发事件时,只有感兴趣的观察者可以接受到通知
缺点:1: 如果观察者数量过多,则事件通知会号是较长、
2:如果存在依赖关系,可能导致循环调用,导致系统奔溃
3:事件通知呈线性关系,如果一个观察者卡壳,后续的时间都会有影响
2:分离了表示层(观察者)和数据逻辑层(被观察者),并且建立了一套处方机制,使得数据的变化可以响应到多个表示层
3:实现了一对多的通讯机制,支持事件注册机制,支持兴趣分发机制,当被观察这触发事件时,只有感兴趣的观察者可以接受到通知
缺点:1: 如果观察者数量过多,则事件通知会号是较长、
2:如果存在依赖关系,可能导致循环调用,导致系统奔溃
3:事件通知呈线性关系,如果一个观察者卡壳,后续的时间都会有影响
源码中的应用 ContextLoaderListener 实现了 ServletContextListener 接口,
类结构图
状态模式(State)
定义 :是运行对象在内部状态发生改变改变他的行为,对象看起来好像修改了它的类,状态模式中的类的行为有状态决定,不同的状态下有不同的行为,其意图是让一个对象在其每部改变的时候,其行为也随之改变,状态模式的核心是状态与行为绑定,不同的状态对应不同的行为,
通俗理解 跟MM交往时,一定要注意她的状态哦,在不同的状态时她的行为会有不同,比如你约她今天晚上去看电影,对你没兴趣的MM就会说“有事情啦”,对你不讨厌但还没喜欢上的MM就会说“好啊,不过可以带上我同事么?”,已经喜欢上你的MM就会说“几点钟?看完电影再去泡吧怎么样?”,当然你看电影过程中表现良好的话,也可以把MM的状态从不讨厌不喜欢变成喜欢哦
优缺点 1:结构清晰,将状态独立为类,消除了更多的if---else,使代码更加简洁,提高系统可维护性,跟策略模式的UML图几乎完全一样,但是有区别,场景不一样,策略的话是多种算法中选一种就能满足,彼此独立,用户可自行更换策略,状态的话,是各个状态之间是存在相互关系的,彼此之间在一定条件下存在自动切换状态效果,且用户无法指定状态,只能设置初始状态
2:将状态转换显示化,通常的对象每部都是使用数值类型来定义状态,状态的切换是通过复制进行表现,不够直观,而使用状态类,在切换状态时,是以不同的类进行表示。转换目的更加明确,
3:状态类职责明确且具备扩展性
缺点:1:类膨胀
2:状态模式结构与实现都较为复杂,
3:状态模式对开闭原则的支持并不太好
2:将状态转换显示化,通常的对象每部都是使用数值类型来定义状态,状态的切换是通过复制进行表现,不够直观,而使用状态类,在切换状态时,是以不同的类进行表示。转换目的更加明确,
3:状态类职责明确且具备扩展性
缺点:1:类膨胀
2:状态模式结构与实现都较为复杂,
3:状态模式对开闭原则的支持并不太好
源码中的应用 很少,一般是在业务中用到,状态顺序不能改变
类结构图
解释器模式(Interpreter)
定义 : 是指给定移门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用改表示来解释语言中的句子,是一种按照规定的预发(文法)进行解析的模式
通俗理解 : 有一个《泡MM真经》,上面有各种泡MM的攻略,比如说去吃西餐的步骤、去看电影的方法等等,跟MM约会时,只要做一个Interpreter,照着上面的脚本执行就可以了。
优缺点 优点:
1:扩展性强:在解释器模式中由于预发是由很多类表示的,当预发规则更改时,只需修改相应的非终结者表达式即可,若扩展语法时,只需要添加相应非终结符类即可
2:增加了新的解释表达式的方法
3:易于实现文法
缺点: 预发规则较为复杂是,会引起类膨胀
执行效率比较低
1:扩展性强:在解释器模式中由于预发是由很多类表示的,当预发规则更改时,只需修改相应的非终结者表达式即可,若扩展语法时,只需要添加相应非终结符类即可
2:增加了新的解释表达式的方法
3:易于实现文法
缺点: 预发规则较为复杂是,会引起类膨胀
执行效率比较低
源码中的应用 JDK中 Pattern对正则表达式的编译和解析
类结构图
子主题
访问者模式Visitor
定义 :是一直将数据结构与数据操作分离的设计模式,是指分装一些作用与某种数据结构中的各元素的操作,他可以在不改变数据结构的前提下定义作用于这些原色的新的操作,
通俗理解 :情人节到了,要给每个MM送一束鲜花和一张卡片,可是每个MM送的花都要针对她个人的特点,每张卡片也要根据个人的特点来挑,我一个人哪搞得清楚,还是找花店老板和礼品店老板做一下Visitor,让花店老板根据MM的特点选一束花,让礼品店老板也根据每个人特点选一张卡,这样就轻松多了
优缺点 1:解耦了数据结构与数据操作,使得操作集合可以独立变化
2:扩展性好,可以通过扩展访问这角色,实现对数据集的不同操作
3:元素具体类型并非单一,访问者均可操作
4:各角色职责分离,符合单一职责原则
缺点:1:无法增加元素类型
2:具体元素变得更困难
3:违背了依赖倒置原则
2:扩展性好,可以通过扩展访问这角色,实现对数据集的不同操作
3:元素具体类型并非单一,访问者均可操作
4:各角色职责分离,符合单一职责原则
缺点:1:无法增加元素类型
2:具体元素变得更困难
3:违背了依赖倒置原则
源码中的应用 JDK 的 NIO模块下的FileVisitor ,它的接口提供了递归遍历文件树的支持
类结构图
调解器模式->中介者模式(Mediator)
定义 用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示相互作用,从而使其耦合松散,而且可以独立改变他们之间的交互
通俗理解 四个MM打麻将,相互之间谁应该给谁多少钱算不清楚了,幸亏当时我在旁边,按照各自的筹码数算钱,赚了钱的从我这里拿,赔了钱的也付给我,一切就OK啦,俺得到了四个MM的电话
子主题
优缺点 1:减少类之前的依赖,将多对多依赖转化成了一对多,降低了类之间的耦合性
2:类间各司其职,符合迪米特法则
缺点:中介者模式中将原本多个对象直接的相互的依赖变成了中介者和多个同事类的依赖关系,当同事类越多时,中介者就会越臃肿,变得复杂且难以维护
2:类间各司其职,符合迪米特法则
缺点:中介者模式中将原本多个对象直接的相互的依赖变成了中介者和多个同事类的依赖关系,当同事类越多时,中介者就会越臃肿,变得复杂且难以维护
源码中的应用 JDK 中的Timerl类中有很多的schedule()重载方法
子主题
类结构图
0 条评论
下一页