探索软件设计模式 2017年2月23日 下午5:17 • 软件开发 探索软件设计模式 创建型模式 抽象工厂(Abstract Factory)举例 抽象工厂的目的是要提供一个创建一系列相关或相互依赖对象的接口,而不需要指定它们具体的类。这种模式可以在日本汽车制造厂所使用的金属冲压设备中找到。这种冲压设备可以制造汽车车身部件。同样的机械用于冲压不同的车型的右边车门、左边车门、右前挡泥板、左前挡泥板和引擎罩等等。通过使用转轮来改变冲压盘,这个机械产生的具体类可以在三分钟内改变。 图2:使用儿童餐作为例子的生成器模式的对象作用表 工厂方法(Factory Method) 工厂方法定义一个用于创建对象的接口,但是让子类决定实例化哪个类。压注成型演示了这种模式。塑料玩具制造商加工塑料粉,将塑料注入到希望形状的模具中。玩具的类别(车,人物等等)是由模具决定的。 图3:使用注入成型为例子的工厂方法的对象图 原型(Prototype)举例 原型模式使用原型实例指定创建对象的种类。新产品的原型通常是先于全部产品建立的,这样的原型是被动的,并不参与复制它自己。一个细胞的有丝分裂,产生两个同样的细胞,是一个扮演主动角色复制自己原型的例子,这演示了原型模式。一个细胞分裂,产生两个同样基因型的细胞。换句话说,细胞克隆了自己。 图4:使用细胞分裂例子的原型模式对象图 单件(Singleton)举例 单件模式确保一个类仅有一个实例,并提供一个访问它的全局访问点。单件模式是模仿单集命名的,单集的定义是每个集合仅含有一个元素。美国总统的职位是单件,美国宪法规定了总统的选举,任期以及继任的顺序。这样,在任何时刻只能由一个现任的总统。无论现任总统的身份为何,其头衔”美利坚美利坚合众国总统”是访问这个职位的人的一个全局的访问点。 图5:使用总统例子的单件模式对象图 结构性模式 适配器(Adapter)举例 适配器模式允许将一个类的接口转换成客户期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。扳手提供了一个适配器的例子。一个孔套在棘齿上,棘齿的每个边的尺寸是相同的。在美国典型的边长为1/2”和1/4”。显然,如果不使用一个适配器的话,1/2”的棘齿不能适合1/4”的孔。一个1/2”至1/4”的适配器具有一个1/2”的阴槽来套上一个1/2”的齿,同时有一个1/4的阳槽来卡入1/4”的扳手。 图6:使用扳手适配器例子的适配器对象图 桥接(Bridge)举例 桥接模式将抽象部分与它的实现分离,使它们能够独立地变化。一个普通的开关控制的电灯、电风扇等等,都是桥接的例子。开关的目的是将设备打开或关闭。实际的开关可以是简单的双刀拉链开关,也可以是调光开关。 图7:使用电子开关例子的桥接对象图 组合(Composite)例子 组合模式将对象组合成树形结构以表示”部分-整体”的层次结构。让用户一致地使用单个对象和组合对象。虽然例子抽象一些,但是算术表达式确实是组合的例子。算术表达式包括操作数、操作符和另一个操作数。操作数可以是数字,也可以是另一个表达式。这样,2+3和(2+3)+(4*6)都是合法的表达式。 图8:使用算术表达式例子的组合模式对象图 装饰(Decorator)举例 装饰模式动态地给一个对象添加额外的职责。不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。 图9:使用有画框的画作为例子的装饰模式对象图 外观(Facade)举例 外观模式为子系统中的接口定义了一个统一的更高层次的界面,以便于使用。当消费者按照目录采购时,则体现了一个外观模式。消费者拨打一个 码与客服代表联系,客服代表则扮演了这个”外观”,他包含了与订货部、收银部和送货部的接口。 图10:使用电话订货例子的外观模式对象图 享元(Flyweight)举例 享元模式使用共享技术有效地支持大量细粒度的对象。公共交换电话 (PSTN)是享元的一个例子。有一些资源例如拨 音发生器、振铃发生器和拨 接收器是必须由所有用户共享的。当一个用户拿起听筒打电话时,他不需要知道使用了多少资源。对于用户而言所有的事情就是有拨 音,拨打 码,拨通电话。 图11:使用拨 音发生器例子的享元模式对象图 代理(Proxy)模式 代理模式提供一个中介以控制对这个对象的访问。一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账 上资金的控制。 图12:使用银行存单例子的代理模式对象图 行为模式 职责链(Chain of Responsibility)举例 职责链模式使得多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。机械硬币分拣银行使用职责链。这里并不是为每一种硬币分配一个滑槽,而是仅使用一个滑槽。当硬币落下时,硬币被银行内部的机械导向至适当的接收盒。 图13:使用硬币分拣例子的职责链模式对象图 命令(Command)模式 命令模式将一个请求封装为一个对象,从而使你可以使用不同的请求对客户进行参数化。用餐时的账单是命令模式的一个例子。服务员接受顾客的点单,把它记在账单上封装。这个点单被排队等待烹饪。注意这里的”账单”是不依赖于菜单的,它可以被不同的顾客使用,因此它可以添入不同的点单项目。 解释器(Interpreter)举例 解释器模式定义了特定语言的文法表示和解释该文法的解释器。音乐家是解释器的例子。音阶和它的持续时间可以用五线谱上的符 表示。这些符 就是音乐语言[14]。音乐家按照乐谱演奏,就可以反复重现同样的音乐。 迭代器(Iterator)举例 迭代器提供一种方法顺序访问一个集合对象中各个元素,而又不需要暴露该对象的内部表示。在早期的电视机中,一个拨盘用来改变频道。当改变频道时,需要手工转动拨盘移过每一个频道,而不论这个频道是否有信 。现在的电视机,使用[后一个]和[前一个]按钮。当按下[后一个]按钮时,将切换到下一个预置的频道。想象一下在陌生的城市中的旅店中看电视。当改变频道时,重要的不是几频道,而是节目内容。如果对一个频道的节目不感兴趣,那么可以换下一个频道,而不需要知道它是几频道。 中介者(Mediator)举例 中介者模式用一个中介对象来控制一系列的对象交互。通过中介者实现各个对象之间的松散耦合,而不是彼此直接作用。机场的控制塔很好地演示了这种模式。降落或者起飞的飞机直接与塔台通讯,而不是彼此间直接通讯。谁可以起飞或降落是由塔台决定的。这里需要注意的是塔台并不控制整个飞行过程。它只负责飞机在机场附近的区域。 图17:使用训练中心为例子的中介者模式 备忘录(Memento)举例 备忘录模式捕获并且在外部保存一个对象的内部状态,使得以后可以将对象恢复到该状态。这种模式通常体现在你自己修理汽车的刹车时。首先移开两边的挡板,露出左右刹车片。只能卸下一片,这时另一片作为一个备忘录来表明刹车是怎样安装的。在这片修理完成后,才可以卸下另一片。当第二片卸下时,第一片就成了备忘录。 观察者(Observer)模式 观察者定义了对象间一对多的关系,当一个对象的状态变化时,所有依赖它的对象都得到通知并且自动地更新。拍卖演示了这种模式。每个投标人都有一个标有数字的牌子用于出价。拍卖师开始拍卖时,他观察是否有牌子举起出价。每次接受一个新的出价都改变了拍卖的当前价格,并且广播给所有的投标人进行新的出价。 状态(State)模式 状态模式允许一个对象在其内部状态改变时改变它的行为。这种模式可以在自动售货机上观察到。自动售货机的状态包括列商品清单,收款,找钱和选择商品等几种状态。当投入硬币并选择了一个商品时,自动售货机可以完成以下几种操作,包括:送出商品不找钱、送出商品并找钱、由于投币不足不送出商品、由于商品售完不送出商品。 策略(Strategy)模式 策略模式定义了一系列可以相互替换的算法。不同的到飞机场去的方式就是一个策略模式的例子。有几种选择:自己开车、坐出租车、乘机场班车、乘公共汽车或使用专车服务等等。对于某些机场,地铁和直升机也是可能的选择。任何一种方式都可以把你送到机场,它们可以相互代替。你必须根据价格、便利性和时间做出选择。 模板方法(Template Method)举例 访问者(Visitor)举例 访问者模式表示一个作用于对象结构中各元素的操作,定义这个操作并不会改变元素的类。这种模式可以在出租车公司的运转中观察到。当一个人给出租车公司打电话时,他(她)就成了公司所有顾客的一员。然后公司指定一辆车去服务(接受访问者)。在进入出租车之后,这个人(访问者)就不再控制他(她)的旅程了,而是由出租车(驾驶员)负责。 意义 软件设计模式有许多非软件的例子存在。也许有人想知道这些例子的实际意义。非软件例子有助于增进模式语言的表达力和辅助模式的学习。 增加模式语言的表达能力 Alexander觉得真正的模式要融入一种通用的语言以便所有人都能够分享。在软件设计的人群中,模式被认为是在同事之间一种约定俗成的开发方式。模式提供了一种比模块、过程和对象更高层次的概念。 一种语言中至关重要的因素是同语言形象所对应的心灵影像。在一种语言中,仅当一个人能够领会一个符 的含义,能够在心里描绘出这种含义时,这个符 的外形才是有意义的。Alexander没有忽视模式语言的这种重要特征,他规定:一种语言只有在它所产生的建筑类型能够被具体地看到之后,这种语言才是完全形态化的。在软件设计中,Richle和Züllighoven认识到具体的例子在指导我们对应用领域的理解的重要性。 如果软件设计模式成为程序员中通用的语言,其基础则是统一的含义。如果设计决定下达了,但是没有被理解,则设计师被迫通过假设来完成工作。平凡的例子更便于理解,其原因在于人们必须在记忆中找到相关联的内容才能够理解。在广泛使用模式的AG Communication Systems公司的项目中,常常使用非软件例子来解释模式之间的关系。这个例子有助于在设计师间提供统一的理解。通过在设计过程的先期建立统一的理解,使得在整个项目生命周期中,设计师间的沟通更加容易。 结论 在非软件例子中软件设计模式的体现表明了模式不是局限于特定领域的。软件设计师可以从这些日常事物的模式举例中受益,哪怕这些例子并不是以程序设计语言表达的。这篇文章尽可能举一些大部分人所熟悉的例子(尽管某些倾向于北美文化)。通过对共同的经历的描述,这些例子有助于对特定的设计模式的理解,并且能够帮助对设计模式的学习。 声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢! 软件 生成海 软件工程师专属的时间预期指南 上一篇 2017年2月23日 图像内插 下一篇 2017年2月23日 相关推荐 基于程序员的知识付费,这个 站有点新意,但是基于程序员的知识付费,能刮起一阵凤么? 2021年1月16日 三条线之间花内切圆matlab,论CAESES的平面三曲线倒圆技术 2021年2月22日 从一块内存开始,带你了解企业级虚拟化(二) 2022年8月5日 靠这个Python脚本轻松月入上万?你信不?打造淘宝主图视频生成! 2021年6月7日 深入浅出嵌入式底层软件开发(嵌入式学习书籍) 2012年3月7日 基于HarmonyOS的华为智能手表APP开发实战——Fitness 2022年9月11日 工程资料员,这款软件你值得拥有!“向日葵远程控制软件 2019年3月7日 近年来火热软件有哪些创意 2018年2月16日 零基础使用 MATLAB 求解偏微分方程(建议收藏) 2022年9月16日 电脑数据丢失如何恢复?分享好用的数据恢复工具 2021年6月16日