一天一个设计模式——工厂方法(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 ...
随机推荐
- k8s解析service地址方式
[root@k8s-master ~]# dig -t A kubernetes.default.svc.cluster.local. @10.96.0.10 ; <<>> D ...
- vue :src 不显示的解决方案
一定要将静态资源引入 [ require("@/assets/") ],绑定到 模型绑定的:src 数据中 动态的数据才能有效 <template> <d ...
- Oracle 的DBA考证
转自 :https://www.cnblogs.com/chunge2050/archive/2013/04/16/3023730.html 详细的了解了几天之后,总结起来就是oracle为DBA认证 ...
- [U53204] 树上背包的优化
题目链接 本文旨在介绍树上背包的优化. 可见例题,例题中N,M∈[1,100000]N,M \in [1,100000]N,M∈[1,100000]的数据量让O(nm2)O(nm^2)O(nm2)的朴 ...
- Day6 - L - Mokia HYSBZ - 1176
维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Input 第 ...
- 064、Java中递归调用
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 【转帖】影响超 10 亿设备,博通和 Cypress 芯片曝惊天漏洞,苹果、华为、三星等中招
影响超 10 亿设备,博通和 Cypress 芯片曝惊天漏洞,苹果.华为.三星等中招 https://www.infoq.cn/article/lpNEQGrxZL22gHDPBE2z 26 ...
- PHP数据库连接
<?php //设置编码格式 header("Content-type:text/html;charset=utf-8"); /** * Created by PhpStor ...
- excel处理经纬度
=LEFT(A1,FIND("°",A1)-1)*1+MID(A1,FIND("°",A1)+1,2)/60+MID(A1,FIND("′" ...
- LCT(1)
LCT(Link-Cut Tree,动态树)是一个支持动态修改树的结构的数据结构,其基本操作有 \(\texttt{access}\) , \(\texttt{findroot}\) , \(\tex ...