(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
常用设计模式总结
最新推荐文章于 2024-07-10 17:49:48 发布