《笔者带你剖析23种设计模式01》
前言
其实就笔者个人而言,并不是很情愿单独开系列博文来针对设计模式进行讲解,原因有2点,首先设计模式早几年已经有大量的专业书籍进行阐述,以及互联网上丰富参考文献等;其次,大量的第三方开源组件、中间件内部已经广泛使用设计模式,底层码砖的开发人员实际工作中接触到几率不大。那么为什么笔者又要做一些不情愿的事情呢?这是因为企业中过多的小家伙们总是希望硬生生的把某一种设计模式强塞到项目中来,纯粹是为了设计模式而设计模式,违背初衷,设计的意义何在?
希望大家记住,良好的系统架构往往是伴随着业务的发展逐步演化而来,并不是设计出来,架构师真正能够做到的是在项目设计之初,尽可能面向接口编程、遵循类的单一原则,善用设计模式,这样才能够使我们的项目具有更好的伸缩性、维护性、扩展性,以及复用性。
目录
一、开篇;
二、创建型——简单工厂模式;
三、创建型——工厂方法模式;
四、创建型——抽象工厂模式;
五、创建型——创建者模式;
六、创建型——原型模式;
七、创建型——单例模式;
八、题外话——实现更好的解耦,Spring IOC工厂外围化;
一、开篇
你必须了解的是,学习和掌握设计模式,并不是为了在企业中显示你的成就感和卓越感,因此,切记不要再生搬硬套的将任何一种设计模式强塞在你的项目中,否则事与愿违,违背初衷,说严重点,你可能将会得不偿失。设计模式其实简单来说仅仅只是一种思想,一种方法论,它并不是指某一种具体的技术,也就是说,任何一种使用OOP开发的系统(Java、C++、Python、C#、Ruby等),只要你想使你的项目具有更好的伸缩性、维护性、扩展性,以及复用性,那么尽可能面向接口编程、遵循类的单一原则,善用设计模式,将会事半功倍。
图A-1 设计模式分类
本着打算利用3章系列博文的篇幅来对Gof提出的23种设计模式做详细的讲解,因此笔者将这一系列的设计模式划分为了3大类,如图A-1所示。
二、创建型——简单工厂模式
相信每一位技术牛人都曾经有过一段较为青涩的人生时光,笔者将那个阶段称之为菜鸟期。在那个阶段,大部分开发人员往往都会在代码中直接使用new关键字创建出一个类的对象实例,当然从语法、语义上来看并没有任何错误,只是从领域模型这个大的方向来分析,其每一个组件都应该具备独立性,当然笔者知道这在实际的开发过程中几乎不可能做到,系统解耦是一个漫长的过程,只是如果不从一点一滴做起,你的系统将不具备任何复用性,因为逻辑耦合度太高,换句话来说,只有首先明确每一个类的单一原则才能够更好的为后续架构调整提供便利。
既然类需要具备单一原则,那么在一个类的内部使用关键字new创建出一个新的对象必然是不合理的,因此创建型模式中提供了3种工厂模式来帮助大家解决这个问题。从严格意义上来说,Gof所提出来的23种设计模式之中其实并不包括简单工厂模式,之所以笔者把它也放在23种设计模式内进行讲解是因为其特有的简易性,在大部分应用场景中,简单工厂模式确实能够解决一部分问题,因此笔者首先拿它最为开篇无疑是最明智的选择。
简单工厂模式也可以称之为静态工厂模式,它的目的就是为了能够将对象的创建过程与实际的调用过程进行分离,这样一来,就体现出了类的单一原则,并且系统各个组件之间的耦合度也随之降低了。那么简单工厂模式如何设计呢?如图A-2所示。
图A-2 简单工厂模式类图
如上图所示,简单工厂模式的核心就是提供一个静态工厂,所有的对象创建过程全部在这个静态工厂内完成,以此分离对象的创建过程和调用过程。当然面向接口编程是前提,静态工厂返回中testMethod()方法的返回类型为抽象类型的接口,因为接口可以有不同的实现,工厂自然根据里氏替换原则创建出对应的派生类实现。简单工厂模式的核心代码:
public class AnimalFactory { public static Animal getAnimal(String type) { Animal animal = null; switch (type) { case "tiger": animal = new Tiger(); break; case "pig": animal = new Pig(); } return animal; } }
相信大家似乎已经尝到了点系统设计的甜头,那么笔者不得不提醒大家,简单工厂模式只是最简单的一种工厂模式,从严格意义上来讲,它并不属于Gof所提出的23种设计模式中的任何一种,尽管简单工厂模式的优点是简易性以及可以分离对象的创建过程和调用过程使类单一化,但是其缺点就是纵向维护成本太高,因为如果有新的类型的对象实例需要进行创建,那么静态工厂内的switch语句将会变得非常冗余,维护成本也就随之升高,不利于后期复用。
三、创建型——工厂方法模式
剖析完简单工厂模式后,接下来我们再来看工厂方法模式。尽管简单工厂模式的易用性可以满足绝大多数应用场景,但是一旦对象关系变得复杂化,或者对象过多时,单凭一个静态工厂是不可能完成所有对象的创建的,尽管你可以这么做,但是是否需要稍微考虑下维护成本?
工厂方法模式可以认为是简单工厂的升级版本,它弥补了简单工厂模式的不足,能够胜任对象关系更加复杂,以及更多对象需要进行创建的应用场景。简单来说,工厂方法模式需要一个抽象的大工厂作为基类,然后不同对象由实现了基类工厂的子工厂负责进行对应创建。打个比方,程序中一共有10个对象需要进行创建,那么编号为1-10的工厂分别负责创建对应的对象实例,这样一来,即分离了对象的创建和调用过程,同样也降低了简单工厂模式在实际开发过程中的纵向维护成本,可谓一举两得。如图A-3所示。
图A-3 工厂方法模式类图
如上图所示,工厂方法模式的核心就是提供了一个抽象的工厂基类,不同的子工厂实现这个抽象的大工厂后,分别负责创建与之对应的对象实例,从而降低了简单工厂模式的纵向维护成本,以及更好的提升了类的单一原则。工厂方法模式的核心代码:
public interface AnimalFactory { public Animal getAnimal(); } public class TigerFactory implements AnimalFactory { @Override public Animal getAnimal() { return new Tiger(); } } public class PigFactory implements AnimalFactory { @Override public Animal getAnimal() { return new Pig(); } }
在此大家需要注意,工厂方法模式的优点既是它的缺点,尽管它可以很好的解决简单工厂模式所面临的弊端,但是如果程序中有>=100个以上的类需要创建其对象实例时,难道需要编写100个对应的子工厂?这样一来尽管降低了纵向维护成本,但是随着子工厂数量的井喷式增长,程序的横向维护成本也随之上升。
四、创建型——抽象工厂模式
抽象工厂模式应该算是所有工厂模式中逻辑上最难理解的一个,它出现的目的只有一个,就是解决简单工厂模式和工厂方法模式遇到的问题(更大程度上是看做工厂方法模式的升级),即能在最大程度上遵循类的单一设计原则,同样又能够降低工厂方法模式所带来的横向维护成本等问题。
那么抽象工厂模式是如何设计的呢?简单来说,如果按照之前在工厂方法模式中的需求,有10个类甚至更多的类需要由子工厂进行创建对象实例时,我们可以根据业务分类将相互关联的一组类型归纳在一起,统一由一个子工厂进行维护并创建(同工厂方法模式一样,也需要继承一个抽象的工厂基类),这样一来,工厂类的数目与需要进行创建对象实例的数目自然就不成正比,大大降低了横向维护成本。
五、创建型——创建者模式
如果说工厂模式的作用是为了将对象的创建过程与调用过程进行分离,那么创建者模式的作用就是更进一步,将对象的创建过程、组装过程与调用过程进行分离。细心的读者应该发现了,笔者由工厂类返回的对象实例,调用者在调用之前,是需要在其内部按照里氏替换原则进行对象组装的,按照类的单一原则来说,调用者的职责仅仅只是负责调用对象的某一个方法,执行相应的逻辑行为,对象的组装过程自然不应该由调用者负责,这便是创建者模式的意义。创建者模式的核心代码:
public class AnimalTest { public @Test void testMethod() { new Director(new PigFactory()).getType(); new Director(new TigerFactory()).getType(); } class Director { AnimalFactory factory; Director(AnimalFactory factory) { this.factory = factory; } void getType() { if (null != factory) { Animal animal = factory.getAnimal(); animal.type(); } } } }
一旦我们在设计过程中使用工厂模式+创建者模式的组合后,就可以成功的将对象的创建过程、组装过程与调用过程进行有效分离。这样一来,调用者的职责就更加清晰,与调用无关的所有操作,比如对象的创建交由工厂负责,而组装过程则交由创建者负责。
相关推荐
在研究GoF设计模式基础上,结合笔者实战中的实际代码对各种23种设计模式进行了分析,说明每种模式的适用条件,与相关模式的关系,尽量避免用System.out去说明问题。
笔者认为分析模型正是OO设计的核心,而设计类只是OO的实现手段。分析模型是MVC模式的经典应用。对比分析类的名称,MVC模式,读者应该能够发现分析类在OO和商业目标中精妙的对应关系:人,事,物,规则--actor,...
笔者以高校内外环境为切入点,结合产学研用的优势,从总体设计、组织结构、管理制度、评价机制4个方面剖析了高校协同创新科研组织模式的构建要点,并以此为基础尝试完成高校协同创新科研组织模式框架,以期为高校协同...
持平台的五层体系结构,分析了其功能组成,并给出了一个笔者设计的用于网络辅助教学的网络教学支持平台,它包含 网络教学支持平台所应具备的核心功能,在个性化和交互方式的设计上有一些独特的考虑。
钢铁企业化验报告数据分析系统 作者:周晓敏 来源:《数字化用户》2013年第01期 【摘 要】笔者通过对钢铁企业化验报告数据分析系统的实现方法的研究,结合现在的网络技 术有效地完成了C/S系统平台,对钢铁企业的管理...
星形模式是基于关系数据库的数据仓库中的一个著名概念,由于星形连接模式的设计思想能够满足人们从不同观察角度(维)分析数据的需求,所以在基于关系数据库的数据仓库的设计中广泛地使用了星形模式。在使用数据仓库...
在java Web应用开发中,底层数据传递的模式和传统本地应用有着不小的区别,对底层数据传递模式的了解和数据传递流程的设计决定了应用开发的复杂程度,影响着整个java Web应用程序的开发效率和后期维护的难易度。笔者从...
笔者提出由三个OTA和两个电容构成三输入单输出电流模式双二阶滤波器电路,适当选择输入电压信号可实现五种滤波器功能。理论分析和MOS管级的SPICE仿真结果表明所提电路方案正确。 1 OTA单元电路 跨导
笔者认为,在《IBM-PC汇编语言程序设计》之类传统教材中的基础部分学习完毕以后,重点就应该转向Win32汇编,以及保护模式方面的知识。 关于本书的内容 本书尝试从编写应用程序的角度,从“Hello,World”这个简单的...
设计模式 算法 :pencil: 操作系统 :laptop: 网络 :cloud: 数据库 :floppy_disk: Java :woman_and_man_holding_hands: JavaWeb :hot_beverage: 分布式 :sweat_droplets: 设计模式 :hammer: 《转载说明》 向优秀的大佬...
Midas软件指导结构模型设计——大学生结构设计竞赛经验漫谈之二 崔苗苗 全国大学生结构设计竞赛是国家教育部批准的九个大学生竞赛资助项目之一,大赛旨 在培养大学生的创新意识与合作精神,提高大学生的创新设计能力...
同时,基于笔者设计的新型煤矿物联网架构体系,设计了音频、视频、数据三网合一的传输模式,解决了实时数据运行中的技术难题。经过多个特大型煤矿的应用实践,实现了井下少人及无人工作面的监控,取得了良好效果。
随着中国大中城市私家车的拥有量飞速增长,在给人们的生活带来便利的同时。...通过分析上海几个小区的调研结果,进一步探讨了地下交通空间的性质,并总结出人车分行模式下地下交通空间的设计要点。
这样当然可以,但是从事产品设计的人都知道,在产品的开发设计过程中,零件的形状和材料等会根据产品结构的需要和加工工艺的要求随时进行改变的,这就要求工程图标题栏中的重量、材料等信息也要随之改变。...
课题内容基于一套包含多种智能控制模块的嵌入式实时控制软件,运用面相对象软件设计方法对其中的FBD功能块进行分析设计,参考IEC1131标准,提出适合需要的编程模型并定义需求、进行功能设计和开发。 作为该课题的...
数据库范式(范式,数据库设计范式,数据库的设计范式)是符合某一种级别的关系模式 的集合。构造数据库必须遵循一定的规则。在关系数据库中,这种规则就是范式。关系 数据库中的关系必须满足一定的要求,即满足不同的...
伴随着互联网技术的应用和...笔者在对软件总线技术、MVC设计模式和构件技术的研究基础之上,介绍了一种基于MVC设计模式的Web应用软件系统架构,为提高Web应用软件系统的可维护性、重用性与扩展性提供了一种可行的方法。
计算机信息管理系统设计原理探究 摘要:随着计算机信息技术的不断发展与应用,各行各业都开始把计算机信息技术引 入到生活生产中,这就越发强调了高效、稳定的计算机信息管理系统的重要性,本文对 计算机信息管理系统...