第三篇 设计模式 之 创建者模式


目的:① 减少内存损耗。② 资源优化(减少CPU的占用和网络资源的占用)。③ 创建和使用分离。④ 将复杂的创造过程简单化。

设计模式说明
单例(Singleton)模式某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其扩展是有限多例模式。
原型(Prototype)模式将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
工厂方法(Factory Method)定义一个用于创建产品的接口,由子类决定生产什么产品。
抽象工厂(AbstractFactory)模式提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。
建造者(Builder)模式将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。

单例模式

单例模式的定义

类只建一个实例。

单例模式的目的

① 为了节省内存资源。② 保存数据内容的一致性。

单例的案例

① 多线程中的线程池。② 显卡的启动程序对象。③ 打印机的后台处理服务。④ 应用程序的日志对象。⑤ 数据库的连接池。⑥ 网站的计数器。⑦ Web应用的配置对象。⑧ 应用程序中的对话框。⑨ 系统中的缓存。

Java框架应用

J2EE标准中的ServletContext和ServletContextConfig、Spring框架应用中的ApplicationContext。
(5) 单例模式的特点:
① 单例类只有一个实例对象。② 该单例对象必须由单例类自行创建。③ 单例类对外提供一个访问该单例的全局访问点。

单例模式的优点和缺点

优点:
① 单例模式可以保证内存里只有一个实例,减少了内存的开销。
② 可以避免对资源的多重占用。
③ 单例模式设置了全局访问点,可以优化和共享资源的访问。

缺点:
① 单例模式一般没有接口,扩展困难。如果要扩展,则除了修改原来的代码,没有第二种途径,违背开闭原则。
② 在并发测试中,单例模式不利于代码调试。在调试过程中,如果单例中的代码没有执行完,也不能模拟生成一个新的对象。
③ 单例模式的功能代码通常写在一个类中,如果功能设计不合理,则很容易违背单一职责原则。

单例模式的应用场景

① 需要频繁创建一些类,使用单例可以降低系统的内存压力,减少GC。
② 某类只要求生成一个对象的时候。
③ 某些类创建实例时占用资源比较多,或实例化耗时较长,且经常使用。
④ 某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。
⑤ 频繁访问数据库或文件的对象。
⑥ 对于一些控制硬件级别的操作,或者从系统上来讲应当是单一控制逻辑的操作,如果有多个实例,则系统会完全乱套。
⑦ 当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如Web中的配置对象、数据库的连接池等。

单例模式的结构

① 单例类:包含一个实例且能自行创建这个实例的类。
② 访问类:使用单例的类。
请添加图片描述

单例模式实现的两种方式

懒汉式:第一次调用才会生成对象。
饿汉式:程序启动以后就有对象了。

原型模式

原型设计模式的定义与特点

定义:用一个已经创建的实例化作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。

优点

① Java自带的原型模式基于内存二进制流的复制,在性能上比直接new一个对象更加优良。
② 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程。

原型模式的结构与实现

① Java提供了对象的clone()方法。

角色

① 抽象原型类:规定了具体原型对象必须实现的接口。
② 具体原型类:实现抽象原型类的clone() 方法,它是可被复制的对象。
③ 访问类:使用具体原型类的clone()方法来复制新的对象。
请添加图片描述

模型的实现

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

应用

① Object类提供了浅克隆的clone()方法
② 具体原型类只要实现Cloneeable接口就可实现对象的浅克隆(cloneable接口就是抽象原型类)。
③【例1】用原型模式生成"三好学生奖状。
分析:同一学校的"三好学生"奖状除了获奖人姓名不同,其他都相同,属于相似对象的复制,同样可以用原型模式创建,然后再做简单修改就可以了。图4所示是三好学生奖状生成器的结构图。
请添加图片描述

原型模式的应用场景

(1) 对象之间相同或相似,即只是个别的几个属性不同的时候。
(2) 创建对象成本较大,例如初始化时间常,占用CPU太多,或者占用网络资源太多等,需要优化资源。
(3) 创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性。
(4) 系统中大量使用该类对象,且各个调用者都需要给它的属性重新赋值。
在Spring中,原型模式应用的非常广泛,例如scope=‘prototype’、JSON.parseObject()等都是原型模式的具体应用。

原型模式的扩展

原型模式可扩展为带原型管理器的原型模式,它在原型模式的基础上增加了一个原型管理器PrototypeManager类。该类用HashMap保存多个复制的原型,Client 类可以通过管理器的get(String id)方法从中获取复制的原型。其结构图如图5所示
请添加图片描述
【例2】用带原型管理器的原型模式来生成包含圆和正方形等图形的原型,并计算其面积。分析:本实例中由于存在不同的图形类,例如,"圆和“"正方形,它们计算面积的方法不一样,所以需要用一个原型管理器来管理它们,图6所示是其结构图,
请添加图片描述

简单工厂模式

工厂模式的定义

定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离"的特点。

按实际业务场景划分

工厂模式有3种不同的实现方式,分别是
① 简单工模式
② 工厂方法模式
③ 抽象工厂模式
我们把被创建的对象称为"产品”,把创建产品的对象称为"工厂。如果要创建的产品不多,

简单工厂/静态工厂

只要一个工厂类就可以完成,这种模式叫简单工厂模式”"。
在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattem)又叫作静态工厂方法模式.

简单来说,简单工厂模式有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式。
简单工厂模式每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度,违背了"开闭原则"。

应用场景

对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。
模式的结构与实现
简单工厂模式的主要角色如下:
.简单工厂(SimpleFactory);是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
.抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
.具体产品(ConcreteProduct):是简单工厂模式的创建日标。

请添加图片描述

工厂方法模式

在《简单工厂模式》一节我们介绍了简单工厂模式,提到了简单工厂模式违背了开闭原则,而"工厂方法模式"是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品。即满足开闭原则。

优点与缺点

优点
① 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具休创建过程。
② 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
③ 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则,

缺点
① 类的个数容易过多,增加复杂度
② 增加了系统的抽象性和理解难度
③ 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。

应用场景

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

模式的结构与实现

工厂方法模式由抽象工厂、具体工厂、抽象产品和具体休产品等4个要素构成。本节来分析其基本结构和实现方法。
1.模式的结构
工厂方法模式的主要角色如下。
1.抽象工厂(AbstractFactory)∶提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct()来创建产品。
2.具体工厂(ConcreteFactory):主要是实现抽象T厂中的抽象方法,完成具体产品的创建。
3.抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
4.具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具休工厂来创建,它同具体工厂之间— —对应,
其结构图如图1所示。
请添加图片描述
模式的应用实例
【例1】用工厂方法模式设计畜牧场。
分析:有很多种类的畜牧场,如养马场用于养马,养牛场用于养牛,所以该实例用工厂方法模式比较适合。
对养马场和养牛场等具休工厂类,只要定义一个生成动物的方法newAnimal()即可。由于要显示马类和牛类等具休产品类的图像,所以它们的构造函数中用到了JPanel、JLabd和Imagelcon等组件,并定义一个show()方法来显示它们.
在这里插入图片描述

抽象工厂模式

前面介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。
同种类称为同等级,也就是说:工厂方法模式只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类)的产品,如农场里既养动物又种植物,电器厂既生产电视机又生产洗衣机或空调,大学既有软件专业又有生物专业等。
本节要介绍的抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族
例如:海尔工厂和TCL工厂所生产的电视机与空调对应的关系图。

模式的定义与特点

抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品.

使用抽象工厂模式一般要满足以下条件。
① 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。·
② 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

优点和缺点

抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。
① 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。·当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组
② 抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
缺点
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。

模式的结构与实现

抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等4个要索构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。现在我们来分析其基本结构和实现方法。
1.模式的结构
抽象工厂模式的主要角色如下。
1.抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
2.具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
3.抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
4.具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系.
请添加图片描述

【例1】用抽象工厂模式设计农场类。
分析:农场中除了像畜牧场一样可以养动物,还可以培养植物,如养马、养牛、种水果、种蔬菜等,所以本实例比前面介绍的畜牧场类复杂,必须用抽象工厂模式来实现。
本例用抽象工厂模式来设计两个农场,一个是留关农场用于养牛和种菜,一个是上饶农场用于养马和种水果,可以在以上两个农场中定义一个生成动物的方法newAnimal()和一个培养植物的方法newPlant().
对马类、牛类、蔬菜类和水果类等具体产品类,由于要显示它们的图像,所以它们的构造函数中用到了JPanel、JLabel和Imagelcon等组件,并定义─个show()方法来显示它们。
请添加图片描述

抽象模式总结

抽象工厂模式的扩展有一定的“开闭原则"倾斜性;
1.当增加一个新的产品族时只需增加一个新的具体工厂,不需要修改原代码,满足开闭原则。
⒉当产品族中需要增加一个新种类的产品时,则所有的工厂类都需要进行修改,不满足开闭原则。
另一方面,当系统中只存在一个等级结构的产品时,抽象工厂模式将退化到工厂方法模式。

建造者(Builder)模式

在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。
例如,计算机是由CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。
生活中这样的例子很多,如游戏中的不同角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差异;还有汽车中的方盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相同。
以上所有这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。这类产品的创建无法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。

模式的定义与特点

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

优点和缺点

该模式的主要优点如下:
1.封装性好,构建和表示分离。
2.扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
3.客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
其缺点如下:
1.产品的组成部分必须相同,这限制了其使用范围。
2.如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期佳护成本较大。
建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用。

模式的结构与实现

建造者(Builder)模式出产品、抽象建造者、具体建造者、指挥者等4个要素构成,现在我们来分析其基本结构和实现方法
1.模式的结构
建造者(Builder)模式的主要角色如下。
① 产品角色(Product) :它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
② 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()
③ 具体建造者(Concrete Builder):实现 Builder接口,完成复杂产品的各个部件的具体创建方法。
④ 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
其结构图如图1所示。
请添加图片描述

模式的应用场景

建造者模式唯一区别于工厂模式的是针对复杂对象的创建。也就是说,如果创建简单对象,通常都是使用工厂模式进行创建,而如果创建复杂对象,就可以考虑使用建造者模式。
当需要创建的产品具备复杂创建过程时,可以抽取出共性创建过程,然后交由具体实现类自定义创建流程,使得同样的创建行为河可以生产出不同的产品,分离了创建与表示,使创建产品的灵活性大大增加。
建造者模式主要适用于以下应用场景:
① 相同的方法,不同的执行顺序,产生不同的结果。
② 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。·产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
③ 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。

建造者模式和工厂模式的区别

通过前面的学习,我们已经了解了建造者模式,那么它和工厂模式有什么区别呢?
① 建造者模式更加注重方法的调用顺序,工厂模式注中创建对象。
② 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样。
③ 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-攀-登-者-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值