总览 这篇文章中,我们主要介绍一下结构型设计模式,以及讨论结构型设计模式中代理模式、装饰者模式、适配器模式和桥接模式有哪些及其差异点。 根据 Gang Of Four (GoF)[设计模式作者]介绍,设计模式可以分为三类,分别为创建型、结构型以及行为型。简单地说,结构模式处理类和对象的组合。 差异点: 尽管代理模式和装饰器模式具有相似的结构,但它们的意图不同; 虽然 Proxy 的主要目的是促进易用性或受控访问,但装饰者附加了额外的责任 代理模式和适配器模式都持有对原始对象的引用 装饰者模式中的所有装饰器都可以无限次递归使用 差异点: 代理提供相同的接口,而适配器提供与其客户端兼容的不同接口 在设计应用程序组件之后使用适配器模式,以便我们可以在不修改源代码的情况下使用它们。 这与在设计组件之前使用的桥接模式形成对比。 桥接模式 桥接模式用于将抽象与其实现分离,以便两者可以独立变化。 这意味着创建一个桥接接口,该接口使用 OOP 原则将职责分离到不同的抽象类中。 差异点: 桥接模式只能在设计应用程序之前实现。
有一个接口类,有一个需实现的方法,其他所有类都实现它,在一个组合类的实现方法中循环调用另外其他类的方法
代理模式主要作用是不改变原始类的情况下,通过代理类来访问原始类方法,从而对原始类方法进行增强。当然,把增强功能直接放入原始类也是可以的,但是这样不符合开闭原则,而且容易把业务代码和非业务代码耦合。 代理模式的实现有2种方式 1.代理类和原始类实现同一个接口,代码如下: public interface UserManager { //新增用户抽象方法 void addUser(String 2.如果原始类没有实现接口,这种情况下代理模式就得用继承的方式来实现了。
GOF23种设计模式中结构型模式,共七种: - 适配器模式、 - 装饰器模式、 - 代理模式、 - 外观模式、 - 桥接模式、 - 组合模式、 - 享元模式。 下面逐一讲解: 其他同系列的文章还有: 面向对象编程中的六大原则 设计模式| 创建型模式 设计模式| 结构型模式 设计模式| 行为型模式 (上) 设计模式| 行为型模式 (下) 欢迎阅读,评论!!! 关于装饰器模式写的不错的文章 3.代理模式 代理模式(Proxy Pattern)又叫委托模式属于是一个使用率非常高结构型设计模式。 外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互, 为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。 桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则”。
设计模式中的结构型模式 结构型模式 结构型模式(Structural Pattern)描述如何将类或者对 象结合在一起形成更大的结构,就像搭积木,可以通过 简单积木的组合形成复杂的 结构型模式可以分为类结构型模式和对象结构型模式: 类结构型模式关心类的组合,由多个类可以组合成一个更大的 系统,在类结构型模式中一般只存在继承关系和实现关系。 - 对象结构型模式关心类与对象的组合,通过关联关系使得在一 个类中定义另一个类的实例对象,然后通过该对象调用其方法。 根据“合成复用原则”,在系统中尽量使用关联关系来替代继 承关系,因此大部分结构型模式都是对象结构型模式。 \ 适配器模式 桥接模式 装饰模式 组合模式 外观模式 享元模式 代理模式 适配器模式 适配器模式讲解 对应代码 桥接模式 桥接模式讲解 对应代码 装饰模式 装饰模式讲解 对应代码 组合模式 组合模式讲解
门面模式(Facade) 门面模式(Facade) 介绍 门面模式(外观模式) 是一种结构型设计模式,能为程序库、框架或其他复杂类提供一个简单的接口。 优缺点 优点: 代码独立于子系统 接口隔离原则 最少知识原则(迪米特法则) 缺点: 外观可能成为与程序中所有类都耦合的上帝对象 与其他模式的关系 适配器是做接口转换,解决的是原接口和目标接口不匹配的问题 门面模式做接口整合,解决的是多接口调用带来的问题。 只需对客户端隐藏创建过程的话,可以用抽象工厂模式来代替门面模式。 一般只要一个门面,可以转换为单例。
组合模式(Composite) 组合模式(Composite) 介绍 组合模式将一组对象组织(Compose)成树形结构,以表示一种”部分-整体”的层次结构。 组合模式让客户端可以统一单个对象和组合对象的处理逻辑。 适用场景 实现树状对象结构 以相同方式处理简单或复杂的元素 ... 优缺点 优点: 可以利用多态和递归机制更方便地使用复杂树结构。 与其他模式的关系 组合模式通常和责任链模式结合使用。 可以在创建复杂组合树时使用生成器模式,可使其构造步骤以递归的方式运行。 可以使用迭代器模式来遍历组合树。 可以使用访问者模式对整个组合树执行操作。 可以使用享元模式实现组合树的共享叶节点以节省内存。 可以使用原型模式来复制大量使用组合或装饰的对象。 实现方式 声明组件接口及其一系列方法。
代理模式(Proxy) 代理模式(Proxy) 介绍 代理模式是一种结构型设计模式,让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问,并允许在将请求提交给对象前后进行一些处理。 优缺点 优点: 对客户端透明 可以进行生命周期的管理 即使对象还没准备好,代理类也可以工作 开闭原则,可以不对服务和客户端修改的情况下创建新代理 缺点: 代码变复杂 服务响应可能延迟 与其他模式的关系 后续讲到对应的模式时再写 示例 接口: public interface CommandExecutor { void runCommand(String cmd) throws Exception instance.setSomeProperty(someProperty); } } Spring Spring AOP (JDK 动态代理和 cglib 动态代理) Mybatis 利用职责链模式和动态代理模式来实现
结构型设计模式 结构型模式关注于整体最终的结构,通过继承和组合,构建出更加复杂的结构 进而提供更加强大的逻辑功能 七种结构型模式 适配器模式(Adapter Pattern) 组合模式(Composite (Flyweight Pattern) 所有的结构型设计模式在逻辑上都各自不同程度的隐含了“间接”“代理”“委托”的含义 ,有的明显,有的含蓄 ? 、不易扩展的问题 但是他们的出发点完全不同 一个关注于功能的动态扩展组合 一个关注于抽象与实现的分离,获得更多的灵活性 总结 所有的结构型模式的都离不开“分离,解耦”的概念 而“分离,解耦” (ps:上面的分离指分开的,不耦合在一起,不是特指原本是一个整体,被分成两部分) 以上各个部分的差异对比点主要根据设计模式的最初意图、动机,设计模式本就是设计原则的实现化角色 对于任何的结构 所以,除非你有更好更合适的选择,或者改变 否则,一定要尽量按照模式原本的意图和动机去使用某种模式 原文地址:结构型设计模式对比 设计模式(十六)
Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。 ? 为了实现这一点,最好的模式是facade模式。 不知何故,您最终得到了一个非常复杂的系统,该系统以各种方式生成报告。系统将报表生成为XML文件、CSV文件,甚至从数据库生成报表。
一、模式定义 外观模式:外观模式就是提供一个统一的接口,用来访问子系统的一群接口。外观模式定义了一个高层接口,让子系统更容易使用。,外观模式也称门面模式,是一种对象结构型设计模式。 ? 外观模式为客户端类提供了便捷,客户端类不需要关注子系统的设计,直接提供外观类访问就好 外观模式符合“迪米特法则”,引入一个单一简单的接口,给客户端调用,从而降低了客户端和子系统的耦合度 不过外观模式也有一些缺点 ,每一种设计模式都是有缺点和优点的,需要根据复杂的业务场景进行选用。 对于一些很复杂的业务系统来说,有时候可以设计多个外观类进行系统解耦 四、简单例子实践 JDBC数据库操作的例子,本例子来自《设计模式》一书 import java.sql.*; public class 下面简单列举一下外观模式的一些应用场景 JavaEE框架里的Session就是用了外观模式 学JSP的JDBC数据库操作也是经常用外观模式的
在上一篇文章中,我们介绍了设计模式的基本概念和分类,以及创建型模式。 根据其意图或目的,结构型模式可以分为两大类: 类结构型模式(Class Structural Pattern):类的结构型模式使用继承机制来组合多个类,以实现一个新功能的组合。 根据“合成复用原则”,系统中要尽量使用关联关系来取代继承关系,因此大部分结构型设计模式都属于对象结构型设计模式。 下面我们来看看每一类中包含哪些具体的设计模式,并举一些简单的例子来说明它们的作用。 这个适配器就是适配器模式的一个应用。 对象结构型模式 对象结构型模式包括以下六种: 桥接模式(Bridge Pattern):将抽象部分与实现部分分离,使它们都可以独立地变化。 你可以使用享元模式,将字符对象设计成享元类,使得相同的字符对象可以被共享使用。这样就可以减少对象的数量,节省内存空间。
booking = new DoubleRoomBooking(); //继承装饰器的可以一层层套 booking = new WiFi(booking); booking = new ExtraBed(
文章目录 模式意图 模式定义 模式角色 模式分析 实际例子 模式应用 模式意图 介绍模式定义定义之前先介绍一下组合模式的意图。 模式定义 组合模式(Composite Pattern):组合多个对象形成树形结构来表示“整体-部分”的结构层次。 组合模式又称“整体-部分”(Part-Whole)模式,属于对象结构型的设计模式。 组合模式对单个对象和组合对象或者说容器对象的使用具有一致性。 模式角色 组合模式包括如下角色: Component:抽象构件 Leaf:叶子构件 Composite:容器构件 Client:客户类 模式分析 组合模式定义一个抽象的构件类,主要用于被客户端调用,客户调调用时就不需要关心是单个对象还是容器对象了 实际例子 例子来自:《设计模式》一书 抽象构件类: public abstract class Component { public abstract void add(Component c);
文章目录 结构型模式 概述 Case Code ---- 结构型模式 结构型模式主要是解决如何将对象和类组装成较大的结构, 并同时保持结构的灵活和⾼效。 结构型模式包括:适配器、桥接、组合、装饰器、外观、享元、代理,这7类 ---- 概述 代理模式有点像⽼⼤和⼩弟,也有点像分销商。 ⽽这种设计思想的模式经常会出现在我们的系统中,或者你⽤到过的组件中,它们都提供给你⼀种⾮常简单易⽤的⽅式控制原本你需要编写很多代码的进⾏使⽤的服务类。 对于Mybatis的使⽤中只需要定义接⼝不需要写实现类就可以完成增删改查操作,解析下来我们会通过实现⼀个这样的代理类交给spring管理的核⼼过程,来讲述代理类模式。 接下来会使⽤代理类模式来模拟实现⼀个Mybatis中对类的代理过程,也就是只需要定义接⼝,就可以关联到⽅法注解中的 sql 语句完成对数据库的操作。
装饰器模式(Decorator) 装饰器模式(Decorator) 介绍 装饰模式是一种结构型设计模式,允许通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承。它主要的作用是给原始类添加增强功能。 适用场景 无需修改代码的情况下给原始类添加增强功能。 类继承结构复杂、组合爆炸的情况下。 与其他模式的关系 装饰模式和代理模式有着相似的结构,但是其意图却非常不同。这两个模式的构建都基于组合原则,也就是说一个对象应该将部分工作委派给另一个对象。 ---- 示例 装饰器 // 代理模式的代码结构(下面的接口也可以替换成抽象类) public interface IA { void f(); } public class A implements { delegate.removeObject(eldestKey); eldestKey = null; } } } 注:本篇实例部分的代码引用自王争老师的《设计模式之美
享元模式(Flyweight) 享元模式(Flyweight) 介绍 享元模式是一种结构型设计模式。 享元模式顾名思义就是被共享的单元,意图是复用对象,节省内存。 适用场景 存在大量重复对象(重复状态)且没有足够的内存容量时使用享元模式。 ... 优缺点 优点: 节省大量内存。 缺点: 代码复杂度提升。 与其他模式的关系 可以使用享元模式实现组合模式树的共享叶节点以节省内存。 如果能将对象的所有共享状态简化为一个享元对象,那么享元就和单例类似了。但这两个模式有两个根本性的不同。 省略 } java.lang.String String 类利用享元模式来复用相同的字符串常量。 JVM 会专门开辟一块存储区来存储字符串常量,这块存储区叫作“字符串常量池”。
设计模式六大原则 适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式 适配器模式: 将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由某个接口不匹配所造成的类的兼容性问题 类的适配器模式,对象的适配器模式,接口的适配器模式。 类的适配器模式 :可以通过多重继承目标接口和被适配者方法来实现适配。 接口的适配器模式:当不需要全部接口实现方法时候,可设计一个抽象类实现接口,并为该接口每个方法提供默认的实现方法,那么该抽象子类可以有选择的覆盖父类某些方法来实现,它使用接口不想使用所有方法的情况。 桥接模式 定义:将抽象部分与它的实现部分分离,使他们可以独立变化。 组合模式 又叫做部分-整体模式,将对象组合成树状的层次结构模式,表示部分-整体的关系,使用户对单个对象和组合对象具有一定访问一致性。
文章目录 结构型模式 概述 Case Bad Impl Better Impl 小结 ---- 结构型模式 结构型模式主要是解决如何将对象和类组装成较大的结构, 并同时保持结构的灵活和⾼效。 结构型模式包括:适配器、桥接、组合、装饰器、外观、享元、代理,这7类 ---- 概述 设计模式是解决程序中不合理、不易于扩展、不易于维护的问题,也是⼲掉⼤部分 ifelse 的利器,在我们常⽤的框架中基本都会 ⽤到⼤量的设计模式来构建组件,这样也能⽅便框架的升级和功能的扩展。 但如果不能合理的设计以及乱⽤设计模式,会导致整个编程变得更加复杂难维护,也就是我们常说的: 反设计 、 过渡设计 。 因⽽使⽤设计模式来让代码结构更加⼲净整洁。
设计模式-结构型模式-装饰模式 栗子 以成绩单需要家长签字为要求。 SchoolReport{ // 自己的成绩单 public void report(){ } // 家长签名 public void sign(String name){ } } 使用装饰器模式 使用装饰器模式,对成绩单进行装饰。 动态改变函数参数,原先有一个正常的函数,通过装饰器,将正常的函数传入,装饰模式 应用ajax加token防止csrf攻击 表单验证,将表单验证的内容,写成一个类,然后需要哪个验证的选项,直接将表单验证传入即可