
Design Patterns
晓梦_知行
这个作者很懒,什么都没留下…
展开
-
招式与内功谈起——设计模式概述(一)
关于金庸小说中到底是招式重要还是内功重要的争论从未停止,我们在这里并不分析张无忌的九阳神功和令狐冲的独孤九剑到底哪个更厉害,但我想每个武林人士梦寐以求的应该是既有淋漓的招式又有深厚的内功。看到这里大家可能会产生疑问了?搞什么,讨论什么招式与内功,我只是个软件开发人员。别急,正因为你是软件开发人员我才跟你谈这个,因为我们的软件开发技术也包括一些招式和内功:Java、C#、C++等编程语言,Eclip转载 2017-07-09 10:40:37 · 899 阅读 · 0 评论 -
从招式与内功谈起——设计模式概述(二)
1.2 设计模式是什么 俗话说:站在别人的肩膀上,我们会看得更远。设计模式的出现可以让我们站在前人的肩膀上,通过一些成熟的设计方案来指导新项目的开发和设计,以便于我们开发出具有更好的灵活性和可扩展性,也更易于复用的软件系统。 设计模式的一般定义如下:设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的转载 2017-07-09 11:05:17 · 929 阅读 · 0 评论 -
面向对象设计原则概述
对于面向对象软件系统的设计而言,在支持可维护性的同时,提高系统的可复用性是一个至关重要的问题,如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解决的核心问题之一。在面向对象设计中,可维护性的复用是以设计原则为基础的。每一个原则都蕴含一些面向对象设计的思想,可以从不同的角度提升一个软件结构的设计水平。 面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计模转载 2017-07-09 11:54:12 · 390 阅读 · 0 评论 -
面向对象设计原则之单一职责原则
单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小。单一职责原则定义如下:单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。 单一职责原则告诉我们:一个类不能太“累”!在软件系统中,一个类(大转载 2017-09-14 16:53:13 · 252 阅读 · 0 评论 -
面向对象设计原则之开闭原则
开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则。开闭原则由Bertrand Meyer于1988年提出,其定义如下:开闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。 在开闭原则的定义中,软件实体可以指一个软转载 2017-10-09 17:13:06 · 593 阅读 · 1 评论 -
面向对象设计原则之里氏代换原则
里氏代换原则由2008年图灵奖得主、美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing教授于1994年提出。其严格表述如下:如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1代换o2时,程序P的行为没有变化,那么类型S是类型T的子类型。这个定义比较拗口且难以理解,因此我们一般使用它的另一个通俗版定义转载 2017-10-09 17:28:03 · 235 阅读 · 0 评论 -
面向对象设计原则之依赖倒转原则
如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是面向对象设计的主要实现机制之一,它是系统抽象化的具体实现。依赖倒转原则是Robert C. Martin在1996年为“C++Reporter”所写的专栏Engineering Notebook的第三篇,后来加入到他在2002年出版的经典著作“Agile Software Development, Principles, Patter转载 2017-10-09 17:52:06 · 184 阅读 · 0 评论 -
面向对象设计原则之接口隔离原则
接口隔离原则定义如下:接口隔离原则(Interface Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。 根据接口隔离原则,当一个接口太大时,我们需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。每一个接口应该承担一种相对独转载 2017-10-10 15:20:15 · 243 阅读 · 0 评论 -
面向对象设计原则之合成复用原则
合成复用原则又称为组合/聚合复用原则(Composition/Aggregate Reuse Principle, CARP),其定义如下:合成复用原则(Composite Reuse Principle, CRP):尽量使用对象组合,而不是继承来达到复用的目的。 合成复用原则就是在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用转载 2017-10-10 15:27:12 · 245 阅读 · 0 评论 -
面向对象设计原则之迪米特法则
迪米特法则来自于1987年美国东北大学(Northeastern University)一个名为“Demeter”的研究项目。迪米特法则又称为最少知识原则(LeastKnowledge Principle, LKP),其定义如下:迪米特法则(Law of Demeter, LoD):一个软件实体应当尽可能少地与其他实体发生相互作用。转载 2017-10-12 09:43:03 · 182 阅读 · 0 评论 -
工厂三兄弟之简单工厂模式(一)
工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式。本章将要学习的简单工厂模式是工厂方法模式的“小弟”,它不属于GoF 23种设计模式,但在软件开发中应用也较为频繁,通常将它作为学习其他工厂模式的入门。此外,工厂方法模式还有一位“大哥”——抽象工厂模式。这三种工厂模式各具特色,难度也逐个加大,在软件开发中它们都得到了广泛的应用,成为面向对转载 2017-10-12 10:02:24 · 260 阅读 · 0 评论 -
工厂三兄弟之简单工厂模式(二)
简单工厂模式并不属于GoF 23个经典设计模式,但通常将它作为学习其他工厂模式的基础,它的设计思想很简单,其基本流程如下: 首先将需要创建的各种不同对象(例如各种不同的Chart对象)的相关代码封装到不同的类中,这些类称为具体产品类,而将它们公共的代码进行抽象和提取后封装在一个抽象产品类中,每一个具体产品类都是抽象产品类的子类;然后提供一个工厂类用于创建各种产品,在工厂类中提供转载 2017-10-12 10:16:11 · 169 阅读 · 0 评论 -
工厂三兄弟之简单工厂模式(三)
3 完整解决方案 为了将Chart类的职责分离,同时将Chart对象的创建和使用分离,Sunny软件公司开发人员决定使用简单工厂模式对图表库进行重构,重构后的结构如图2所示:图2 图表库结构图 在图2中,Chart接口充当抽象产品类,其子类HistogramChart、PieChart和LineChart充当具体产品类,ChartFactor转载 2017-10-12 10:27:38 · 248 阅读 · 0 评论 -
工厂三兄弟之简单工厂模式(四)
4 方案的改进 Sunny软件公司开发人员发现在创建具体Chart对象时,每更换一个Chart对象都需要修改客户端代码中静态工厂方法的参数,客户端代码将要重新编译,这对于客户端而言,违反了“开闭原则”,有没有一种方法能够在不修改客户端代码的前提下更换具体产品对象呢?答案是肯定的,下面将介绍一种常用的实现方式。 我们可以将静态工厂方法的参数存储在XML或pro转载 2017-10-12 10:37:52 · 229 阅读 · 0 评论 -
工厂三兄弟之工厂方法模式(一)
简单工厂模式虽然简单,但存在一个很严重的问题。当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码,将违背“开闭原则”,如何实现增加新产品而不影响已有代码?工厂方法模式应运而生,本文将介绍第二种工厂模式——工厂方法模式。 1 日志记录器的设计 Sunny软件公司欲开发一个系统运行日志记转载 2017-10-12 11:05:06 · 206 阅读 · 0 评论 -
工厂三兄弟之抽象工厂模式(四)
4 完整解决方案 Sunny公司开发人员使用抽象工厂模式来重构界面皮肤库的设计,其基本结构如图6所示:图6 界面皮肤库结构图 在图6中,SkinFactory接口充当抽象工厂,其子类SpringSkinFactory和SummerSkinFactory充当具体工厂,接口Button、TextField和ComboBox充当抽象产品,其子类Sp转载 2017-10-12 16:42:01 · 262 阅读 · 0 评论 -
确保对象的唯一性——单例模式 (一)
3.1 单例模式的动机 对于一个软件系统的某些类而言,我们无须创建多个实例。举个大家都熟知的例子——Windows任务管理器,如图3-1所示,我们可以做一个这样的尝试,在Windows的“任务栏”的右键弹出菜单上多次点击“启动任务管理器”,看能否打开多个任务管理器窗口?如果你的桌面出现多个任务管理器,我请你吃饭,(注:电脑中毒或私自修改Windows内核者除外)。通常情况下,无论转载 2017-11-07 09:32:23 · 364 阅读 · 2 评论 -
确保对象的唯一性——单例模式 (二)
3.3 负载均衡器的设计与实现 Sunny软件公司承接了一个服务器负载均衡(Load Balance)软件的开发工作,该软件运行在一台负载均衡服务器上,可以将并发访问和数据流量分发到服务器集群中的多台设备上进行并发处理,提高系统的整体处理能力,缩短响应时间。由于集群中的服务器需要动态删减,且客户端请求需要统一分发,因此需要确保负载均衡器的唯一性,只能有一个负载均转载 2017-11-07 09:45:45 · 301 阅读 · 0 评论 -
确保对象的唯一性——单例模式 (三)
3.4 饿汉式单例与懒汉式单例的讨论 Sunny公司开发人员使用单例模式实现了负载均衡器的设计,但是在实际使用中出现了一个非常严重的问题,当负载均衡器在启动过程中用户再次启动该负载均衡器时,系统无任何异常,但当客户端提交请求时出现请求分发失败,通过仔细分析发现原来系统中还是存在多个负载均衡器对象,导致分发时目标服务器不一致,从而产生冲突。为什么会这样呢?Sunny公司开发人员百思转载 2017-11-07 10:01:23 · 327 阅读 · 1 评论 -
确保对象的唯一性——单例模式 (四)
3.5 一种更好的单例实现方法 饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。可见,无论是饿汉式单例还是懒汉式单例都存在这样那样的问题,有没有一种方法,能够将两种单例的缺点都克服,而将两者的优点合二为一呢?答案是:Yes!下面我们来学习这种更好的被称之为Initialization Demand Holder (Io转载 2017-11-07 10:08:32 · 261 阅读 · 0 评论 -
确保对象的唯一性——单例模式 (五)
3.6 单例模式总结 单例模式作为一种目标明确、结构简单、理解容易的设计模式,在软件开发中使用频率相当高,在很多应用软件和框架中都得以广泛应用。 1.主要优点 单例模式的主要优点如下: (1) 单例模式提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。转载 2017-11-07 10:11:50 · 354 阅读 · 0 评论 -
对象的克隆——原型模式(一)
张纪中版《西游记》以出乎意料的造型和雷人的台词遭到广大观众朋友的热议,我们在此对该话题不作过多讨论。但无论是哪个版本的《西游记》,孙悟空都是其中的一号雄性主角,关于他(或它)拔毛变小猴的故事几乎人人皆知,孙悟空可以用猴毛根据自己的形象,复制(又称“克隆”或“拷贝”)出很多跟自己长得一模一样的“身外身”来。在设计模式中也存在一个类似的模式,可以通过一个原型对象克隆出多个一模一样的对象,该模式称之为原转载 2017-11-07 10:28:04 · 210 阅读 · 0 评论 -
对象的克隆——原型模式(二)
7.3 完整解决方案 Sunny公司开发人员决定使用原型模式来实现工作周报的快速创建,快速创建工作周报结构图如图7-3所示:图7-3 快速创建工作周报结构图 在图7-3中,WeeklyLog充当具体原型类,Object类充当抽象原型类,clone()方法为原型方法。WeeklyLog类的代码如下所示://工作周报WeeklyLog:具体原转载 2017-11-07 10:34:10 · 177 阅读 · 0 评论 -
工厂三兄弟之工厂方法模式(二)
2 工厂方法模式概述 在简单工厂模式中只提供一个工厂类,该工厂类处于对产品类进行实例化的中心位置,它需要知道每一个产品对象的创建细节,并决定何时实例化哪一个产品类。简单工厂模式最大的缺点是当有新产品要加入到系统中时,必须修改工厂类,需要在其中加入必要的业务逻辑,这违背了“开闭原则”。此外,在简单工厂模式中,所有的产品都由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂,具体产品转载 2017-10-12 14:24:47 · 165 阅读 · 0 评论 -
工厂三兄弟之工厂方法模式(三)
3 完整解决方案 Sunny公司开发人员决定使用工厂方法模式来设计日志记录器,其基本结构如图3所示:图3 日志记录器结构图 在图3中,Logger接口充当抽象产品,其子类FileLogger和DatabaseLogger充当具体产品,LoggerFactory接口充当抽象工厂,其子类FileLoggerFactory和DatabaseLog转载 2017-10-12 14:49:13 · 273 阅读 · 0 评论 -
工厂三兄弟之工厂方法模式(四)
5 重载的工厂方法 Sunny公司开发人员通过进一步分析,发现可以通过多种方式来初始化日志记录器,例如可以为各种日志记录器提供默认实现;还可以为数据库日志记录器提供数据库连接字符串,为文件日志记录器提供文件路径;也可以将参数封装在一个Object类型的对象中,通过Object对象将配置参数传入工厂类。此时,可以提供一组重载的工厂方法,以不同的方式对产品对象进行创建。当然,对于同转载 2017-10-12 16:00:22 · 240 阅读 · 0 评论 -
对象的克隆——原型模式(三)
7.4 带附件的周报 通过引入原型模式,Sunny软件公司OA系统支持工作周报的快速克隆,极大提高了工作周报的编写效率,受到员工的一致好评。但有员工又发现一个问题,有些工作周报带有附件,例如经理助理“小龙女”的周报通常附有本周项目进展报告汇总表、本周客户反馈信息汇总表等,如果使用上述原型模式来复制周报,周报虽然可以复制,但是周报的附件并不能复制,这是由于什么原因导致的呢?如何才能转载 2017-11-07 13:37:35 · 206 阅读 · 0 评论 -
对象的克隆——原型模式(四)
7.5 原型管理器的引入和实现 原型管理器(Prototype Manager)是将多个原型对象存储在一个集合中供客户端使用,它是一个专门负责克隆对象的工厂,其中定义了一个集合用于存储原型对象,如果需要某个原型对象的一个克隆,可以通过复制集合中对应的原型对象来获得。在原型管理器中针对抽象原型类进行编程,以便扩展。其结构如图7-8所示:转载 2017-11-07 13:51:03 · 188 阅读 · 0 评论 -
复杂对象的组装与创建——建造者模式(一)
没有人买车会只买一个轮胎或者方向盘,大家买的都是一辆包含轮胎、方向盘和发动机等多个部件的完整汽车。如何将这些部件组装成一辆完整的汽车并返回给用户,这是建造者模式需要解决的问题。建造者模式又称为生成器模式,它是一种较为复杂、使用频率也相对较低的创建型模式。建造者模式为客户端返回的不是一个简单的产品,而是一个由多个部件组成的复杂产品。8.1 游戏角色设计Sunny软件公转载 2017-11-07 14:03:00 · 237 阅读 · 0 评论 -
工厂三兄弟之抽象工厂模式(一)
工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,我们可以考虑将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产,这就是我们本文将要学习的抽象工厂模式的基本思想。 1 界面皮肤库的初始设计 Sunn转载 2017-10-12 16:10:23 · 260 阅读 · 0 评论 -
工厂三兄弟之抽象工厂模式(二)
2 产品等级结构与产品族 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法具有唯一性,一般情况下,一个具体工厂中只有一个或者一组重载的工厂方法。但是有时候我们希望一个工厂可以提供多个产品对象,而不是单一的产品对象,如一个电器工厂,它可以生产电视机、电冰箱、空调等多种电器,而不是只生产某一种电器。为了更好地理解抽象工厂模式,我们先引入两个概念:转载 2017-10-12 16:25:04 · 191 阅读 · 0 评论 -
工厂三兄弟之抽象工厂模式(三)
3 抽象工厂模式概述 抽象工厂模式为创建一组对象提供了一种解决方案。与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品。抽象工厂模式定义如下: 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模转载 2017-10-12 16:32:44 · 293 阅读 · 0 评论 -
工厂三兄弟之抽象工厂模式(五)
5 “开闭原则”的倾斜性Sunny公司使用抽象工厂模式设计了界面皮肤库,该皮肤库可以较为方便地增加新的皮肤,但是现在遇到一个非常严重的问题:由于设计时考虑不全面,忘记为单选按钮(RadioButton)提供不同皮肤的风格化显示,导致无论选择哪种皮肤,单选按钮都显得那么“格格不入”。Sunny公司的设计人员决定向系统中增加单选按钮,但是发现原有系统居然不能够在符合“开闭原则”的前提下增加新的转载 2017-10-12 16:55:07 · 209 阅读 · 0 评论 -
复杂对象的组装与创建——建造者模式(二)
8.3 完整解决方案 Sunny公司开发人员决定使用建造者模式来实现游戏角色的创建,其基本结构如图8-3所示:图8-3 游戏角色创建结构图 在图8-3中,ActorController充当指挥者,ActorBuilder充当抽象建造者,HeroBuilder、AngelBuilder和DevilBuilder充当具体建造者,Actor充当复杂产品转载 2017-11-08 09:24:03 · 208 阅读 · 0 评论 -
复杂对象的组装与创建——建造者模式(三)
8.4 关于Director的进一步讨论 指挥者类Director在建造者模式中扮演非常重要的作用,简单的Director类用于指导具体建造者如何构建产品,它按一定次序调用Builder的buildPartX()方法,控制调用的先后次序,并向客户端返回一个完整的产品对象。下面我们讨论几种Director的高级应用方式: 1.省略Director转载 2017-11-08 09:24:21 · 322 阅读 · 0 评论 -
不兼容结构的协调——适配器模式(三)
9.4 类适配器 除了对象适配器模式之外,适配器模式还有一种形式,那就是类适配器模式,类适配器模式和对象适配器模式最大的区别在于适配器和适配者之间的关系不同,对象适配器模式中适配器和适配者之间是关联关系,而类适配器模式中适配器和适配者是继承关系,类适配器模式结构如图9-5所示:图 9-5 类适配器模式结构图 根据类适配器模式结构图,适配器类实转载 2017-11-13 09:30:56 · 296 阅读 · 0 评论 -
不兼容结构的协调——适配器模式(二)
9.3 完整解决方案 Sunny软件公司开发人员决定使用适配器模式来重用算法库中的算法,其基本结构如图9-4所示:图9-4 算法库重用结构图 在图9-4中,ScoreOperation接口充当抽象目标,QuickSort和BinarySearch类充当适配者,OperationAdapter充当适配器。完整代码如下所示://抽象成绩操转载 2017-11-12 00:14:12 · 221 阅读 · 0 评论 -
不兼容结构的协调——适配器模式(一)
我的笔记本电脑的工作电压是20V,而我国的家庭用电是220V,如何让20V的笔记本电脑能够在220V的电压下工作?答案是引入一个电源适配器(AC Adapter),俗称充电器或变压器,有了这个电源适配器,生活用电和笔记本电脑即可兼容,如图9-1所示:图9-1 电源适配器示意图 在软件开发中,有时也存在类似这种不兼容的情况,我们也可以像引入一个电源适配器一样引入转载 2017-11-12 00:04:09 · 281 阅读 · 0 评论 -
不兼容结构的协调——适配器模式(四)
9.6 缺省适配器 缺省适配器模式是适配器模式的一种变体,其应用也较为广泛。缺省适配器模式的定义如下:缺省适配器模式(Default Adapter Pattern):当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适转载 2017-11-13 09:33:21 · 509 阅读 · 0 评论 -
处理多维度变化——桥接模式(一)
在正式介绍桥接模式之前,我先跟大家谈谈两种常见文具的区别,它们是毛笔和蜡笔。假如我们需要大中小3种型号的画笔,能够绘制12种不同的颜色,如果使用蜡笔,需要准备3×12 = 36支,但如果使用毛笔的话,只需要提供3种型号的毛笔,外加12个颜料盒即可,涉及到的对象个数仅为 3 + 12 = 15,远小于36,却能实现与36支蜡笔同样的功能。如果增加一种新型号的画笔,并且也需要具有12种颜色,对转载 2017-11-13 09:41:48 · 303 阅读 · 0 评论