研磨设计模式之工厂方法模式(Factory Method)-模式讲解1
3 模式讲解
3.1 认识工厂方法模式
(1)模式的功能
工厂方法的主要功能是让父类在不知道具体实现的情况下,完成自身的功能调用,而具体的实现延迟到子类来实现。
这样在设计的时候,不用去考虑具体的实现,需要某个对象,把它通过工厂方法返回就好了,在使用这些对象实现功能的时候还是通过接口来操作,这非常类似于IoC/DI的思想,这个在后面给大家稍详细点介绍一下。
(2)实现成抽象类
工厂方法的实现中,通常父类会是一个抽象类,里面包含创建所需对象的抽象方法,这些抽象方法就是工厂方法。
这里要注意一个问题,子类在实现这些抽象方法的时候,通常并不是真的由子类来实现具体的功能,而是在子类的方法里面做选择,选择具体的产品实现对象。
父类里面,通常会有使用这些产品对象来实现一定的功能的方法,而且这些方法所实现的功能通常都是公共的功能,不管子类选择了何种具体的产品实现,这些方法的功能总是能正确执行。
(3)实现成具体的类
当然也可以把父类实现成为一个具体的类,这种情况下,通常是在父类中提供获取所需对象的默认实现方法,这样就算没有具体的子类,也能够运行。
通常这种情况还是需要具体的子类来决定具体要如何创建父类所需要的对象。也把这种情况称为工厂方法为子类提供了挂钩,通过工厂方法,可以让子类对象来覆盖父类的实现,从而提供更好的灵活性。
(4)工厂方法的参数和返回
工厂方法的实现中,可能需要参数,以便决定到底选用哪一种具体的实现。也就是说通过在抽象方法里面传递参数,在子类实现的时候根据参数进行选择,看看究竟应该创建哪一个具体的实现对象。
一般工厂方法返回的是被创建对象的接口对象,当然也可以是抽象类或者一个具体的类的实例。
(5)谁来使用工厂方法创建的对象
这里首先要搞明白一件事情,就是谁在使用工厂方法创建的对象?
事实上,在工厂方法模式里面,应该是Creator中的其它方法在使用工厂方法创建的对象,虽然也可以把工厂方法创建的对象直接提供给Creator外部使用,但工厂方法模式的本意,是由Creator对象内部的方法来使用工厂方法创建的对象,也就是说,工厂方法一般不提供给Creator外部使用。
客户端应该是使用Creator对象,或者是使用由Creator创建出来的对象。对于客户端使用Creator对象,这个时候工厂方法创建的对象,是Creator中的某些方法使用。对于使用那些由Creator创建出来的对象,这个时候工厂方法创建的对象,是构成客户端需要的对象的一部分。分别举例来说明。
①客户端使用Creator对象的情况
比如前面的示例,对于“实现导出数据的业务功能对象”的类ExportOperate,它有一个export的方法,在这个方法里面,需要使用具体的“导出的文件对象的接口对象” ExportFileApi,而ExportOperate是不知道具体的ExportFileApi实现的,那么怎么做的呢?就是定义了一个工厂方法,用来返回ExportFileApi的对象,然后export方法会使用这个工厂方法来获取它所需要的对象,然后执行功能。
这个时候的客户端是怎么做的呢?这个时候客户端主要就是使用这个ExportOperate的实例来完成它想要完成的功能,也就是客户端使用Creator对象的情况,简单描述这种情况下的代码结构如下:
/** * 客户端使用Creator对象的情况下,Creator的基本实现结构 */ public abstract class Creator { /** * 工厂方法,一般不对外 * @return 创建的产品对象 */ protected abstract Product factoryMethod(); /** * 提供给外部使用的方法, * 客户端一般使用Creator提供的这些方法来完成所需要的功能 */ public void someOperation(){ //在这里使用工厂方法 Product p = factoryMethod(); } } |
②客户端使用由Creator创建出来的对象
另外一种是由Creator向客户端返回由“工厂方法创建的对象”来构建的对象,这个时候工厂方法创建的对象,是构成客户端需要的对象的一部分。简单描述这种情况下的代码结构如下:
/** * 客户端使用Creator来创建客户端需要的对象的情况下,Creator的基本实现结构 */ public abstract class Creator { /** * 工厂方法,一般不对外,创建一个部件对象 * @return 创建的产品对象,一般是另一个产品对象的部件 */ protected abstract Product1 factoryMethod1(); /** * 工厂方法,一般不对外,创建一个部件对象 * @return 创建的产品对象,一般是另一个产品对象的部件 */ protected abstract Product2 factoryMethod2(); /** * 创建客户端需要的对象,客户端主要使用产品对象来完成所需要的功能 * @return 客户端需要的对象 */ public Product createProduct(){ //在这里使用工厂方法,得到客户端所需对象的部件对象 Product1 p1 = factoryMethod1(); Product2 p2 = factoryMethod2();
//工厂方法创建的对象是创建客户端对象所需要的 Product p = new ConcreteProduct(); p.setProduct1(p1); p.setProduct2(p2);
return p; } } |
小结一下:在工厂方法模式里面,客户端要么使用Creator对象,要么使用Creator创建的对象,一般客户端不直接使用工厂方法。当然也可以直接把工厂方法暴露给客户端操作,但是一般不这么做。
(6)工厂方法模式的调用顺序示意图
由于客户端使用Creator对象有两种典型的情况,因此调用的顺序示意图也分做两种情况,先看看客户端使用由Creator创建出来的对象情况的调用顺序示意图,如图.5所示:
图5 客户端使用由Creator创建出来的对象的调用顺序示意图
接下来看看客户端使用Creator对象时候的调用顺序示意图,如图6所示:
图6 客户端使用Creator对象的调用顺序示意图
本文链接:研磨设计模式之工厂方法模式(Factory Method)-模式讲解1,转自:http://chjavach.iteye.com/blog/692792
知识点
相关教程
更多研磨设计模式之工厂方法模式(Factory Method)-模式讲解2
3.2 工厂方法模式与IoC/DI,IoC——Inversion of Control 控制反转,DI——Dependency Injection 依赖注入,1:如何理解IoC/DI 要想理解上面两个概念,就必须搞清楚如下的问题...
研磨设计模式之工厂方法模式(Factory Method)-模式讲解3
3.3 平行的类层次结构(1)什么是平行的类层次结构呢?简单点说,假如有两个类层次结构,其中一个类层次中的每个类在另一个类层次中都有一个对应的类的结构,就被称为平行的类层次结构...
研磨设计模式之工厂方法模式(Factory Method)-场景问题
1.1 导出数据的应用框架,考虑这样一个实际应用:实现一个导出数据的应用框架,来让客户选择数据的导出方式,并真正执行数据导出。在一些实际的企业应用中,一个公司的系统往往分散在很多个不同的地方运行...
研磨设计模式之工厂方法模式(Factory Method)-解决方案
2.1 工厂方法模式来解决 用来解决上述问题的一个合理的解决方案就是工厂方法模式。那么什么是工厂方法模式呢?(1)工厂方法模式定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到其子类...
JAVA设计模式学习5——工厂方法模式
工厂方法模式(Factory Method)又称虚拟构造子模式,可以说是简单工厂的抽象,也可以理解为简单工厂是退化了的工厂方法模式,其表现在简单工厂丧失了工厂方法的多态性。我们前一节中提到当产品结构变的复杂的时候,简单工厂就变的难以应付,如果增加一种产品,核心工厂类必须改动,使得整个工厂的可扩展性变得很差,对开闭原则支持不够。工厂方法模式克服了这些缺点,它定义一个创建产品对象的工厂接口,将实际创建
研磨设计模式之简单工厂模式(模式讲解)
根据前面的学习,我们知道接口是用来封装隔离具体的实现的,目标就是不要让客户端知道封装体内部的具体实现。简单工厂的位置是位于封装体内的,也就是简单工厂是跟接口和具体的实现在一起的,算是封装体内部的一个类,所以简单工厂知道具体的实现类是没有关系的。
研磨设计模式之抽象工厂模式(Abstract Factory)-场景问题
举个生活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如:CPU、硬盘、内存、主板、电源、机箱等等。为了使讨论简单点,只考虑选择CPU和主板的问题...
研磨设计模式之简单工厂模式(场景问题)
简单工厂不是一个标准的设计模式,但是它实在是太常用了,简单而又神奇,所以还是需要好好掌握的,就当是对学习设计模式的热身运动吧。为了保持一致性,我们尽量按照学习其它模式的步骤来进行学习。
研磨设计模式之适配器模式(Adapter)-模式讲解
4.3 模式讲解 4.3.1 认识适配器模式(1)模式的功能 适配器模式的主要功能是进行转换匹配,目的是复用已有的功能,而不是来实现新的接口。也就是说,客户端需要的功能应该是已经实现好了的,不需要适配器模式来实现,适配器模式主要负责把不兼容的接口转换成客户端期望的样子就好了...
研磨设计模式之外观模式(Facade)(模式讲解)
(1)外观模式的目的 外观模式的目的不是给子系统添加新的功能接口,而是为了让外部减少与子系统内多个模块的交互,松散耦合,从而让外部能够更简单的使用子系统。
研磨设计模式之单例模式(Singleton)-模式讲解1
3.1 认识单例模式(1)单例模式的功能 单例模式的功能是用来保证这个类在运行期间只会被创建一个类实例,另外单例模式还提供了一个全局唯一访问这个类实例的访问点,就是那个getInstance的方法。不管采用懒汉式还是饿汉式的实现方式,这个全局访问点是一样的...
研磨设计模式之单例模式(Singleton)-模式讲解2
3.3 延迟加载的思想 单例模式的懒汉式实现方式体现了延迟加载的思想,什么是延迟加载呢?通俗点说,就是一开始不要加载资源或者数据,一直等,等到马上就要使用这个资源或者数据了,躲不过去了才加载,所以也称Lazy Load,不是懒惰啊,是“延迟加载”...
研磨设计模式之单例模式(Singleton)-模式讲解3
3.8 在Java中一种更好的单例实现方式,根据上面的分析,常见的两种单例实现方式都存在小小的缺陷,那么有没有一种方案,既能够实现延迟加载,又能够实现线程安全呢?还真有高人想到这样的解决方案了...
设计模式-工厂模式
JAVA设计模式学习4——简单工厂模式
从这节开始学习设计模式,首先学习创建模式,其中工厂模式是创建模式里面最常见也常用的一种,工厂模式又分简单工厂模式(Simple Factory),工厂方法模式(Factory Method)和抽象工厂模式(Abstractor Factory),这里先学习最简单的也就是简单工厂模式。 简单工厂模式(Simple Factory)也称静态工厂方法模式,是工厂方法模式的特殊实现。简单工厂模式的一般性结
最新教程
更多java线程状态详解(6种)
java线程类为:java.lang.Thread,其实现java.lang.Runnable接口。 线程在运行过程中有6种状态,分别如下: NEW:初始状态,线程被构建,但是还没有调用start()方法 RUNNABLE:运行状态,Java线程将操作系统中的就绪和运行两种状态统称为“运行状态” BLOCK:阻塞状态,表示线程阻塞
redis从库只读设置-redis集群管理
默认情况下redis数据库充当slave角色时是只读的不能进行写操作,如果写入,会提示以下错误:READONLY You can't write against a read only slave. 127.0.0.1:6382> set k3 111 (error) READONLY You can't write against a read only slave. 如果你要开启从库
Netty环境配置
netty是一个java事件驱动的网络通信框架,也就是一个jar包,只要在项目里引用即可。
Netty基于流的传输处理
在TCP/IP的基于流的传输中,接收的数据被存储到套接字接收缓冲器中。不幸的是,基于流的传输的缓冲器不是分组的队列,而是字节的队列。 这意味着,即使将两个消息作为两个独立的数据包发送,操作系统也不会将它们视为两个消息,而只是一组字节(有点悲剧)。 因此,不能保证读的是您在远程定入的行数据
Netty入门实例-使用POJO代替ByteBuf
使用TIME协议的客户端和服务器示例,让它们使用POJO来代替原来的ByteBuf。
Netty入门实例-时间服务器
Netty中服务器和客户端之间最大的和唯一的区别是使用了不同的Bootstrap和Channel实现
Netty入门实例-编写服务器端程序
channelRead()处理程序方法实现如下
Netty开发环境配置
最新版本的Netty 4.x和JDK 1.6及更高版本
电商平台数据库设计
电商平台数据库表设计:商品分类表、商品信息表、品牌表、商品属性表、商品属性扩展表、规格表、规格扩展表
HttpClient 上传文件
我们使用MultipartEntityBuilder创建一个HttpEntity。 当创建构建器时,添加一个二进制体 - 包含将要上传的文件以及一个文本正文。 接下来,使用RequestBuilder创建一个HTTP请求,并分配先前创建的HttpEntity。
MongoDB常用命令
查看当前使用的数据库 > db test 切换数据库 > use foobar switched to db foobar 插入文档 > post={"title":"领悟书生","content":"这是一个分享教程的网站","date":new
快速了解MongoDB【基本概念与体系结构】
什么是MongoDB MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era. MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
windows系统安装MongoDB
安装 下载MongoDB的安装包:mongodb-win32-x86_64-2008plus-ssl-3.2.10-signed.msi,按照提示步骤安装即可。 安装完成后,软件会安装在C:\Program Files\MongoDB 目录中 我们要启动的服务程序就是C:\Program Files\MongoDB\Server\3.2\bin目录下的mongod.exe,为了方便我们每次启动,我
Spring boot整合MyBatis-Plus 之二:增删改查
基于上一篇springboot整合MyBatis-Plus之后,实现简单的增删改查 创建实体类 添加表注解TableName和主键注解TableId import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baom
分布式ID生成器【snowflake雪花算法】
基于snowflake雪花算法分布式ID生成器 snowflake雪花算法分布式ID生成器几大特点: 41bit的时间戳可以支持该算法使用到2082年 10bit的工作机器id可以支持1024台机器 序列号支持1毫秒产生4096个自增序列id 整体上按照时间自增排序 整个分布式系统内不会产生ID碰撞 每秒能够产生26万ID左右 Twitter的 Snowflake分布式ID生成器的JAVA实现方案