
软件架构
文章平均质量分 89
LoveLion
这个作者很懒,什么都没留下…
展开
-
单例模式之枚举实现
如果你没有学过单例模式,请点击:确保对象的唯一性——单例模式。 有很多网友留言说我漏掉了一种非常重要的Java语言的单例模式实现方式——枚举。 这篇姗姗来迟的博文将弥补这个“巨大的”缺陷。 在Java语言中,如果综合考虑线程安全和延迟加载,IoDH(Initialization Demand Holder)无疑是一种比较好的实现方式【参见:确保对象的唯一性——单例模式 (四)】,它巧妙利用了Java静态内部类的特点。 但...原创 2020-12-10 20:47:51 · 35395 阅读 · 42 评论 -
用心之作,倾心出品——《设计模式的艺术》震撼来袭!
用心之作,倾心出品!《设计模式的艺术》双色版正式出版,再次感谢清华大学出版社!一本修炼编程内功的设计模式著作,内容涵盖本博客所有精品文章!图书目录可参考:史上最全设计模式导学目录(完整版):https://blog.youkuaiyun.com/lovelion/article/details/17517213【本目录访问次数已超过30万次】出版社: 清华大学出版社书号:9787302541882 京东链接 当当链接 《设计模式的艺术》前言【节段】在过去多年的...原创 2020-08-29 13:22:28 · 9307 阅读 · 6 评论 -
《设计模式》教材前言
本教材(《设计模式》)已由清华大学出版社于2011年10月正式出版,以下是其前言部分: 鲁迅先生曾说过: “其实地上本没有路,走的人多了,也便成了路”。模式与之同理,它是人类在工程应用领域经验的总结与传承,是人类在具体环境下解决特定现实问题所积累和整理的解决方案。模式的概念来自于建筑领域,模式之父Christopher Alexander博士将模式定义为“在具体环境中解决问题的方法”原创 2012-02-11 19:42:06 · 8859 阅读 · 3 评论 -
《设计模式实践指南》意见和建议征集帖
偶准备近期写一本《设计模式实践指南》,非教材,通俗读物,文字相对较为轻松,面向一线开发人员和模式自学者,大概300页左右(定价控制在40以内,),现向广大XDJM们征集一些意见和建议: 1. 编程语言?C#、Java还是C++,如果完全和语言无关,实例代码可能会不完整。 2. 讲解实例?偏向生活实例还是应用实例,生活实例容易理解,但是仅此而已,看完了就看完了,不知道原创 2012-02-11 20:26:02 · 3980 阅读 · 6 评论 -
对象的克隆——原型模式(二)
7.3 完整解决方案 Sunny公司开发人员决定使用原型模式来实现工作周报的快速创建,快速创建工作周报结构图如图7-3所示:图7-3 快速创建工作周报结构图 在图7-3中,WeeklyLog充当具体原型类,Object类充当抽象原型类,clone()方法为原型方法。WeeklyLog类的代码如下所示://工作周报WeeklyLog:具体原型类原创 2012-04-03 22:46:39 · 20609 阅读 · 35 评论 -
对象的克隆——原型模式(一)
张纪中版《西游记》以出乎意料的造型和雷人的台词遭到广大观众朋友的热议,我们在此对该话题不作过多讨论。但无论是哪个版本的《西游记》,孙悟空都是其中的一号雄性主角,关于他(或它)拔毛变小猴的故事几乎人人皆知,孙悟空可以用猴毛根据自己的形象,复制(又称“克隆”或“拷贝”)出很多跟自己长得一模一样的“身外身”来。在设计模式中也存在一个类似的模式,可以通过一个原型对象克隆出多个一模一样的对象,该模式称之为原原创 2012-04-03 22:43:10 · 33432 阅读 · 27 评论 -
扩展系统功能——装饰模式(一)
尽管目前房价依旧很高,但还是阻止不了大家对新房的渴望和买房的热情。如果大家买的是毛坯房,无疑还有一项艰巨的任务要面对,那就是装修。对新房进行装修并没有改变房屋用于居住的本质,但它可以让房子变得更漂亮、更温馨、更实用、更能满足居家的需求。在软件设计中,我们也有一种类似新房装修的技术可以对已有对象(新房)的功能进行扩展(装修),以获得更加符合用户需求的对象,使得对象具有更加强大的功能。这种技术对应于一原创 2012-04-03 23:36:05 · 26684 阅读 · 18 评论 -
对象的克隆——原型模式(四)
7.5 原型管理器的引入和实现 原型管理器(Prototype Manager)是将多个原型对象存储在一个集合中供客户端使用,它是一个专门负责克隆对象的工厂,其中定义了一个集合用于存储原型对象,如果需要某个原型对象的一个克隆,可以通过复制集合中对应的原型对象来获得。在原型管理器中针对抽象原型类进行编程,以便扩展。其结构如图7-8所示:原创 2012-04-03 23:07:29 · 20459 阅读 · 16 评论 -
复杂对象的组装与创建——建造者模式(二)
8.3完整解决方案 Sunny公司开发人员决定使用建造者模式来实现游戏角色的创建,其基本结构如图8-3所示:图8-3 游戏角色创建结构图 在图8-3中,ActorController充当指挥者,ActorBuilder充当抽象建造者,HeroBuilder、AngelBuilder和DevilBuilder充当具体建造者,Actor充当复杂产品。完整代码如下原创 2012-04-04 20:04:21 · 22977 阅读 · 22 评论 -
扩展系统功能——装饰模式(二)
12.2 装饰模式概述 装饰模式可以在不改变一个对象本身功能的基础上给对象增加额外的新行为,在现实生活中,这种情况也到处存在,例如一张照片,我们可以不改变照片本身,给它增加一个相框,使得它具有防潮的功能,而且用户可以根据需要给它增加不同类型的相框,甚至可以在一个小相框的外面再套一个大相框。 装饰模式是一种用于替代继承的技术,它通过一种无须定义子类的方式来给对象动态增加职原创 2012-04-04 16:26:48 · 25341 阅读 · 19 评论 -
设计模式之反射与配置文件
为了满足“开闭原则”,大部分设计模式都引入了抽象层,如工厂方法模式、抽象工厂模式、适配器模式、桥接模式、命令模式、策略模式等等。客户端代码针对抽象层编程,而在程序运行的时候再指定其子类,根据“里氏代换原则”和面向对象的多态性,子类对象在运行时将覆盖父类对象。如果需要对系统进行扩展或修改,只需修改子类类名即可。在具体实现时,通过引入配置文件可以使得用户在不修改任何客户端代码的前提下增加或替换子类,其原创 2012-04-05 22:47:30 · 13765 阅读 · 9 评论 -
设计模式面试与笔试题剖析(三)
Windows Media Player和RealPlayer是两种常用的媒体播放器,它们的API结构和调用方法存在区别。现在你的应用程序需要支持这两种播放器API,而且在将来可能还需要支持新的媒体播放器,请问如何设计该应用程序? 参考解答:【个人观点】 本题可使用适配器模式和抽象工厂模式,参考类图如下所示: 在该类图中,我们为两原创 2012-04-05 23:35:44 · 11685 阅读 · 1 评论 -
操作复杂对象结构——访问者模式(二)
26.2 访问者模式概述 访问者模式是一种较为复杂的行为型设计模式,它包含访问者和被访问元素两个主要组成部分,这些被访问的元素通常具有不同的类型,且不同的访问者可以对它们进行不同的访问操作。例如处方单中的各种药品信息就是被访问的元素,而划价人员和药房工作人员就是访问者。访问者模式使得用户可以在不修改现有系统的情况下扩展系统的功能,为这些不同类型的元素增加新的操作。 在使原创 2012-04-06 20:07:28 · 15637 阅读 · 9 评论 -
设计模式面试与笔试题剖析(二)
某知名IT企业笔试题: 程序设计:猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。要求:(1) 要有联动性,老鼠和主人的行为是被动的;(2) 考虑可扩展性,猫的叫声可能引起其他联动效应。 参考解答:【个人观点】 本题可使用观察者模式,参考类图如下所示: 参考代码如下: import原创 2012-04-05 23:20:37 · 8534 阅读 · 1 评论 -
设计模式面试与笔试题剖析(一)
近几年来,设计模式试题已广泛出现在一些IT企业(包括一些巨牛型企业)的面试和笔试题中,从本文开始我将通过几篇文章来介绍一下一些已出现过的设计模式面试和笔试题,欢迎大家讨论。某房地产公司欲开发一套房产信息管理系统,根据如下描述选择合适的设计模式进行设计:(1) 该公司有多种房型,如公寓、别墅等,在将来可能会增加新的房型;(2) 销售人员每售出一套房子,主管将收到相原创 2012-04-05 23:11:39 · 20700 阅读 · 2 评论 -
操作复杂对象结构——访问者模式(四)
26.4 访问者模式与组合模式联用 在访问者模式中,包含一个用于存储元素对象集合的对象结构,我们通常可以使用迭代器来遍历对象结构,同时具体元素之间可以存在整体与部分关系,有些元素作为容器对象,有些元素作为成员对象,可以使用组合模式来组织元素。引入组合模式后的访问者模式结构图如图26-4所示: 需要注意的是,在图26-4所示结构中,由于叶子元素的遍历操作已经原创 2012-04-06 20:20:58 · 11304 阅读 · 13 评论 -
扩展系统功能——装饰模式(三)
12.3 完整解决方案 为了让系统具有更好的灵活性和可扩展性,克服继承复用所带来的问题,Sunny公司开发人员使用装饰模式来重构图形界面构件库的设计,其中部分类的基本结构如图12-4所示:图12-4 图形界面构件库结构图 在图12-4中,Component充当抽象构件类,其子类Window、TextBox、ListBox充当具体构件类,Component类原创 2012-04-04 16:30:38 · 19204 阅读 · 19 评论 -
处理多维度变化——桥接模式(一)
在正式介绍桥接模式之前,我先跟大家谈谈两种常见文具的区别,它们是毛笔和蜡笔。假如我们需要大中小3种型号的画笔,能够绘制12种不同的颜色,如果使用蜡笔,需要准备3×12 = 36支,但如果使用毛笔的话,只需要提供3种型号的毛笔,外加12个颜料盒即可,涉及到的对象个数仅为 3 + 12 = 15,远小于36,却能实现与36支蜡笔同样的功能。如果增加一种新型号的画笔,并且也需要具有12种颜色,对原创 2012-04-15 23:56:32 · 30523 阅读 · 18 评论 -
处理多维度变化——桥接模式(二)
10.2 桥接模式概述 桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则”。与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关联关系类似一条连接两个独立继承结构的桥,故名桥接模式。 桥接模式原创 2012-04-16 00:07:09 · 30731 阅读 · 21 评论 -
处理多维度变化——桥接模式(三)
10.3 完整解决方案 为了减少所需生成的子类数目,实现将操作系统和图像文件格式两个维度分离,使它们可以独立改变,Sunny公司开发人员使用桥接模式来重构跨平台图像浏览系统的设计,其基本结构如图10-5所示: 在图10-5中,Image充当抽象类,其子类JPGImage、PNGImage、BMPImage和GIFImage充当扩充抽象类;ImageImp原创 2012-04-16 00:15:41 · 23694 阅读 · 10 评论 -
面向对象设计原则之单一职责原则
单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小。单一职责原则定义如下:单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。 单一职责原则告诉我们:一个类不能太“累”!在软件系统中,一个类(大到模块,原创 2012-05-04 23:57:59 · 57147 阅读 · 52 评论 -
面向对象设计原则之开闭原则
开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则。开闭原则由Bertrand Meyer于1988年提出,其定义如下:开闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。 在开闭原则的定义中,软件实体可以指一个软件模块、原创 2012-05-05 15:05:50 · 59065 阅读 · 48 评论 -
面向对象设计原则之接口隔离原则
接口隔离原则定义如下:接口隔离原则(Interface Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。 根据接口隔离原则,当一个接口太大时,我们需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。每一个接口应该承担一种相对独立的原创 2012-05-13 19:54:28 · 39728 阅读 · 60 评论 -
面向对象设计原则之依赖倒转原则
如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是面向对象设计的主要实现机制之一,它是系统抽象化的具体实现。依赖倒转原则是Robert C. Martin在1996年为“C++Reporter”所写的专栏Engineering Notebook的第三篇,后来加入到他在2002年出版的经典著作“Agile Software Development, Principles, Patter原创 2012-05-13 19:43:25 · 44148 阅读 · 46 评论 -
面向对象设计原则之合成复用原则
合成复用原则又称为组合/聚合复用原则(Composition/Aggregate Reuse Principle, CARP),其定义如下:合成复用原则(Composite Reuse Principle, CRP):尽量使用对象组合,而不是继承来达到复用的目的。 合成复用原则就是在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些已有原创 2012-05-14 01:24:22 · 43290 阅读 · 34 评论 -
面向对象设计原则之迪米特法则
迪米特法则来自于1987年美国东北大学(Northeastern University)一个名为“Demeter”的研究项目。迪米特法则又称为最少知识原则(LeastKnowledge Principle, LKP),其定义如下:迪米特法则(Law of Demeter, LoD):一个软件实体应当尽可能少地与其他实体发生相互作用。 如果一个原创 2012-05-14 01:34:44 · 42692 阅读 · 37 评论 -
操作复杂对象结构——访问者模式(三)
26.3 完整解决方案 Sunny软件公司开发人员使用访问者模式对OA系统中员工数据汇总模块进行重构,使得系统可以很方便地增加新类型的访问者,更加符合“单一职责原则”和“开闭原则”,重构后的基本结构如图26-3所示: 在图26-3中,FADepartment表示财务部,HRDepartment表示人力资源部,它们充当具体访问者角色,其抽象父类Department充原创 2012-04-06 20:15:05 · 12869 阅读 · 11 评论 -
实现对象的复用——享元模式(二)
享元模式结构较为复杂,一般结合工厂模式一起使用,在它的结构图中包含了一个享元工厂类,其结构图如图14-3所示: 图14-3 享元模式结构图 在享元模式结构图中包含如下几个角色: ● Flyweight(抽象享元类):通常是一个接口或抽象类,在抽象享元类中声明了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法来设置原创 2012-06-15 22:27:52 · 15851 阅读 · 7 评论 -
实现对象的复用——享元模式(三)
14.3 完整解决方案 为了节约存储空间,提高系统性能,Sunny公司开发人员使用享元模式来设计围棋软件中的棋子,其基本结构如图14-4所示:图14-4 围棋棋子结构图 在图14-4中,IgoChessman充当抽象享元类,BlackIgoChessman和WhiteIgoChessman充当具体享元类,IgoChessmanFactory充当享元工厂类原创 2012-06-15 22:45:58 · 14297 阅读 · 8 评论 -
实现对象的复用——享元模式(四)
14.5 带外部状态的解决方案 Sunny软件公司开发人员通过对围棋棋子进行进一步分析,发现虽然黑色棋子和白色棋子可以共享,但是它们将显示在棋盘的不同位置,如何让相同的黑子或者白子能够多次重复显示且位于一个棋盘的不同地方?解决方法就是将棋子的位置定义为棋子的一个外部状态,在需要时再进行设置。因此,我们在图14-4中增加了一个新的类Coordinates(坐标类),用于存储每一个棋子原创 2012-06-15 22:55:03 · 12399 阅读 · 13 评论 -
实现对象的复用——享元模式(一)
当前咱们国家正在大力倡导构建和谐社会,其中一个很重要的组成部分就是建设资源节约型社会,“浪费可耻,节俭光荣”。在软件系统中,有时候也会存在资源浪费的情况,例如在计算机内存中存储了多个完全相同或者非常相似的对象,如果这些对象的数量太多将导致系统运行代价过高,内存属于计算机的“稀缺资源”,不应该用来“随便浪费”,那么是否存在一种技术可以用于节约内存使用空间,实现对这些相同或者相似对象的共享访问呢?答案原创 2012-06-15 22:24:11 · 18913 阅读 · 9 评论 -
实现对象的复用——享元模式(五)
14.5 单纯享元模式和复合享元模式 标准的享元模式结构图中既包含可以共享的具体享元类,也包含不可以共享的非共享具体享元类。但是在实际使用过程中,我们有时候会用到两种特殊的享元模式:单纯享元模式和复合享元模式,下面将对这两种特殊的享元模式进行简单的介绍: 1.单纯享元模式 在单纯享元模式中,所有的具体享元类都是可以共享的,不存在非共享具体享元类。单纯原创 2012-06-15 23:02:28 · 12707 阅读 · 20 评论 -
自定义语言的实现——解释器模式(五)
18.5 再谈Context的作用 在解释器模式中,环境类Context用于存储解释器之外的一些全局信息,它通常作为参数被传递到所有表达式的解释方法interpret()中,可以在Context对象中存储和访问表达式解释器的状态,向表达式解释器提供一些全局的、公共的数据,此外还可以在Context中增加一些所有表达式解释器都共有的功能,减轻解释器的职责。 在上面的机原创 2012-07-04 00:13:57 · 9886 阅读 · 10 评论 -
自定义语言的实现——解释器模式(二)
18.2 文法规则和抽象语法树 解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。在正式分析解释器模式结构之前,我们先来学习如何表示一个语言的文法规则以及如何构造一棵抽象语法树。 在前面所提到的加法/减法解释器中,每一个输入表达式,例如“1 + 2 + 3 – 4 + 1”,都包含了三个语言单位,可以使用如下文法规则来定原创 2012-07-03 23:54:23 · 12348 阅读 · 3 评论 -
自定义语言的实现——解释器模式(一)
有朋友一直在等待我的解释器模式文稿,,现把某个版本发在博客上,欢迎大家讨论! 虽然目前计算机编程语言有好几百种,但有时候我们还是希望能用一些简单的语言来实现一些特定的操作,我们只要向计算机输入一个句子或文件,它就能够按照预先定义的文法规则来对句子或文件进行解释,从而实现相应的功能。例如提供一个简单的加法/减法解释器,只要输入一个加法/减法表达式,它就能够计算出表达式结果,如图18-原创 2012-07-03 23:50:01 · 16047 阅读 · 6 评论 -
自定义语言的实现——解释器模式(三)
18.3 解释器模式概述 解释器模式是一种使用频率相对较低但学习难度较大的设计模式,它用于描述如何使用面向对象语言构成一个简单的语言解释器。在某些情况下,为了更好地描述某一些特定类型的问题,我们可以创建一种新的语言,这种语言拥有自己的表达式和结构,即文法规则,这些问题的实例将对应为该语言中的句子。此时,可以使用解释器模式来设计这种新的语言。对解释器模式的学习能够加深我们对面向对象思原创 2012-07-04 00:00:38 · 12539 阅读 · 5 评论 -
自定义语言的实现——解释器模式(六)
18.6 解释器模式总结 解释器模式为自定义语言的设计和实现提供了一种解决方案,它用于定义一组文法规则并通过这组文法规则来解释语言中的句子。虽然解释器模式的使用频率不是特别高,但是它在正则表达式、XML文档解释等领域还是得到了广泛使用。与解释器模式类似,目前还诞生了很多基于抽象语法树的源代码处理工具,例如Eclipse中的Eclipse AST,它可以用于表示Java语言的语法结原创 2012-07-04 00:23:37 · 9490 阅读 · 6 评论 -
数学表达式解析器简介
在实际项目开发中如果需要解析数学公式,无须再运用解释器模式进行设计,可以直接使用一些第三方解析工具包,它们可以统称为数学表达式解析器(Math Expression Parser, MEP),如Expression4J、Jep、JbcParser、Symja、Math Expression String Parser(MESP)等来取代解释器模式,它们可以方便地解释一些较为复杂的文法,功能强大原创 2012-07-04 00:32:47 · 11875 阅读 · 2 评论 -
对象间的联动——观察者模式(一)
观察者模式是设计模式中的“超级模式”,其应用随处可见,在之后几篇文章里,我将向大家详细介绍观察者模式。 “红灯停,绿灯行”,在日常生活中,交通信号灯装点着我们的城市,指挥着日益拥挤的城市交通。当红灯亮起,来往的汽车将停止;而绿灯亮起,汽车可以继续前行。在这个过程中,交通信号灯是汽车(更准确地说应该是汽车驾驶员)的观察目标,而汽车是观察者。随着交通信号灯的变化,汽车的行为也将随之原创 2012-07-05 23:03:41 · 24803 阅读 · 16 评论 -
对象间的联动——观察者模式(二)
22.2 观察者模式概述 观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展。 观察者模原创 2012-07-05 23:34:09 · 25715 阅读 · 13 评论