一天一个设计模式——工厂方法(FactoryMethod)模式
一、模式说明
在前一个模板方法(Template Method)模式中,父类定义了处理流程,而流程中用到的方法交给子类去实现。类似的,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类,具体的处理交由子类来处理。这样可以将生成实例的框架和实例本身解耦。
工厂方法模式在很多框架中都有用到,在面试中也问的比较多的,需要重点理解把握。
二、工厂方法(Factory Method)模式类图

三、工厂方法(Factory Method)模式中的角色
- Product产品类【框架】:定义了工厂方法模式生成的实例应该持有哪些接口。
- Creater创建者类【框架】:负责生成Product角色的抽象类。Creater角色对最终生成的实例是一无所知的,它只知道,只要调用Product角色和工厂方法(factoryMethod),就可以生成Product的实例,无需调用new方法,这样可以将父类和其他具体类耦合。
- ConreteProduct具体的产品类:工厂方法生成的具体产品。
- ConcreteCreater具体的创建者类:负责生成具体的产品。
四、工厂方法(Factory Method)代码示例:
1、模式框架类的创建,Product类:
package com.designpattern.cn.factorymethodpattern.patternframework;
public abstract class Product {
public abstract void use();
}
2、模式框架类的创建,Factory类:
package com.designpattern.cn.factorymethodpattern.patternframework;
public abstract class Factory {
public final Product create(String owner){
Product product = this.createProduct(owner);
this.registerProduct(product);
return product;
}
protected abstract Product createProduct (String owner);
protected abstract void registerProduct(Product product);
}
3、模式实现类,IDCard身份证类:
package com.designpattern.cn.factorymethodpattern.patterndemostrate;
import com.designpattern.cn.factorymethodpattern.patternframework.Product;
public class IDCard extends Product {
private String owner;
IDCard(String owner){
System.out.println("制作" + owner + "的ID卡");
this.owner = owner;
}
public void use(){
System.out.println("使用" + this.owner + "的ID卡");
}
public String getOwner() {
return owner;
}
}
4、模式实现类,IDCardFactory类:
package com.designpattern.cn.factorymethodpattern.patterndemostrate; import com.designpattern.cn.factorymethodpattern.patternframework.Factory;
import com.designpattern.cn.factorymethodpattern.patternframework.Product; import java.util.ArrayList;
import java.util.List; public class IDCardFactory extends Factory {
private List owners = new ArrayList();
protected Product createProduct(String owner){
return new IDCard(owner);
} protected void registerProduct(Product product){
owners.add(((IDCard)product).getOwner());
} public List getOwners(){
return owners;
}
}
5、Main方法类与运行结果:

上面的代码示例中,工厂模式的createProduct是一个抽象方法,必须在子类中实现该方法,具体可以选择三种实现方式:
- 指定其为抽象方法,如同上面的代码示例一样;
- 为其实现默认处理:
public Product createProduct(String name){
return new Product(name);
}
如果采用这种方式,Product类就不能定义为抽象类。
3.抛出异常的方式:
public Product createProduct(String name){
throw new FactoryMethodRuntimeException();
}
这样一来,就必须在子类中重写该方法,否则会抛出异常。
五、工厂方法(Factory Method)模式相关的模式
- 模板方法(Template Method)模式:工厂方法模式是模板方法模式的典型应用,工厂方法中的createProduct就是模板方法。
- 单例模式(Singleton):工厂方法模式中,具体的创建者角色(上例中的IDCardFactory)类,可以设计为单例模式,因为程序中没有必要存在多个创建者角色的实例(后续学习到单例模式时再回头修改这个示例)。
- 组合(Composite)模式:将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。工厂方法模式中的Creater和ConcreteCreater对象可以用到该模式。
- 迭代器(Iterator)模式:在迭代器模式中,使用iterator方法生成Iterator实例时,会使用工厂方法模式。
一天一个设计模式——工厂方法(FactoryMethod)模式的更多相关文章
- 设计模式之工厂方法(FactoryMethod)模式
在五大设计原则的基础上经过GOF(四人组)的总结,得出了23种经典设计模式,其中分为三大类:创建型(5种).结构型(7种).行为型(11种).今天对创建型中的工厂方法(FactoryMethod)模式 ...
- 工厂方法(FactoryMethod)模式
之前说了简单工厂设计模式如果增加一个新的运算的时候需要:增加一个具体的实现类,工厂类中增加一个case分支.也就是说我们不但对扩展开发了,也对修改开放了,违背了开闭原则.当然如果工厂类采用反射的话不存 ...
- 一天一个设计模式——模板方法(Template Method)模式
一.模式说明 现实世界中的模板是用于将事物的结构规律予以固定化.标准化的成果,它体现了结构形式的标准化.例如镂空文字印刷的模板,通过某个模板印刷出来的文字字体大小都是一模一样,但是具体使用什么材质的颜 ...
- 4. 星际争霸之php设计模式--工厂方法模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- C++设计模式——工厂方法模式
本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.» 本文链接:http://www.jellythink.com/arch ...
- 工厂方法FactoryMethod 初步学习笔记
一,意图 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 二,别名 虚构造器 Virtual Constructor 三,适用性 当一个类不知道它 ...
- 设计模式-工厂方法模式(FactoryMethod)
简介: 简单工厂模式将类的示例化放在工厂对象中. 工厂方法模式是简单工厂模式的延伸,不同的是其将子类的实例化延迟到子类工厂中实现,本身仅定义一个创建对象的接口. 工厂方法模式主要由四部分组成: 1.抽 ...
- Java设计模式---工厂方法模式(Factory-Method)
一.普通工厂模式 建立一个工厂类,对实现了同一接口的一些类进行实例的创建 实例代码: 发送短信和邮件的例子,首先创建接口: public interface Sender { public void ...
- Python设计模式——工厂方法模式(FactoryMethod)
需求:有一个学雷锋活动,有买米和扫地两个内容,参与的人有大学生和社区志愿者,他们各自的方法不一样. 如果用简单工厂模式实现: #encoding=utf-8 __author__ = 'kevinlu ...
随机推荐
- pygame库的学习
第一天:我学习了如何设置窗口和加载图片,以及加载音乐.这个库真的很有意思啊,打算py课设就拿这个写了. 代码: import pygamefrom sys import exit pygame.ini ...
- is application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem
最近试着了解 c++,接触到了QT,写了一个测试程序,在开发环境下正常后移到非开发环境,报错 网上找资料说是少了platforms文件夹中的dll,把里面所有的dll复制到执行程序目录,还是提示,继续 ...
- mysql多实例双主部署
本文引自公司技术文档,仅作为记录. 背景 有的时候需要进行数据库环境的隔离,以及节省服务器资源一台mysql安装多个数据库实例,一个实例下构建多个数据库 安装mysql yum -y install ...
- 再次实践 MySQL chart【转】
学习了 chart 结构和模板的知识后,现在重新实践一次 MySQL chart,相信会有更多收获. chart 安装前的准备 作为准备工作,安装之前需要先清楚 chart 的使用方法.这些信息通常记 ...
- MyBatis源码部分简单地解析
. 一.解析xml: > org.apache.ibatis.session.SqlSessionFactoryBuilder.build(java.io.InputStream, java.l ...
- mysql性能优化及 Comparison method violates its general contract
项目上嵌套结果集查询,查询的列表再根据每个id进行查询计算,嵌套的sql如下: SELECT SUM(IFNULL(t.out_rate,0)) totalOutRate, SUM(IF(IFNULL ...
- JAVA基础-反射机制
什么是JAVA的反射机制 Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其 ...
- linux 查看ip、用户、时间对应执行的命令
这个需要使用到history命令.可以加数字,返回最近执行的几条命令.如果不加数字会返回所有的历史命令. [root@localhost ~]# history 20 1015 rm stdin.lo ...
- angularJS 服务
- delphi中json转dataset
unit uJSONDB; interface uses SysUtils, Classes, Variants, DB, DBClient, SuperObject, Dialogs; type T ...