原创文章,转载请标注出处:Java设计模式之《工厂方法模式》及使用场景

一、概述

工厂,就是生产产品的地方。

在Java设计模式中使用工厂的概念,那就是生成对象的地方了。

本来直接就能创建的对象为何要增加一个工厂类呢?

这就需要了解工厂方法要解决的是什么问题了,如果只有一个类,我们直接new一个对象完事,这是最简单的;但是如果有多个类呢,而且这些类还需要针对不同的情况来创建不同的对象,这时候就需要工厂了,我们可以在工厂中根据条件来创建具体的对象。

这样一来就将调用方和具体的目标类进行了解耦,调用方根本就不知道需要创建那个对象,它只是提出了条件,然后工厂就可以根据给定的条件来决定创建哪一个对象。

二、简单工厂方法模式

要说工厂方法模式,不得不先了解下简单工程方法模式,这个模式并不是23种设计模式中的内容。

所谓简单工厂方法模式,就是为目标类创建一个工厂,当有多个目标实现的时候,在这个工厂内部进行逻辑判断来根据条件创建不同的目标实例。

下面看个例子,我就以桌子为例来写:

桌子接口:Desk

/**
* 桌子接口
*/
public interface Desk {
String getType();
}

木质桌子:WoodenDesk

/**
* 木质桌子
*/
public class WoodenDesk implements Desk{
private String type = "木质桌";
@Override
public String getType() {
return type;
}
}

塑料桌子:PlasticDesk

/**
* 塑料桌
*/
public class PlasticDesk implements Desk {
private String type = "塑料桌";
@Override
public String getType() {
return type;
}
}

类型枚举:Type

/**
* 类型
*/
public enum Type {
PLASTIC,WOODEN;
}

桌子工厂:DeskFactory

/**
* 桌子工厂
*/
public class DeskFactory {
public static Desk createDesk(Type type) {
switch (type) {
case WOODEN:
return new WoodenDesk();
case PLASTIC:
return new PlasticDesk();
default:
return null;
}
}
}

测试类:Clienter

/**
* 测试类
*/
public class Clineter {
public static void main(String[] args) {
Desk desk = DeskFactory.createDesk(Type.PLASTIC);
System.out.println(desk.getType());
}
}

执行结果

塑料桌

这就是简单工厂方法,只有一个工厂类来面向多个目标实现。当目标实现增多时,我们不得不去修改工厂类的方法,使其兼容新的实现类型,这明显违背了开闭原则,所以出现了工厂方法模式。

三、工厂方法模式

工厂方法模式是对简单工厂模式的抽象升级,将工厂这个概念抽象出来成为接口,然后针对每种目标实现类创建一个工厂实现,一对一来实现,当新增了目标实现,只要同时新增一个工厂实现即可。

下面看看实例:

桌子接口:Desk

/**
* 桌子接口
*/
public interface Desk {
String getType();
}

木质桌子:WoodenDesk

/**
* 木质桌子
*/
public class WoodenDesk implements Desk{
private String type = "木质桌";
@Override
public String getType() {
return type;
}
}

塑料桌子:PlasticDesk

/**
* 塑料桌
*/
public class PlasticDesk implements Desk {
private String type = "塑料桌";
@Override
public String getType() {
return type;
}
}

桌子工厂接口:DeskFactory

/**
* 桌子工厂接口
*/
public interface DeskFactory {
Desk createDesk();
}

木质桌子工厂:WoodenDeskFactory

/**
* 木质桌子工厂
*/
public class WoodenDeskFactory implements DeskFactory{
@Override
public Desk createDesk(){
return new WoodenDesk();
}
}

塑料桌子工厂:

/**
* 塑料桌子工厂
*/
public class PlasticDeskFactory implements DeskFactory {
@Override
public Desk createDesk() {
return new PlasticDesk();
}
}

测试类:Clienter

/**
* 测试类
*/
public class Clienter {
public static void main(String[] args) {
DeskFactory factory = new WoodenDeskFactory();
Desk desk = factory.createDesk();
System.out.println(desk.getType());
}
}

执行结果:

木质桌

四、解析

从上面的实例中可以很容易看出来,工厂方法模式的重点就在这个工厂接口了。

目标可以无限扩展,工厂类也要随之扩展,一对一存在,满足了开闭原则,但如果目标实现较多,工厂实现类也会增多,不简洁。

MyBatis中使用的比较多,事务模块和数据源模块都使用了工厂方法模式。


同系列文章:

Java设计模式系列-工厂方法模式的更多相关文章

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

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

  2. Android设计模式系列--工厂方法模式

    工厂方法模式,往往是设计模式初学者入门的模式,的确,有人称之为最为典型最具启发效果的模式.android中用到了太多的工厂类,其中有用工厂方法模式的,当然也有很多工厂并不是使用工厂方法模式的,只是工具 ...

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

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

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

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

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

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

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

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

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

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

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

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

  9. PHP 设计模式系列 —— 工厂方法模式(Factory Method)(转)

    1.模式定义 定义一个创建对象的接口,但是让子类去实例化具体类.工厂方法模式让类的实例化延迟到子类中. 2.问题引出 框架需要为多个应用提供标准化的架构模型,同时也要允许独立应用定义自己的域对象并对其 ...

随机推荐

  1. BZOJ_4269_再见Xor_线性基

    BZOJ_4269_再见Xor_线性基 Description 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. Input 第一行 ...

  2. 磁盘IOPS计算与测量

    IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一.IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的I/O请求 ...

  3. java日志文件用法总结

    1.基本概念 日志门面(接口):commons logging ; slf4j ; 日志具体实现:log4j ; logback(Spring 系列在使用) ; log4j2(添加了异步logger的 ...

  4. “卷积神经网络(Convolutional Neural Network,CNN)”之问

    目录 Q1:CNN 中的全连接层为什么可以看作是使用卷积核遍历整个输入区域的卷积操作? Q2:1×1 的卷积核(filter)怎么理解? Q3:什么是感受野(Receptive field)? Q4: ...

  5. ASP.Net Core MVC+Ajax 跨域

    要求 C端:用户端(http://www.b.com) A端:管理端(http://admin.b.com) 问题:A端上传图片到C端指定文件夹内保存,供C端使用. 方案 ① C端从nuget引入Mi ...

  6. AWVS12 介绍和安装详解 -- For Windows10

    一.AWVS介绍: Acunetix Web Vulnerability Scanner,简称:AWVS,是一个自动化的Web安全测试工具,它可以扫描Web站点和Web应用. AWVS可以快速扫描SQ ...

  7. go语言调度器源代码情景分析之六:go汇编语言

    go语言runtime(包括调度器)源代码中有部分代码是用汇编语言编写的,不过这些汇编代码并非针对特定体系结构的汇编代码,而是go语言引入的一种伪汇编,它同样也需要经过汇编器转换成机器指令才能被CPU ...

  8. C# .NET Web API 如何自訂 ModelBinder

    各位好!這次要來替大家介紹的是如何在 .NET  Web API 中自訂一個 ModelBinder 透過自定義的 ModelBinder 我們可以很簡單的將 QueryString 傳過來的參數綁定 ...

  9. Win64下编译集成GEOS和Proj4的GDAL

    目录 1.编译GEOS 2.编译Proj4 3.GDAL集成Proj4和GEOS 1) 修改安装的目录 2) 配置Proj4 3) 配置GEOS 4) 自定义动态库名称(可跳过) 5) 编译 1.编译 ...

  10. 如何给自己的app添加分享到有道云笔记这样的功能

    文章同步自http://javaexception.com/archives/34 如何给自己的app添加分享到有道云笔记这样的功能 问题: 在之前的一个开源笔记类项目Leanote中,有个用户反馈想 ...