定义与类型

  • 定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。
  • 类型:创建型

适用场景

  • 创建对象需要大量重复的代码
  • 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
  • 一个类通过其子类来指定创建哪个对象

优点

  • 用户只需要关心所需产品对应的工厂,无须关心创建细节
  • 加入新产品符合开闭原则,提高可扩展性

缺点

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度

Coding

工厂方法模式从一定意义上讲是从简单工厂模式衍生过来的,创建产品抽象类

public abstract class Video {
public abstract void produce();
}

创建具体产品

public class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("录制Java课程");
}
}
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("录制Python视频");
}
}

创建产品工厂方法抽象类

public abstract class VideoFactory {
public abstract Video getVideo();
}

创建产品工厂方法实现类(每个产品都有对应的实现类)

public class JavaVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
}
public class PythonVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new PythonVideo();
}
}

测试类

public class Test {
public static void main(String[] args) {
VideoFactory javaVideoFactory = new JavaVideoFactory();
VideoFactory pythonVideoFactory = new PythonVideoFactory();
Video video = javaVideoFactory.getVideo();
video.produce(); video = pythonVideoFactory.getVideo();
video.produce();
}
}

控制台输出

录制Java课程
录制Python视频

如果我们现在新增一个产品--前端课程,我们需要创建产品类,产品工厂类,但是无需改动其他代码,做到了对扩展开放,对修改关闭,符合开闭原则。

public class FEVideo extends Video {
@Override
public void produce() {
System.out.println("录制前端课程");
}
}
public class FEVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new FEVideo();
}
}

但是,我们也不难看出工厂方法模式的缺点--类的个数容易过多,增加复杂度。

因为一旦我们需要现在产品,就需要创建产品对应的产品实现类,以及产品工厂方法类,无疑增加了类的个数和系统的复杂度。

完整的UML类图

源码解析

Collection源码

jdk中典型的工厂方法模式体现为java.util.Collection

抽象产品为java.util.Iterator

public interface Iterator<E> {
...
}

抽象工厂定义了创建产品族的方法java.util.Collection.#iterator

Iterator<E> iterator();

由子类来定义具体创建产品的逻辑,如java.util.ArrayList.#iterator

public Iterator<E> iterator() {
return new Itr();
}

而具体的产品定义为java.util.ArrayList$Itr

private class Itr implements Iterator<E> {
...
}

UML类图

URLStreamHandlerFactory源码

再来看一个典型例子,java.net.URLStreamHandlerFactory作为工厂方法抽象类,定义了创建产品的抽象方法

public interface URLStreamHandlerFactory {
URLStreamHandler createURLStreamHandler(String protocol);
}

产品抽象类就是java.net.URLStreamHandler

public abstract class URLStreamHandler {
...
}

产品的工厂方法实现类为sun.misc.Launcher$Factory

private static class Factory implements URLStreamHandlerFactory {
...
public URLStreamHandler createURLStreamHandler(String var1) {
private static String PREFIX = "sun.net.www.protocol"; private Factory() {
} public URLStreamHandler createURLStreamHandler(String var1) {
String var2 = PREFIX + "." + var1 + ".Handler"; try {
// 通过反射创建指定类型的产品
Class var3 = Class.forName(var2);
return (URLStreamHandler)var3.newInstance();
} catch (ReflectiveOperationException var4) {
throw new InternalError("could not load " + var1 + "system protocol handler", var4);
}
}
}
}

可以发现,工厂实现类通过反射类创建具体的产品实现类,而产品实现类非常多

这样满足了开闭原则,也没有过多的增加类的数量,值得我们学习。

Java设计模式(四)工厂方法模式的更多相关文章

  1. Java 设计模式(四)-工厂方法模式 (FactoryMethod Pattern)

    1     概念定义 1.1   定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 1.2   类型 创建类模式 2     原理特征 2.1   类 ...

  2. Java设计模式之工厂方法模式(转) 实现是抽象工厂?

    Java设计模式之工厂方法模式 责任编辑:覃里作者:Java研究组织   2009-02-25   来源:IT168网站   文本Tag: 设计模式 Java [IT168 技术文章]         ...

  3. Java设计模式系列-工厂方法模式

    原创文章,转载请标注出处:<Java设计模式系列-工厂方法模式> 一.概述 工厂,就是生产产品的地方. 在Java设计模式中使用工厂的概念,那就是生成对象的地方了. 本来直接就能创建的对象 ...

  4. java设计模式(二)---工厂方法模式

    2普通工厂方法模式 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建. 2.1创建接口 /** * 发送接口 * Created by mrf on 2016/2/25. */ public ...

  5. Java设计模式 之 工厂方法模式

    1. 使用设计模式的好处:可提高代码的重复性,让代码更容易被他人理解,保证代码的可靠性. 2. 工厂模式定义:就是创建一个工厂类来创建你需要的类,工厂模式包括工厂模式和抽象工厂模式,抽象工厂模式是工厂 ...

  6. JAVA设计模式之工厂方法模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述工厂方法模式的: 工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymor ...

  7. 【java】 java 设计模式(1):工厂方法模式(Factory Method)

    工厂方法模式分为三种: 1.普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建.首先看下关系图: 举例如下:(我们举一个发送邮件和短信的例子) 首先,创建二者的共同接口:   p ...

  8. Java设计模式(2)——工厂方法模式

    工厂方法模式同样属于类的创建型模式又被称为多态工厂模式.工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色, ...

  9. java设计模式学习 ----- 工厂方法模式(Factory Method)

    工厂方法模式(Factory Method) 工厂方法模式分为三种:普通工厂模式.多个工厂方法模式.静态工厂方法模式 普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建. 关系图 ...

  10. C#设计模式(3)——工厂方法模式

    一.概念:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 二.代码实现 namespace 设计模式之工厂方法模式 { /// <summary&g ...

随机推荐

  1. Linux 查看磁盘容量、查找大文件、查找大目录

    Linux 查看磁盘容量.查找大文件.查找大目录 磁盘统计 查看磁盘使用情况 df -h 文件统计 查找/home 目录下大于800M的文件 find /home -type f -size +800 ...

  2. pytorch --Rnn语言模型(LSTM,BiLSTM) -- 《Recurrent neural network based language model》

    论文通过实现RNN来完成了文本分类. 论文地址:88888888 模型结构图: 原理自行参考论文,code and comment: # -*- coding: utf-8 -*- # @time : ...

  3. debian wget 报ERROR: The certificate of ‘xxx’ is not trusted.

    # wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz --2019-01-11 15:04:41-- https://w ...

  4. php 安装扩展插件实例-gd库

    今天给php 安装一个扩展插件 gd库   一.gd库是什么 gd库是一个开源的图像处理库,它通过提供一系列用来处理图片的API,使其可以用来创建图表.图形.缩略图以及其他图像的处理操作. gd库支持 ...

  5. APP图标在线生成

    在线生成安卓APP图标生成 图标在线 在线图标 安卓图标 生成图标 https://icon.wuruihong.com/ 在线png图片压缩  png压缩 https://compresspng.c ...

  6. Hibernate入门之创建数据库表

    前言 Hibernate 5.1和更早版本至少需要Java 1.6和JDBC 4.0,Hibernate 5.2和更高版本至少需要Java 1.8和JDBC 4.2,从本节开始我们正式进入Hibern ...

  7. 小白学 Python 数据分析(9):Pandas (八)数据预处理(2)

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  8. 基于SSM开发自行车在线租赁管理系统源码

    开发环境: Windows操作系统开发工具: Myeclipse+Jdk+Tomcat+MYSQL数据库注意:此项目分管理员与普通用户两种角色运行效果图 源码及原文链接:https://javadao ...

  9. kthrotlds(WatchDogs变种)查杀方法

    病毒现象 服务器出现卡顿.CPU飙升 以下为WatchDogs的判断方式及其命令:存在恶意进程watchdogs: ps -ef | grep watchdogs存在恶意进程ksoftirqds: p ...

  10. 6.python设置代理和添加镜像源介绍

    为什么要修改镜像源? 一般使用python安装库,会用到pip install xxx 指令或者conda install xxx指令,因为pip和conda默认国外镜像源,这时会在Python的官方 ...