一天一个设计模式——工厂方法(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 ...
随机推荐
- PCHMI工控组态开发视频教程
PCHMI是一款适合所有PLC工程师快速上手工控组态开发的控件 下面是视频教程链接 PCHMI工控组态 02-按钮的使用 PCHMI工控组态 03-数据显示器使用 PCHMI工控组态 04-标签控件的 ...
- linux中df和du查看磁盘大小不一致解决方法
挂了一块50G到/data目录下# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvdb1 50G 46G 1.2G 98% /dat ...
- C++面试常见问题——17类模板的使用
类模板的使用 注意在每次类模板函数时都需要声明一个类模板 #include<iostream> using namespace std; template <class T,int ...
- http协议请求报文与响应报文分析
什么是HTTP协议: HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到 不断地完善和扩展.目前在WWW中使用 ...
- eshop-环境配置
1. iptables # Generated by iptables-save v1. :: #*filter #:INPUT ACCEPT [:] #:FORWARD ACCEPT [:] #:O ...
- node - 读取cookie
req.headers.cookie
- Redis 详解 (五) redis的五大数据类型实现原理
目录 1.对象的类型与编码 ①.type属性 ②.encoding 属性和 *prt 指针 2.字符串对象 3.列表对象 4.哈希对象 5.集合对象 6.有序集合对象 7.五大数据类型的应用场景 8. ...
- HDU 4902 Nice boat 多校4 线段树
给定n个数 第一个操作和普通,区间覆盖性的,把l-r区间的所有值改成固定的val 第二个操作是重点,输入l r x 把l-r区间的所有大于x的数,变成gcd(a[i],x) a[i]即指满足条件的序列 ...
- Linux_Program 前台后台 切换 查看 kill 实用 mark
有时当我们在linux 上 输入 yum repolist 或 curl www.XXX. 时程序由已 :Intel或system 原因 按下 ctrl+z .在Linux终端运行命令的 ...
- RFX2401C与RFX2402E的区别
随着科技的发展,射频设备也慢慢的普及,射频放大器在射频设备中起着非常重要的作用.为了能获得足够大的距离,必须都要外加射频信号放大器. 射频信号放大器简称 “PA”.PA主流应用主要有ZigBee .无 ...