常用设计模式总结

(1)装饰者模式
定义:装饰者模式(Decorator Pattern)是指在不改变原有对象的基础之上,将功能附加到对
象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。


使用场景:
装饰者在代码程序中适用于以下场景:
     1、用于扩展一个类的功能或给一个类添加附加职责。
     2、动态的给一个对象添加功能,这些功能可以再动态的撤销。


例子:
来看一个这样的场景,上班族白领其实大多有睡懒觉的习惯,每天早上上班都是踩点,
于是很多小伙伴为了多赖一会儿床都不吃早餐。那么,也有些小伙伴可能在上班路上碰
到卖煎饼的路边摊,都会顺带一个到公司茶水间吃早餐。卖煎饼的大姐可以给你的煎饼
加鸡蛋,也可以加香肠


装饰者模式的优缺点
优点:
1、装饰者是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象
扩展功能,即插即用。
2、通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。
3、装饰者完全遵守开闭原则。
缺点:
1、会出现更多的代码,更多的类,增加程序复杂性。
2、动态装饰时,多层装饰时会更复杂。
那么装饰者模式我们就讲解到这里,希望小伙伴们认真体会,加深理解


代码地址:https://github.com/madongyu555666/design-pattern-ma/tree/master/decorator-observer-pattern


(2)观察者模式
定义:观察者模式(Observer Pattern)定义了对象之间的一对多依赖,让多个观察者对象同
     时监听一个主体对象,当主体对象发生变化时,它的所有依赖者(观察者)都会收到通
     知并更新,属于行为型模式。观察者模式有时也叫做发布订阅模式。


使用场景:
微信朋友圈动态通知、邮件通知、广播通知


观察者模式的优缺点
优点:
1、观察者和被观察者之间建立了一个抽象的耦合。
2、观察者模式支持广播通信。
缺点:
1、观察者之间有过多的细节依赖、提高时间消耗及程序的复杂度。
2、使用要得当,要避免循环调用。


代码地址:https://github.com/madongyu555666/design-pattern-ma/tree/master/decorator-observer-pattern


(3)模板模式
定义:模板模式通常又叫模板方法模式(Template Method Pattern)是指定义一个算法的骨
   架,并允许子类为一个或者多个步骤提供实现。模板方法使得子类可以在不改变算法结
   构的情况下,重新定义算法的某些步骤,属于行为性设计模式。


应用场景:
1、一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2、各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码重复


例子:比如入职流程,离职流程等


模板模式的优缺点
优点:
1、利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。
2、将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。
3、把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则。
缺点:
1、类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加。
2、类数量的增加,间接地增加了系统实现的复杂度。
3、继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。
模板方法模式比较简单,相信小伙伴们肯定能学会,也肯定能理解好!只要勤加练习,
多结合业务场景思考问题,就能够把模板方法模式运用好。


代码地址:https://github.com/madongyu555666/design-pattern-ma/tree/master/template-adapter-pattern


(4)适配器模式
定义:适配器模式(Adapter Pattern)是指将一个类的接口转换成客户期望的另一个接口,使
   原本的接口不兼容的类可以一起工作,属于结构型设计模式


业务场景:
1、已经存在的类,它的方法和需求不匹配(方法结果相同或相似)的情况。
2、适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不
同厂家造成功能类似而接口不相同情况下的解决方案。有点亡羊补牢的感觉。


例子:生活中也非常的应用场景,例如电源插转换头、手机充电转换头、显示器转接头。


适配器模式的优缺点
优点:
1、能提高类的透明性和复用,现有的类复用但不需要改变。
2、目标类和适配器类解耦,提高程序的扩展性。
3、在很多业务场景中符合开闭原则。
缺点:
1、适配器编写过程需要全面考虑,可能会增加系统的复杂性。
2、增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱


代码地址:https://github.com/madongyu555666/design-pattern-ma/tree/master/template-adapter-pattern


(5)委派模式
定义:委派模式不属于 GOF23 种设计模式中。委派模式(Delegate Pattern)的基本作用就是
   负责任务的调用和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理
   的全权代理,但是代理模式注重过程,而委派模式注重结果


应用场景:
委派模式在 Spring 中应用
非常多,大家常用的 DispatcherServlet 其实就是用到了委派模式


例子:
老板(Boss)给项目经理(Leader)下达任务,项目经理会根据
实际情况给每个员工派发工作任务,待员工把工作任务完成之后,再由项目经理汇报工
作进度和结果给老板。


代码地址:https://github.com/madongyu555666/design-pattern-ma/tree/master/delegate-strategy-pattern


(6)策略模式

定义:
策略模式(Strategy Pattern)是指定义了算法家族、分别封装起来,让它们之间可以互
相替换,此模式让算法的变化不会影响到使用算法的用户。

应用场景:
1、假如系统中有很多类,而他们的区别仅仅在于他们的行为不同。
2、一个系统需要动态地在几种算法中选择一种


例子:对接支付:支付宝,微信,银联等
     对接push: apns,华为,小米,魅族,viov等

策略模式的优缺点
优点:
1、策略模式符合开闭原则。
2、避免使用多重条件转移语句,如 if...else...语句、switch 语句
3、使用策略模式可以提高算法的保密性和安全性。
缺点:
1、客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
2、代码中会产生非常多策略类,增加维护难度

代码地址:https://github.com/madongyu555666/design-pattern-ma/tree/master/delegate-strategy-pattern

(7)代理模式
定义:代理模式(Proxy
   Pattern)的定义也非常简单,是指为其他对象提供一种代理,以控制对这个对象的访问。
   代理对象在客服端和目标对象之间起到中介作用,代理模式属于结构型设计模式。


例子:租房中介、售票黄牛、婚介、经纪人、快递、
     事务代理、非侵入式日志监听等



CGLib 和 JDK 动态代理对比
1.JDK 动态代理是实现了被代理对象的接口,CGLib 是继承了被代理对象。
2.JDK 和 CGLib 都是在运行期生成字节码,JDK 是直接写 Class 字节码,CGLib 使用 ASM
框架写 Class 字节码,Cglib 代理实现更复杂,生成代理类比 JDK 效率低。
3.JDK 调用代理方法,是通过反射机制调用,CGLib 是通过 FastClass 机制直接调用方法,
CGLib 执行效率更高。


代理模式的优缺点
使用代理模式具有以下几个优点:
1、代理模式能将代理对象与真实被调用的目标对象分离。
2、一定程度上降低了系统的耦合度,扩展性好。
3、可以起到保护目标对象的作用。
4、可以对目标对象的功能增强。
当然,代理模式也是有缺点的:
1、代理模式会造成系统设计中类的数量增加。
2、在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢。
3、增加了系统的复杂度。


高仿真 JDK Proxy 手写实现
不仅知其然,还得知其所以然。既然 JDK Proxy 功能如此强大,那么它是如何实现的呢?
我们现在来探究一下原理,并模仿 JDK Proxy 自己动手写一个属于自己的动态代理。
我们都知道 JDK Proxy 采用字节重组,重新生的对象来替代原始的对象以达到动态代理
的目的。JDK Proxy 生成对象的步骤如下:
1、拿到被代理对象的引用,并且获取到它的所有的接口,反射获取。
2、JDK Proxy 类重新生成一个新的类、同时新的类要实现被代理类所有实现的所有的接
口。
3、动态生成 Java 代码,把新加的业务逻辑方法由一定的逻辑代码去调用(在代码中体
现)。
4、编译新生成的 Java 代码.class。
5、再重新加载到 JVM 中运行


代码地址:https://github.com/madongyu555666/design-pattern-ma/tree/master/proxy-pattern


(8)原型模式()

定义:原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些
   原型创建新的对象


原型模式主要适用于以下场景:
1、类初始化消耗资源较多。
2、new 产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)
3、构造函数比较复杂。
4、循环体中生产大量对象时。

简单克隆
复制的不是值,而是引用的地址。

深度克隆
创建新的对象,不同的地址

例子:set,get


(9)单例模式
定义:单例模式(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并
   提供一个全局访问点。单例模式是创建型模式。

应用场景:
国家主席、公司 CEO、部门经理等。在 J2EE 标准中,ServletContext、
ServletContextConfig 等;在 Spring 框架应用中 ApplicationContext;数据库的连接
池也都是单例形式。


饿汉式单例
饿汉式单例是在类加载的时候就立即初始化,并且创建单例对象。绝对线程安全,在线
程还没出现以前就是实例化了,不可能存在访问安全问题。
优点:没有加任何的锁、执行效率比较高,在用户体验上来说,比懒汉式更好。
缺点:类加载的时候就初始化,不管用与不用都占着空间,浪费了内存,有可能占着茅
坑不拉屎。


懒汉式单例
懒汉式单例的特点是:被外部类调用的时候内部类才会加载


注册式单例
注册式单例又称为登记式单例,就是将每一个实例都登记到某一个地方,使用唯一的标
识获取实例。注册式单例有两种写法:一种为容器缓存,一种为枚举登记。


ThreadLocal 线程单例
线程单例实现 ThreadLocal。ThreadLocal 不能保证其
创建的对象是全局唯一,但是能保证在单个线程中是唯一的,天生的线程安全


单例模式小结
单例模式可以保证内存里只有一个实例,减少了内存开销;可以避免对资源的多重占用。
单例模式看起来非常简单,实现起来其实也非常简单。但是在面试中却是一个高频面试
题。

地址:https://github.com/madongyu555666/design-pattern-ma/tree/master/singleton-pattern

(10)工厂模式

定义:
简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类
   的实例,但它不属于 GOF,23 种设计模式

工厂方法模式(Fatory Method Pattern)是指定义一个创建对象的接口,但让实现这个
接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。在工厂方法
模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符
合开闭原则。

工厂方法适用于以下场景:
1、创建对象需要大量重复的代码。
2、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
3、一个类通过其子类来指定创建哪个对象。
工厂方法也有缺点:
1、类的个数容易过多,增加复杂度。
2、增加了系统的抽象性和理解难度。



抽象工厂模式
抽象工厂模式(Abastract Factory Pattern)是指提供一个创建一系列相关或相互依赖
对象的接口,无须指定他们具体的类。客户端(应用层)不依赖于产品类实例如何被创
建、实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对
象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从
而使客户端不依赖于具体实现。

抽象工厂缺点的:
1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂
的接口。
2、增加了系统的抽象性和理解难度。
但在实际应用中,我们千万不能犯强迫症甚至有洁癖。在实际需求中产品等级结构升级
是非常正常的一件事情。我们可以根据实际情况,只要不是频繁升级,可以不遵循开闭
原则。

地址:https://github.com/madongyu555666/design-pattern-ma/tree/master/factory-pattern

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值