《笔者带你剖析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(); } } } }
一旦我们在设计过程中使用工厂模式+创建者模式的组合后,就可以成功的将对象的创建过程、组装过程与调用过程进行有效分离。这样一来,调用者的职责就更加清晰,与调用无关的所有操作,比如对象的创建交由工厂负责,而组装过程则交由创建者负责。
相关推荐
商业模式分析是产品经理的基础工作之一,它是产品设计的基础,涉及到四方面的工作:商业模式分析、竞品分析、需求分析和产品设计。商业模式分析是产品经理在产品设计前最重要的一个阶段,如果一个产品的商业模式不...
因此,在这里,我们可以借助一种大名鼎鼎的分析模式——商业画布,来帮助我们更加全面地分析一款竞品的商业化模式。画布的模板如下: * 重要伙伴:竞品企业的有哪些重要的合作伙伴,例如渠道公司、供应链公司、协会...
通过对计算机网络课程的教学现状分析,笔者提出了基于翻转课堂的教学模式设计,旨在提高学生的学习效率和创新能力。 一、计算机网络课程教学现状分析 目前,计算机网络课程教学中存在一些问题,主要体现在以下几个...
从0设计App(2):竞品分析-吃透3款产品看职场在线学习平台.pdf 本文主要讲述了竞品分析的重要性和方法,并对三款职场在线学习平台产品进行了分析。竞品分析是产品经理的“好朋友”,可以从三个方面进行分析:① ...
持平台的五层体系结构,分析了其功能组成,并给出了一个笔者设计的用于网络辅助教学的网络教学支持平台,它包含 网络教学支持平台所应具备的核心功能,在个性化和交互方式的设计上有一些独特的考虑。
爬取所有评论后,笔者使用基于Python的SnowNLP模型和TextBlob模型对所有中英文评论进行情感分析,分析结果分为三类(类别个数可以拟定和修改):积极、消极、中立。 五、研究结果 本研究结果表明,“滇西小哥”利用...
拟采取的研究方法、技术路线、实验方案及可行性分析 本文主要目标是对峰峰矿矿区的地质环境进行详细的调查研究,分析峰峰矿环境地质问题特征,建立峰峰矿地质环境评价的指标体系和评价方法,探索适合峰峰矿使用的 ...
通过分析大学计算机基础课程的特色和教学现状,笔者构建了基于专业特征分类的混合教学模式,结合慕课背景下基于专业特征分类的教学设计和实践过程。 一、计算机基础课程特色与教学现状 计算机基础课程是大学生系统...
通过分析C语言知识结构的特点,笔者设计了一种新的教学模式,即将传统文化融入C语言教学中。该模式旨在提高工科学生的文化底蕴,坚定文化自信,增强民族自豪感,解决学生学习兴趣不高、学习目标不明确等问题。 首先...
本资源摘要信息是对《从0设计App(5):2个维度构建产品之道(上)》的解读和分析,主要关注产品设计的两个维度:战略&定位和用户价值(人性)。文章首先强调了产品设计的重要性,并提出了九个产品设计步骤,从市场...
C语言是一种高级程序设计语言,具有功能丰富、表达能力强、使用方便、应用广、目标程序效率高、可移植性好等优点。在湖南省,C语言已经成为职业高中计算机科目的必考课程。然而,很多学生在学习C语言时,缺乏计算机...
根据笔者对南京地区软件公司程序员岗位进行的分析,程序员的主要工作任务是完成软件的设计、开发、测试等,需要精通编程语言,如Java、C++等,完成功能的详细设计,实现单元测试,撰写相关文档等。 二、Java语言...
笔者提出由三个OTA和两个电容构成三输入单输出电流模式双二阶滤波器电路,适当选择输入电压信号可实现五种滤波器功能。理论分析和MOS管级的SPICE仿真结果表明所提电路方案正确。 1 OTA单元电路 跨导
EDA课程设计 数字时钟的设计(VHDL) 本文将详细介绍数字时钟的设计,包括实验目的、功能设计、系统设计方案概述及工作原理等方面的知识点。 实验目的: 1. 掌握 VHDL 语言的基本运用 2. 掌握 MAX+plusII 的简单...
也正因如此,设计师要做出正确的设计决策,首先需要明确目标(goal),笔者称之为“5W1H1G”思考模式。我们把 5W1H1G 置于交互设计流程中详细拆解,并进行对照。5W1H1G,分别指 who (目标用户)、where (场景)、...
二、分析与设计 2.1 功能模块划分 学生信息管理系统可以划分为以下几个模块: * 学生基本信息管理模块 * 用户管理模块 * 登陆模块 * 数据查询模块 * 数据统计模块 2.2 数据库结构描述 学生信息管理系统的数据库...