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

设计模式问答(三)

阅读更多

什么是状态模式?

状态模式允许一个对象根据当前对象的值来决定其行为。如下图“状态模式示例”是一个关于电灯泡操作的例子。如果电灯的状态为关,当按下开关时状态将打开;如果开关为开,则按下开关灯关闭。简而言之,根据不同的状态行为会发生变化。

图1:状态模式示例

下 面我们尝试使用C#实现该示例。图“状态模式实践”展示了业务类和客户端代码。我们创建了一个类‘clsState’,该类包含有两个状态“On”和 “Off”枚举;还定义了‘PressSwitch’方法,它根据当前状态来切换状态。在图右半部分我们实现了使用类‘clsState’的客户端来调用 ‘PressSwitch方法,并使用‘getStatus’方法将当前状态显示在文本框中。

当我们点击后会来回切换当前状态。

图2:状态模式实践

什么是策略模式?

策略模式在类中封装了算法,可以根据所使用的类来互换。当我们想在运行时决定使用哪个算法时这种模式非常有用。

下 面来看一个策略模式工作原理的例子。我们以数学运算中的加、减为例,图“策略模式实践”展示了该逻辑。它接收连个数字作为参数,根据不同的策略给出不同的 结果。因此,如果使用的是加法策略,那么两个数字会被相加;如果使用的是减法策略,那么两个数字将被相减。这些策略仅仅是算法。策略模式也仅仅是对算法的 封装。

图3:策略模式实践

首 先我们需要知道的是这些算法是如何被封装到类中的。下图“算法封装”展示了“add”算法是如何被封装到‘clsAddStatergy’类、 ‘substract’算法是如何被封装到‘clsSubstractStatergy’类中的;而这些类都继承自‘clsStratergy’类,该类 为子类提供了一个‘calculate’方法。

图4:算法封装

接着定义包装类‘clsMaths’来引用‘clsStatergy’类,并通过‘setStatergy’来设置需要使用的策略类。

图5:策略类及其包装类

下图“策略模式调用代码”展示了包装类的用法以及在运行时通过‘setStatergy’方法设置策略。

图6:策略模式调用代码

什么是访问者模式?

访问者模式允许在不改变实际类的情况下修改类结构。它是一种将逻辑和算法从当前出具结构中分离开来的方式。基于这种方式我们可以在不修改结构的情况下来为当前数据增加新的逻辑;另一方面,我们可以在不接触逻辑的情况下修改数据结构。

下 图“逻辑和数据结构”包含了一个消费者数据结构,每个消费者对象都有多个地址对象,每个地址对象又有多个电话对象。这个数据结构需要以两种不同的格式展 示:String、XML。因此我们需要写两个类其中一个是String相关逻辑的类,另一个是XML逻辑相关的类。这两个类遍历对象结构并给出相应的输 出。简而言之,访问者包含了逻辑。

图7:逻辑和数据结构

接着我们用C#来实现上面例子。其他编程语言同理。我们创建了连个访问者类来分别解析string逻辑和xml。这两个类都有一个visit方法来解析相应对象。为了保持统一这些类都实现了一个‘IVisitor’通用接口。

图8:访问者类

之前定义的访问者类将被传递给数据结构类,如消费者类。所以,在消费者类中,我们在‘Accept’函数中传入访问者类。在该方法中我们通过传递这种访问者类的类型来调用visit方法;同时visit方法做了重载,因此它将根据所传递的参数类的类型来决定调用哪个方法。

图9:传递访问者类到数据结构

由 于每个消费者都有多个地址,每个地址都有多个电话对象,因此在‘clsCustomer’类中集成有‘objAddresses’集合,而在 ‘clsAddress’类中则集成有‘objPhones’集合。每个对象都有accept方法并持有访问者类对象并在访问者类中的visit方法中解 析自己。由于visit方法的经过重载,所以它将多态的调用适当的方法。

图10:消费者、地址、电话对象

现 在我们定义好了访问者类的逻辑和消费者类的内部数据结构,接着可以在客户端使用它们了。下图“访问者模式客户端代码”展示了使用访问者模式的代码快照。首 先创建访问者对象并将其传递给消费者数据类;如果我们想要以字符串形式展示消费者对象数据结构,那么就创建‘clsVisitorString’,如果想 以xml格式展示,则需创建‘clsXML’对象并将其传递到消费者对象数据结构中。从数据结构中我们可以很容易明白该逻辑。

图11:访问者模式客户端代码

访问者模式和策略模式的区别?

访 问者模式和策略模式看起来非常相似,因为它们都是从数据中封装负责逻辑。可以说访问者模式是策略模式的通用形式。在策略模式中,在多个算法之上有一个上下 文或者单一的逻辑数据对象。在前一个问题中我们解释了策略模式和访问者模式的基本原理,那么让我们再次看下之前已经理解的例子。在策略模式中有一个单一的 上下文类和多个算法。图“策略模式”展示该上下文类和多个算法之间是如何协调工作的。

图12:策略模式

访问者模式有多个上下文对象,每个上下文对象都包含有一个算法。在访问者模式的例子中我们写过解析数据的例子如消费者、地址、电话对象。

图13:访问者模式

因 此,简而言之策略模式是访问者模式的特殊形式。在策略模式中,所有的算法只有一个上下文而访问者模式则每个算法对象都有一个上下文。所以对于选择使用策略 模式还是访问者模式的基本标准就是上下文和算法之间的关系。如果需要一个上下文、多个算法,那么就选择策略模式;如果有多个上下文和算法就选择使用访问者 模式。

什么是适配器模式?

很 多时候两个类由于继承自不兼容的接口而变得不兼容。适配器模式帮助我们来包装已存在的类使得两个类变得互相兼容。下图“不兼容接口”中两个集合都持有一个 string值;它们都有一个方法来增加一个字符串到集合中;其中一个方法是‘Add’另一个是‘Push’;一个使用的集合对象而另一个使用的栈。我们 想要使栈对象和集合对象兼容。

图14:不兼容接口

有两种方法实现适配器模式,一种是聚合(这种方式称为对象适配器模式),另一种是继承(这种方式称为类适配器模式)。首先我们来看看对象适配器模式。

下图“对象适配器模式”展示了一个广泛的实现方式。该例子中我们引入了一个新的包装类‘clsCollectionAdapter’,该类包装了‘clsStack’类并且将push方法包含在add方法之中,这样使得两个类变得兼容。

图15:对象适配器模式

另一种方式是使用继承来实现适配器模式,也叫类适配器模式。图“类适配器模式”展示了类‘clsStack’如何通过继承‘clsCollectionAdapter’使得兼容‘clsCollection’类。

图16:类适配模式

什么是享元模式?

当 我们需要创建很多对象并且这些对象都共用一种数据时享元模式非常有用。下图“对象和共用数据”中,我们需要为组织中所有员工打印名片,这样我们有两部分数 据一种是可变数据如员工名称,另一个部分是静态数据如地址。通过只保留一份静态数据并使所有可变对象引用该地址这种方式,可以使内存使用最小化。因此我们 创建不同的可变数据但是都引用同一份静态数据,这样可以优化对内存的使用。

图17:对象和通用数据

以 下是享元模式的一个C#代码实例。其中有两个类:‘clsVariableAddress’来保存动态数据,‘clsAddress’来保存静态数据;为 了确保‘clsAddress’类只有一个实例,我们创建了一个包装类‘clsStatic’以及‘clsAddress’类的静态实例。这个类聚合了 ‘clsVariableAddress’类。

图18:享元模式类图

下图“享元模式客户端代码”中我们创建了‘clsVariableAddress’类的两个对象,但是内部的静态数据如地址类则只有一个实例。

图19:享元模式客户端代码

 

 

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

2. 本文译自 http://www.codeproject.com/Articles/28384/Design-pattern-FAQ-Part-Design-pattern-training

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

4. 更多文章请扫码:

2
0
分享到:
评论

相关推荐

    设计模式问答(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

    设计模式被分为三个主要类别,包括创建型模式、结构型模式和行为型模式。创建型模式包括单例、工厂、建造者等模式;结构型模式包括适配器、装饰器、代理等模式;行为型模式包括模板方法、观察者、策略等模式。 2. ...

    设计模式总复习题.doc

    设计模式是软件工程中的一种重要概念,用于解决在软件设计中常见的问题,提供了一套可重用的解决方案。设计模式的出现使得开发者能够更高效地编写可维护、可扩展的代码,遵循一定的设计原则,提高代码质量。以下是...

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

    本书的特色是通过小菜与大鸟的趣味问答,在讲解程序的不断重构和演变过程中,把设计模式的学习门槛降低,让初学者可以更加容易地理解——为什么这样设计才是好的?是怎样想到这样设计的?以达到不但授之以“鱼”,还...

    UML设计模式笔试题.doc

    三、问答题 1. 开-闭原则是指软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着,我们可以在不修改软件实体的基础上添加新的功能。 知识点:软件设计的开-闭原则。 2. 抽象工厂模式是一种创建型...

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

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

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

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

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

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

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

    目录 第一部分 人工智能大数据概览 第二部分 知识图谱技术概览 第三部分 自动问答解决方案 人工智能自动问答系统方案设计全文共33页,当前为第2页。 我国的大数据+人工智能战略 国外 2016年初,AlphaGo在围棋领域...

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

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

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

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

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

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

    基于springboot的问答管理系统

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

    c#简易问答系统.zip

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

    基于PHP的问答系统v3.7(超赞得ASK2在线问答解惑系统网站源码).zip

    2. **MVC架构**:问答系统通常采用Model-View-Controller(MVC)设计模式,将业务逻辑(Model)、数据展示(View)和用户交互(Controller)分离,提高了代码的可维护性和可扩展性。在这个系统中,PHP类库可能被用来...

    java知识问答服务器

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

    JAVA知识问答器

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

    仿360问答源码 完整可运营问答社区系统源码

    这套源码使用了ThinkPHP框架作为核心开发工具,这是一款国内广泛使用的轻量级PHP框架,以其MVC(Model-View-Controller)模式、简洁的API设计和丰富的插件系统而受到开发者喜爱。 源码中的会员等级和积分系统是构建...

Global site tag (gtag.js) - Google Analytics