一、模式说明

  在前一个模板方法(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是一个抽象方法,必须在子类中实现该方法,具体可以选择三种实现方式:

  1. 指定其为抽象方法,如同上面的代码示例一样;
  2. 为其实现默认处理:

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)模式的更多相关文章

  1. 设计模式之工厂方法(FactoryMethod)模式

    在五大设计原则的基础上经过GOF(四人组)的总结,得出了23种经典设计模式,其中分为三大类:创建型(5种).结构型(7种).行为型(11种).今天对创建型中的工厂方法(FactoryMethod)模式 ...

  2. 工厂方法(FactoryMethod)模式

    之前说了简单工厂设计模式如果增加一个新的运算的时候需要:增加一个具体的实现类,工厂类中增加一个case分支.也就是说我们不但对扩展开发了,也对修改开放了,违背了开闭原则.当然如果工厂类采用反射的话不存 ...

  3. 一天一个设计模式——模板方法(Template Method)模式

    一.模式说明 现实世界中的模板是用于将事物的结构规律予以固定化.标准化的成果,它体现了结构形式的标准化.例如镂空文字印刷的模板,通过某个模板印刷出来的文字字体大小都是一模一样,但是具体使用什么材质的颜 ...

  4. 4. 星际争霸之php设计模式--工厂方法模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  5. C++设计模式——工厂方法模式

    本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.» 本文链接:http://www.jellythink.com/arch ...

  6. 工厂方法FactoryMethod 初步学习笔记

    一,意图   定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 二,别名   虚构造器 Virtual Constructor 三,适用性 当一个类不知道它 ...

  7. 设计模式-工厂方法模式(FactoryMethod)

    简介: 简单工厂模式将类的示例化放在工厂对象中. 工厂方法模式是简单工厂模式的延伸,不同的是其将子类的实例化延迟到子类工厂中实现,本身仅定义一个创建对象的接口. 工厂方法模式主要由四部分组成: 1.抽 ...

  8. Java设计模式---工厂方法模式(Factory-Method)

    一.普通工厂模式 建立一个工厂类,对实现了同一接口的一些类进行实例的创建 实例代码: 发送短信和邮件的例子,首先创建接口: public interface Sender { public void ...

  9. Python设计模式——工厂方法模式(FactoryMethod)

    需求:有一个学雷锋活动,有买米和扫地两个内容,参与的人有大学生和社区志愿者,他们各自的方法不一样. 如果用简单工厂模式实现: #encoding=utf-8 __author__ = 'kevinlu ...

随机推荐

  1. Mapreduce实例——WordCount

    实验步骤 切换目录到/apps/hadoop/sbin下,启动hadoop. cd /apps/hadoop/sbin ./start-all.sh 2.在linux上,创建一个目录/data/map ...

  2. CSS - flex使行内元素快速对齐

    div{ display:flex; alian-items:center; //使垂直对齐 justify-content:center //使水平对齐 }

  3. es678910语法糖

    傲娇: 新es是js的进步,是编程的进步,es6已经过去了5年了,兼容率达到了90%,还是有10%的手机不兼容,那到底应不应该去照顾那些跟不上的人,我觉得是不应该的,新es能5行写出来的功能,我为什么 ...

  4. python手动实现深拷贝

    深拷贝是将对象全拷贝,包括嵌套对象 def deepcopy(cls): if isinstance(cls, dict): dct = {} for k, v in cls.items(): dct ...

  5. Educational Codeforces Round 64 选做

    感觉这场比赛题目质量挺高(A 全场最佳),难度也不小.虽然 unr 后就懒得打了. A. Inscribed Figures 题意 给你若干个图形,每个图形为三角形.圆形或正方形,第 \(i\) 个图 ...

  6. MongoDB_01

    解释:MongoDB可应对 --三高需求 High performance-对数据库高并发读写的需求 Huge Storage -对海量数据的高效率存储和访问的需求 High Scalability ...

  7. 官网英文版学习——RabbitMQ学习笔记(八)Remote procedure call (RPC)

    在第四篇学习笔记中,我们学习了如何使用工作队列在多个工作者之间分配耗时的任务.   但是,如果我们需要在远程计算机上运行一个函数并等待结果呢?这是另一回事.这种模式通常称为远程过程调用或RPC.   ...

  8. 官网英文版学习——RabbitMQ学习笔记(四)Work queues

    工作队列:把每个任务只发送给一个工作者. 上一篇我们是从一个指定的队列发送接收消息,在本文中,我们将创建一个工作队列,用于在多个工作者之间分配耗时的任务. 工作队列(即任务队列)背后的主要思想是避免立 ...

  9. 我的Java语言学习日志1_"简单的银行管理系统实现"

    设计步骤:注意:本篇代码,直接建两个类( Bank_Account.BankManage)在BankManage往里面填方法就行.是为了让和我一样自学朋友可以更快的接受.但是代码优化的空间还是很大的( ...

  10. 在spark udf中读取hdfs上的文件

    某些场景下,我们在写UDF实现业务逻辑时候,可能需要去读取某个文件. 我们可以将此文件上传个hdfs某个路径下,然后通过hdfs api读取该文件,但是需要注意: UDF中读取文件部分最好放在静态代码 ...