`
冰糖葫芦
  • 浏览: 298317 次
社区版块
存档分类
最新评论

设计模式问答(四)

阅读更多

什么是桥接模式?

桥接模式有助于将抽象从实现中解耦。这样如果实现发生变化但是不会影响到抽象,反之亦然。如图“抽象和实现”所示,开关为抽象层,电子设备是实现;而开关可以被任何电子设备实现,因此开关是一种抽象思维而设备是实现。

图1:抽象和实现

下面我们编写开关和设备例子的代码。首先要做的事情是将实现和抽象分开到两个类总。图“实现”展示了‘IEquipment’接口,该接口包含‘Start()’和‘Stop()’两个方法。我们实现了两个设备,一个是冰箱,另一个是电灯泡。

图2:实现

第二部分是抽象。这个例子中的抽象部分是开关,它有一个‘SetEquipment’方法来设置对象;‘On’方法调用设备的‘Start’方法,‘off’调用设备的‘stop’方法。

图3:抽象

最后是客户端代码。我们之前分别创建了实现对象和抽象对象,下面我们可以单独使用他们。

图4:桥接模式客户端代码

什么是组合模式?

很多时候对象是以树形结构组织的,开发者必须去理解叶子对象和分枝对象的区别。这使得代码变得复杂,错误率提升。例如以下是一个简单的树形结构对象,消费者是主对象,每个消费者有多个地址,每个地址有多个电话对象。

图5:通常处理

我们假设想要插入完整的对象树。简单的代码示例如下,循环所有消费者、消费者中的地址对象以及所有地址中的电话对象。下面代码片段中在循环内调用了更新方法。

以上代码的问题是每个对象都需要更新。对于消费者来说是‘UpdateCustomer’、地址类为‘UpdateAddress’、电话类为‘UpdatePhone’。换句话说就是主对象和被包含的叶子对象被区别对待,这种方式会导致应用混乱增加出错几率。

如果能够统一对待主对象和叶子对象,那么代码就会变的整洁。以下代码中我们创建了一个接口(IBusinessObject),该接口限制所有类如消费者、地址、电话类使用统一的接口。统一接口以后,所有对象就都有一个“Update”方法了。

为了实现组合模式我们首先创建了一个接口,如下代码片段中所示:

强制所有根节点以及叶子节点使用该接口,如下所示:

同样,地址对象也强制实现该接口。

电话对象同理,如下所示:

什么是装饰器模式?

提示:装饰器模式增加了动态叠加行为来帮助我们在运行时改变对象的行为。

有很多情况下我们需要在运行时为一个类增加动态叠加行为。其中叠加是非常重要的词。例如,让我们考虑以下一个酒店销售面包餐的例子;他们有3个主要的产品,订单可以包含以下几种组合:

  • 简易面包

  • 面包和鸡肉

  • 面包和饮料

  • 面包和鸡肉、饮料

换句话说,订单流程的行为和订单成本在运行时的变化取决于组合的类型。

下面的例子是一个只有面包的订单,有两个函数‘prepare’和‘calculatecost’。我们将根据客户需求来在基础面包订单上动态增加新产品。

以下是所有订单的接口,每个订单都有如Prepare和CalculateCost两个功能。

基础产品是面包,实现了IOrder接口。可以在面包订单上增加新的产品并改变整个订单的行为。

我们可以使用装饰器模式动态选择面包订单。实现装饰器模式有以下5个步骤:

步骤1:创建一个装饰器类,并聚集需要动态增加行为的对象或接口

这个装饰器类将持有这些对象,所有对主对象方法的调用都要先调用所有持有对象的方法才调用主对象方法。

因此,如果调用了prepare方法,这个装饰器类将调用所有持有类的prepare方法,最后才调用该类的prepare方法。我们可以在下图看到引入装饰器类后输出结果是如何变化的。

步骤2:被持有的对象或接口指向需要初始化的类。我们可以通过多种方式实现该例子,下面我们将开放一个简单的构造函数并传递对象到该构造函数来初始化所持有对象。

步骤3:我们将实现IOrder接口并通过virtual方法调用所持有对象的方法。大家可以看到我们创建了virtual方法来调用所持有对象的方法。

步骤4:我们已经完成了重要的步骤,如创建装饰器。现在需要创建对象行为对象,这种对象可以被添加到装饰器并在运行时改变对象的行为。

以下是一个简单的鸡肉订单,该订单可以被添加到面包订单来创建出一个不同订单,叫做鸡肉+面包订单。鸡肉订单是通过继承订单装饰器类来被创建的。

任何对该对象的调用,首先要调用鸡肉订单的自定义函数,接着才调用持有对象的函数。例如当调用prepare方法时,他先调用准备鸡肉方法然后调用所持有对象的prepare方法。

花费计算也会加入鸡肉的花费,并调用所持有订单的花费来计算总额。

同理,准备订单饮料,如下所示:

步骤5:之后一步是观察装饰器模式的应用。所以在客户端我们可以写一些代码如创建一个面包订单。

以下是上面代码的输出结果:

创建一个包含有面包、鸡肉、饮料的订单代码逻辑如下:

输出结果如下:

换句话说,我们现在可以将这些行为附加到主对象之上并在运行时动态改变其行为。

以下是我们可以生成不同订单的组合,这样我们可以动态选择订单的行为。

什么是门面模式?

门面模式位于一组子系统之上并允许这些子系统以一种统一的方式交互。

图6:门面和子系统

图“订单门面”展示了门面模式的一个实例。为了下订单系统需要和产品、支付、发票类交互。所以订单成了一个门面来统一产品、支付和发票类。

图7:订单门面

图“门面模式实践”展示了类‘clsorder’通过实现‘PlaceOrder’函数来统一使用‘clsproduct’、’clsproduct’、‘clsInvoice’类。

图8:门面模式实践

什么是责任链模式(COR)?

当我们有一系列处理逻辑时使用责任链模式比较合适。下面我们来了解下这句话的意思。假设,一个请求需要一系列处理;因此请求被第一个句柄处理,他可以处理一部分或者不能处理,一旦完成,该句柄将请求传入链总的下一个处理。这种流程将一直持续直到有处理收到请求后完成处理。

图9:责任链模式概念

下面我们通过一个简单例子来了解这个概念。图“简单例子”中有一些处理逻辑,其中有3个处理将通过;也就是处理1做一些处理传给处理2,处理2做一些处理后传递给处理3来完成整个处理。

图10:简单例子

图“责任链模式类图”中,3个处理都继承自一个抽象类。其中重要的一点是每个处理点都会调用下一个需要处理的过程。所以在处理类中我们加入了一个额外的处理对象‘objProcess’,这个对象指向系一个需要被调用的处理对象。

图11:责任链模式类图

定 义好所有类以后既可以写客户端调用了。我们分别创建3个处理过程对象process1、process2、process3,使用 ‘setProcess’来定义处理对象调用链。我们将process2链接到process1之后,将process3链接到process2之后。当 链接创建完成后在运行过程中就会按照我们定义的顺序依次运行。

图12:责任链模式客户端代码

什么是代理模式?

代理模式从根本上讲就是一个表现的像接口的类指向一个拥有数据的真实类,其中的数据可以是很大的图片也可以是很大的不能被复制的对象数据。这样我们可以创建多个代理指向内存消耗较大的对象来完成操作。这避免了对象的复制从而节省了内存。所以代理就是指向真实对象的引用。

图“代理和实际对象”展示了接口与真实对象的创建。其中接口‘IImageProxy’为代理,实现类如‘clsActualImage’为真实类。在客户端代码中可以看到接口是如何指向真实对象的。

图13:代理和实际类

使用代理模式的优点是安全并且避免了大数据对象的复制;不是使用实际对象代码而是使用代理,这样避免了在客户端装载实际类的代码;而在客户端只装载代理类更安全。第二点是当有大对象时在网络或域名之间传输这些对象将非常耗内存;所以不传这些大对象而是传递代理性能会更好。

什么是模板模式?

模板模式属于行为模式。它定义了一个主要处理模板,主处理模板中还有子处理,在这个序列中调用字处理。而主处理中的子处理则可以选择产生不同的行为。

提示:模板模式的使用场景是当我们在一般化和特殊化关系之间想创建扩展行为时使用。

例如,以下是一个简单的格式化数据并存储到oracle中的例子。数据来源可以有多种,如文件、SQL server等。不考虑数据从哪来的话,整体处理流程是从数据源加载数据、解析数据、将数据存入oracle。

图14:总处理

接下来我们可以根据总的处理,通过重写‘Load’和‘Parse’字处理来创建一个CSV文件加载数据处理或者SQL server数据加载处理。

图15:模板模式处理方式

从上图中我们可以看出如何改变‘Load’和‘Parse’子出来生成CSV文件处理和SQL server处理。‘Dump’函数和子处理在整个处理中的调用方式并没改变。

实现模板模式需要以下4个步骤:

  1. 通过创建一个父抽象类来创建模板或主处理

  2. 通过定义抽象方法和函数来创建子处理

  3. 创建一个方法来定义字处理被调用的顺序。这个方法应该为正常方法,这样子类既可以重写该方法

  4. 最后创建子类来实现抽象方法或实现新的子处理流程

‘SqlServerParser’继承‘GeneralParser’并重写‘Load’和‘Parse’来实现SQL server解析。

‘FileParser’继承‘GeneralParser’并重写‘Load’和‘Parse’来实现特定文件解析

在客户端我们可以调用这两个类:

两个解析器输出结果如下:

 

1. 本文由程序员学架构翻译

2. 本文译自 http://www.codeproject.com/Articles/28402/Design-pattern-FAQ-part

3. 转载请务必注明本文出自:程序员学架构(微信号:archleaner )

4. 更多文章请扫码:

2
1
分享到:
评论

相关推荐

    设计模式问答(2)Java开发Java经验技巧共18页.p

    这个压缩包文件“设计模式问答(2)Java开发Java经验技巧共18页.pdf.zip”显然包含了关于Java开发中的设计模式及其应用的深入讨论。下面,我们将详细探讨这些设计模式以及它们在Java开发中的重要性。 1. **单例模式...

    JAVA设计模式问答题[整理].pdf

    JAVA设计模式问答题[整理].pdf

    常见UI设计模式.pdf

    ### 常见UI设计模式解析 #### 一、引言 随着互联网技术的发展与用户需求的多样化,UI设计在产品开发过程中扮演着越来越重要的角色。优秀的UI设计不仅能够提升用户体验,还能有效促进产品的市场竞争力。为了更好地...

    C++设计模式课件25_Interpreter.pdf

    从提供的文件信息中,我们可以推断该课件《C++设计模式课件25_Interpreter.pdf》是关于C++语言实现设计模式中的解释器模式(Interpreter Pattern)的一部分教学资料。文件中出现的网站***和网易云课堂是指两个在线...

    大话设计模式的源码 pdf文件在我空间免费下载

    用多个小故事或编程示例来组织讲解GoF(设计模式的经典名著——Design Patterns:Elements of Reusable Object-Oriented Software,中译本名为《设计模式——可复用面向对象软件的基础》的四位作者Erich Gamma、...

    设计模式总复习题.doc

    四、问答题 1. 设计模式是对在特定上下文中经常出现的问题的解决方案的描述,目标是提高代码的可重用性、可读性和可维护性。 2. 设计模式通常遵循的原原则包括单一职责原则、开闭原则、里氏替换原则、依赖倒置原则、...

    《JAVA设计模式》期末试题(A卷)[归纳].pdf

    《JAVA设计模式》期末试题(A卷)主要涵盖了设计模式的基础知识和应用,包括选择题、填空题、名词解释和综合问答四个部分,涉及到了多种设计模式的概念、分类、作用以及Java语言中与设计模式相关的编程原则。...

    UML设计模式笔试题.doc

    UML设计模式笔试题 UML 设计模式笔试题是 Java 程序设计的重要组成部分,本文档涵盖了 UML 设计模式、Java 基础知识、多线程编程、Struts2 框架、MVC 模式、设计模式等多方面的知识点。 一、选择题 1. UML 设计...

    智能问答机器人辅助的在线教学模式研究.pdf

    以C语言程序设计教学为例,构建教学领域的知识图谱,可以辅助智能问答机器人更有效地理解和解答课程相关问题。机器人通过对问题的分析、信息检索和答案抽取,为学生提供及时的解答。同时,通过对大量问答日志的分析...

    android 网络应用轻量框架-多线程管理-高效缓存-设计模式

    问答是happy http://blog.csdn.net/b275518834/article/details/8247685 操作方式:输入文本框设置线程数 点击第一个按钮请求10个地址信息 点击第二个按钮中断10个地址信息 1:判断当前网络环境 2:编写了3套...

    java毕业设计-课程设计-问答论坛系统

    1. **MVC设计模式**:Model-View-Controller模式是Web应用开发中常用的设计模式,它将业务逻辑、数据模型和用户界面分离,使得代码更易于维护和扩展。 2. **Servlet与JSP**:Servlet用于处理HTTP请求,JSP则用于...

    人工智能自动问答系统方案设计.pptx

    释放数据决策力 人工智能自动问答系统解决方案 人工智能自动问答系统方案设计全文共33页,当前为第1页。 目录 第一部分 人工智能大数据概览 第二部分 知识图谱技术概览 第三部分 自动问答解决方案 人工智能自动问答...

    基于springboot的问答管理系统

    2. **MVC架构**:SpringBoot支持Model-View-Controller(MVC)设计模式,用于处理Web请求。在问答系统中,模型代表数据模型,视图负责展示,控制器接收并处理用户请求,协调模型和视图的交互。 3. **Spring Data ...

    基于epoll的推送和问答模式服务器

    总结,基于epoll的服务器设计充分利用了epoll的高效特性,实现了推送和问答模式的结合,是学习网络编程和并发处理的优秀实践案例。通过理解和掌握这个项目,开发者能够更好地理解epoll的工作原理以及如何利用它构建...

    c#简易问答系统.zip

    8. 设计模式:根据系统规模和复杂度,可能会应用到设计模式,如工厂模式用于创建问题和答案对象,单例模式用于保证问答系统的全局唯一性。 9. 测试:为了确保系统功能的正确性,需要进行单元测试和集成测试。C#中的...

    前端采用vue,后端采用springboot,基于知识图谱构建的中文病症问答系统,可用于个人学习研究,毕业设计,课程设计

    前端采用vue,后端采用springboot,基于知识图谱构建的中文病症问答系统,可用于个人学习研究,毕业设计,课程设计 基于知识图谱的中文症状问答系统,前端vue.js,后端springboot 开发语言是java,运行环境是...

    java知识问答服务器

    这种设计模式是典型的C/S(客户端/服务器)架构,其中服务器端是服务的提供者,客户端是服务的消费者。 在描述中提到了“接口”,这可能是指Java中的接口(Interface)。在Java中,接口是一种完全抽象的类型,定义...

    JAVA知识问答器

    总之,【JAVA知识问答器】是一个综合运用了Java核心特性和设计模式的项目,通过它不仅可以学习到Java的基础语法,还可以深入理解面向对象设计、资源管理以及数据持久化等方面的知识。对于初学者来说,这是一个极好的...

    tipask问答系统111

    问答系统是互联网上常见的信息交流工具,它允许用户提出问题并由其他用户或专家给出回答,类似于现实生活中的一种社区互助模式。 【标签】"问答系统11111"强调了这个主题的核心——问答系统,可能是为了突出其在...

Global site tag (gtag.js) - Google Analytics