美文网首页@IT·互联网
设计模式之创建型模式

设计模式之创建型模式

作者: 苦难_69e0 | 来源:发表于2021-04-03 21:28 被阅读0次

2、 设计模式之创建型模式

创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的 耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成。就像我们去商场购买商品时,不需 要知道商品是怎么生产出来一样,因为它们由专门的厂商生产。

创建型模式分为以下几种。

image.png

2.1 单例模式

2.1.1 什么是单例模式?(概念的引入)

案例:我是皇帝,独此一家。

中国自从秦始皇确立了皇帝这个职位之后,同一个时期基本上上就只有一个人孤零零的坐在皇位上啦。这种情况的 好处就是大家好办事,大家讨论或者汇报大事的时候只要提及皇帝,每个人都知道指的是谁,不需要在皇帝面前加 上特定的称呼。这种过程反应到软件设计领域就是:一个类只能产生一个对象(皇帝),大家对他的依赖都是相同 的。我们把皇帝这种特殊的职位通过程序来实现。

皇帝类:


image.png

大臣类:


image.png

运行结果:


image.png

大臣每天上朝汇报国事的对象都是同一个皇帝,这就是单例模式!

2.1.2 单例模式的定义以及特点

定义:

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
Ensure a class has only one instance,and provide a global point of access to it.

特点:

  • 单例类只有一个实例对象;
  • 该单例对象必须由单例类自行创建;
  • 单例类对外提供一个访问该单例的全局访问点。

2.1.3 单例模式的分类

上面的单例模式,在低并发的情况下可能不会出现问题,如果并发量增大,内存中就会出现多个实例,就不是真正 意义上的单例。为什么会出现这种情况呢?

解决线程不安全的方式有多种。我们先将上面代码的单例模式修改为线程安全的:

懒汉式单例:

image.png

该模式的特点是类加载时没有生成单例,只有当第一次调用 getlnstance 方法时才去创建这个单例。

关键字 volatile 和 synchronized,能保证线程安全,但是每次访问时都要同步,会影响性能,且消耗更多的资 源,这是懒汉式单例的缺点。

饿汉式单例:

image.png

该模式的特点是类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。而且该方式是线 程安全的。

2.1.4 单例模式的使用场景

  • 某类只要求生成一个对象的时候,如一个航班的机长、每个人的身份证号等。
  • 当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问 速度。如 Web 中的配置对象、数据库的连接池等。
  • 当某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。
  • 在计算机系统中, Windows 的回收站、操作系统中的文件系统、多线程中的线程池、显卡的驱动程序对象、 打印机的后台处理服务、应用程序的日志对象、数据库的连接池、网站的计数器、Web 应用的配置对象、应 用程序中的对话框、系统中的缓存等常常被设计成单例。

2.1.5 单例模式的优缺点

优点:

  • 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。
  • 避免对资源的多重占用(比如写文件操作)。
  • 单例模式可以在系统设置全局的访问点,优化和共享资源访问。

缺点:

  • 单例模式一般没有接口,扩展很困难。如果要扩展,只能修改代码。
  • 与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

2.1.6 单例模式的扩展

单例模式可扩展为有限的多例(Multitcm)模式,这种模式可生成有限个实例并保存在 ArrayList 中,客户需要时 可随机获取。

image.png

大臣类:

image.png

运行结果:PS:每个人的运行结果都不一样,因为随机数的产生不一致

image.png

2.2 工厂方法模式

2.2.1 什么是工厂模式?

引入案例:话说前一阵疫情期间,居家的时间有点长,于是我也跟广大网友一样,开始好好修炼自己的厨艺,有人 做凉皮,有人做锅巴。我也加入了霍霍面粉的大军--做面包。

于是和面、发面、捏成我想要的布朗熊的样子,开心放入烤箱 ,等待我的布朗熊面包出炉。然而,步骤没错,烤箱 没错,可能是大厨不对:

第一次:时间稍短了点,没太烤熟,于是布朗熊面包变成了北极熊面包;

再来一次:时间长点肯定能熟了,烤箱中多靠一会,出炉发现烤焦啦,与布朗熊面包变成了黑熊面包;

第三次:吸取教训,别跟时间死磕了,一直盯着烤箱中的面包好了,等到面包微微发焦,终于成功的做出了我想要 的布朗熊面包

好在家人给面子,每一种面包都有人吃掉哈。

在这个过程中,我的职业病就犯了,是不是可以通过软件开发来实现这个过程呢?

在面向对象的思想中,万物皆对象。是对象我们就可以通过软件设计来实现。来分析一下烤面包的过程,该过程涉 及三个对象:大厨(也就是我哈)、烤箱、三种不同成果的面包(我称他们为北极熊、黑熊、布朗熊)。

大厨可以使用场景类Client来表示,烤箱类似一个工厂,负责生产产品(即面包),三种不同成果的面包都是一个 接口下不同实现类,因为好不好吃好不好看也都是面包啊。

image.png image.png image.png image.png image.png

2.2.2 工厂方法模式的定义

定义:

定义一个用户创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

工厂方法模式的主要角色如下:

  1. 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
  2. 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对 应。

我们可以将工厂方法模式抽取出一个实用的通用代码:

image.png

2.2.3 工厂方法模式的应用场景

工厂方法模式通常适用于以下场景。

  • 客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。
  • 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
  • 客户不关心创建产品的细节,只关心产品的品牌。

2.3 抽象工厂模式

2.3.1 引入案例:

上回书说到我的烤面包副业已经小有成就,做的多了发现我的面包似乎缺少了灵魂,面包怎么能没有馅儿呢?!于 是打算将自己最爱的水果菠萝和芒果放入面包中。

大厨烤面包之前也是做了很多的准备工作的,所以想在不浪费现有资源的情况下继续完成新产品的制作。之前做的 面包中虽然大厨自己觉得布朗熊面包才是最成功的的,但是每个人的口味不一样,有人偏爱烤的过火的,有的偏爱 稍欠火候的。所以我决定继续满足所有人的口味:即将做出三种火候的菠萝面包和芒果面包。

即将要做的产品分析完了,可是我的工厂(面包机)真真只有一个烤面包的功能,于是为了做出蛋糕,又专门买了 一个烘焙蛋糕的烤箱。于是乎,可以准备干活啦!

image.png image.png image.png image.png

所有产品都出炉啦!

image.png

工厂方法模式只考虑生产同等级的产品,抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于 不同等级的一组产品称为一个产品族。

2.3.2 模式的定义与特点

抽象工厂(AbstractFactory)模式的定义:为创建一组相关或者相互依赖的对象提供一个接口,而且无须指定他们 的具体类。

抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是 一种非常好的解决方案。工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

使用抽象工厂模式一般要满足以下条件。

  • 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

2.3.3 抽象工厂的通用代码

image.png image.png image.png

2.3.4 抽象工厂模式的优缺点:

优点:

  • 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
  • 当增加一个新的产品族时不需要修改原代码,满足开闭原则。

其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

2.3.5 抽象工厂模式的应用场景

  1. 适合于产品之间相互关联、相互依赖且相互约束的地方
  2. 需要动态切换产品族的地方

2.4 建造者(Builder)模式

2.4.1 案例引入

老板:又签订了一个新合同,XX公司将宝马和奔驰两款车辆模型都交给我们公司制作了。不过这次有了新的需求: 汽车的启动、停止、鸣笛、引擎声音都由客户自己控制,他们想要什么顺序就什么顺序,OK吗?

我:OK!

来分析一下需求:宝马和奔驰两款车辆模型都是产品,他们有共有的属性,XX公司关心的是每个模型的运行过程, 期待奔驰A模型先有引擎声音再鸣笛,奔驰B模型是先启动再有引擎声音。老板的意思就是满足客户所有要求,要 什么顺序立刻就生成什么顺序的模型出来,而且能批量生成出来。

使用程序模拟实现这一需求:

image.png image.png image.png image.png image.png

看到运行结果,满足了一个需求,如果还有更多的不同顺序的需求怎么办呢?不停的写场景类来满足吗?很显然这 是一个问题,所以我们就要想一种方案来解决这个问题。

我们为每种产品模型定义一个建造者,要创建什么顺序直接通知建造者,由建造者来建造。使用程序模拟一下:

image.png image.png image.png

同样运行顺序的宝马车也出来了,而且代码比第一版直接访问产品类简单清晰。

我们在做项目的时候要知道:需求不可能一成不变的。我们案例中的4个过程(start stop alarm engineboom)按 照组合有很多种。客户可以随意组合,它是上帝,想要什么顺序我就要生成什么顺序的车模。怎么办呢?我们就需 要封装一下,找个导演来指挥各个事件的先后顺序,然后为每种顺序指定一个代码,你要什么我们立刻就可以提 供。

image.png image.png

有了这样的导演类之后,我们的场景类就更容易处理了。而且代码变得简单清晰。

其实我们上面用的就是建造者模式!

其实生活中还有更多的这样的案例。例如,计算机是由 OPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、 鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机 销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。

再例如游戏中的不同角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差异;还有汽车中的方向 盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相 同。

以上所有这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。这类产品的创建无 法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。

2.4.2 模式的定义与结构

2.4.2.1 建造者模式的定义:

指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者 模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组 成部分是不变的,但每一部分是可以灵活选择的。

2.4.2.2 模式的结构与实现

1. 模式的结构

建造者模式的主要角色如下。

  1. 产品(Product)类:它是包含多个组成部件的复杂对象,由具体建造者来创建其各个部件。
  2. 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产 品的方法 getResult()。
  3. 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
  4. 导演(Director)类:它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具 体产品的信息。

2. 模式的实现

image.png image.png image.png image.png image.png

2.4.3 建造者模式的优缺点

优点:

  1. 各个具体的建造者相互独立,有利于系统的扩展。
  2. 客户端不必知道产品内部组成的细节,便于控制细节风险。

缺点:

  1. 产品的组成部分必须相同,这限制了其使用范围。
  2. 如果产品的内部变化复杂,该模式会增加很多的建造者类。

建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零 部件的创建过程,但两者可以结合使用。

2.4.4 模式的应用场景

建造者(Builder)模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算 法却相对稳定,所以它通常在以下场合使用。

  • 相同的方法,不同的执行顺序,产生不同的实践结果
  • 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
  • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立 的。

2.5 原型模式

相关文章

  • 《设计模式之美》- 23种设计模式

    学习《设计模式之美》笔记。 23 种经典设计模式共分为 3 种类型,分别是创建型、结构型和行为型 创建型模式 创建...

  • 23种设计模式总结一

    23 种经典设计模式共分为 3 种类型,分别是创建型、结构型和行为型。 一、创建型设计模式 创建型设计模式包括:单...

  • Java设计模式——生成器模式

    Java设计模式之生成器模式 回顾 这期继续跟大家聊下创建型的设计模式,如果想了解其他创建类的设计模式有哪些,可以...

  • 简单工厂模式

    Android进阶之设计模式 简单工厂模式 简单工厂模式(又叫作静态工厂方法模式), 其属于创建型设计模式,但并不...

  • 设计模式之活学活用的工厂模式

    设计模式之活学活用的工厂模式 工厂模式简介 工厂模式是我们日常开发工作中经常使用的设计模式,它属于创建型设计模式,...

  • 建造者设计模式-Builder design pattern

    建造者设计模式是创建型设计模式的一种。创建型设计模式处理对象创建的问题。 建造者设计模式,用来构建需要经过若干个建...

  • 创建型设计模式总结

    创建型设计模式总结 Intro 前面几篇文章已经把创建型设计模式都介绍了,来做一个简单的总结。 创建型设计模式,就...

  • 单例模式

    单例 单例模式,是一种设计模式,属于创建型设计模式,还有一种创建型设计模式,工厂模式。设计模式总共有23种,三大类...

  • 设计模式简单总结(待完善)

    设计模式简单总结 设计模式可以分为:创建型,结构型,行为型三种模式。 1 创建型模式 1.1 单例模式 用来指定某...

  • 设计模式归纳

    一、设计模式的分类 23 种经典的设计模式分为三类:创建型、结构型、行为型。 1.创建型设计模式主要解决“对象的创...

网友评论

    本文标题:设计模式之创建型模式

    本文链接:https://www.haomeiwen.com/subject/dhvnqltx.html