大白话工厂方法模式(Factory Method)
简单工厂模式缺陷
大白话简单工厂模式(Simple Factory Pattern)中通过买车的经历解释了简单工厂模式。但熟悉设计模式的朋友会发现一些问题。
- 工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响。用日产车工厂的例子来形容就是日产汽车的工厂负责所有车型的制造,当发生停电、火灾等情况时,汽车无法正常制造,大大影响汽车的销售,使企业陷入困境
- 违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。这句话的意思是当企业发布新产品,该工厂需要重新学习新车型的制造,加大工人压力。
所以,随着企业的发展,日产公司决定将每种车型进行分工厂制造,解决了上述问题。这种方法在设计模式中被称为工厂方法模式
简单工厂模式改造
下面我们从代码的角度进行分析。4S店卖车首先要有车,这里只取日产部分车型逍客,轩逸和天籁。
代码片段1 日产车父类,所有车型都继承此类。
/**
* 日产车
* @author coderzcr
*/
abstract class NissanCar {
String name;
void printCar(){
System.out.println(name+"汽车已制造完成");
}
}
代码片段2 车型:逍客
/**
* 车型:逍客
* @author coderzcr
*/
class Xtrail extends NissanCar {
Xtrail(){
this.name = "逍客";
}
}
代码片段3 车型:轩逸
/**
* 车型:轩逸
* @author coderzcr
*/
class Sylphy extends NissanCar {
Sylphy(){
this.name = "轩逸";
}
}
代码片段4 车型:天籁
/**
* 车型:天籁
* @author coderzcr
*/
class Altima extends NissanCar {
Altima(){
this.name="天籁";
}
}
有了具体的车型要求,我们需要对不同车型建立工厂。
代码片段5 日产工厂父类,所有工厂都继承此类。
/**
* 日产车工厂
* @author coderzcr
*/
public abstract class NissanCarFactory {
/**
* 生产汽车
*/
abstract NissanCar createCar() ;
}
代码片段6 天籁工厂。
/**
* 天籁工厂
* @author coderzcr
*/
public class AltimaFactory extends NissanCarFactory {
@Override
NissanCar createCar() {
return new Altima();
}
}
代码片段7 逍客工厂。
/**
* 逍客工厂
* @author coderzcr
*/
public class XtrailFactory extends NissanCarFactory {
@Override
NissanCar createCar() {
return new Xtrail();
}
}
代码片段8 轩逸工厂。
/**
* 轩逸工厂
* @author coderzcr
*/
public class SylphyFactory extends NissanCarFactory {
@Override
NissanCar createCar() {
return new Sylphy();
}
}
图1 多工厂类图

工厂方法模式定义
工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
工厂父类(日产车工厂)
工厂子类(轩逸工厂、天籁工厂、逍客工厂)
即产品的制造分配给子工厂,缓解单一工厂的压力。
工厂方法模式结构
图2 工厂方法模式结构

工厂方法模式包含如下角色:
- Product:抽象产品
- ConcreteProduct:具体产品
- Factory:抽象工厂
- ConcreteFactory:具体工厂
工厂方法模式分析
优点分析
- 工厂方法模式的优点包括简单工厂方法模式的优点:用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
- 而且解决了简单工厂存在的不符合开闭原则问题,
在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
缺点分析
添加新产品时,需要添加一个具体工厂和具体产品,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
参考文献
2. 工厂方法模式(Factory Method Pattern) — Graphic Design Patterns
大白话工厂方法模式(Factory Method)的更多相关文章
- 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)
原文:乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pa ...
- 【设计模式】工厂方法模式 Factory Method Pattern
在简单工厂模式中产品的创建统一在工厂类的静态工厂方法中创建,体现了面形对象的封装性,客户程序不需要知道产品产生的细节,也体现了面向对象的单一职责原则(SRP),这样在产品很少的情况下使用起来还是很方便 ...
- 工厂方法模式-Factory Method(Java实现)
工厂方法模式-Factory Method 工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法让实例化的具体内容交给子类工厂来进行. 本文中的例子是这样的. 生产一个身份证, ...
- 二十四种设计模式:工厂方法模式(Factory Method Pattern)
工厂方法模式(Factory Method Pattern) 介绍定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类. 示例有SqlMes ...
- 设计模式-03工厂方法模式(Factory Method Pattern)
插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背 ...
- IOS设计模式浅析之工厂方法模式(Factory Method)
概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何隔离出这个易变对象的变化,使得系统中“其它依赖该对象的对 ...
- 大话设计模式--工厂方法模式 Factory Method -- C++实现
1. 工厂方法模式 定义一个用于创建对象的接口, 让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 和简单工厂模式相比: A: 简单工厂模式最大的优点在于工厂类中包含有必要的逻辑判断, ...
- 六个创建模式之工厂方法模式(Factory Method Pattern)
问题: 在使用简单工厂模式的时候,如果添加新的产品类,则必需修改工厂类,违反了开闭原则. 定义: 定义一个用于创建对象的接口,让子类决定具体实例化哪个产品类.此时工厂和产品都具有相同的继承结构,抽象产 ...
- 工厂方法模式(Factory Method Pattern)
工厂方法模式概述 工厂方法模式是为了弥补简单工厂模式的不足并且继承它的优点而延生出的一种设计模式,属于GoF中的一种.它能更好的符合开闭原则的要求. 定义:定义了一个用于创建对象的接口,但是让子类决定 ...
- 设计模式之工厂方法模式(Factory Method Pattern)
一.工厂方法模式的诞生 在读这篇文章之前,我先推荐大家读<设计模式之简单工厂模式(Simple Factory Pattern)>这篇文档.工厂方法模式是针对简单工厂模式中违反开闭原则的不 ...
随机推荐
- 如何用rflask快速初始化Flask Restful项目
如何用rflask快速初始化Flask Restful项目 说明 多啰嗦两句 我们在创建flask项目的时候,使用pycharm创建出来的项目比较简陋,而且随着项目的功能完善,项目目录结构会比较多,多 ...
- 远程桌面软件RDCMan汉化版
自己汉化的远程桌面控制软件RDCMan--Remote Desktop Connection Manager(RDCMan) v2.7 简体中文汉化版. 介绍 Remote Desktop Conne ...
- Qt常用UI控件读取、写入方法
本文用途:快速备忘,方便调用,写熟了自然就记下了. [1.标签label] 读取:ui->label->text() 写入:ui->label->setText("p ...
- Python学习初级python3.6的安装配置
首先我们来安装python 1.首先进入网站下载:点击打开链接(或自己输入网址https://www.python.org/downloads/),进入之后如下图,选择图中红色圈中区域进行下载. 2. ...
- volatile梳理
volatile 可见性也就是说一旦某个线程修改了该被volatile修饰的变量,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,可以立即获取修改之后的值. 在Java中为了加快程序的运行 ...
- Matlab 与 c++对txt 文档的读写格式
学习g++能够读取什么格式的txt文件. 读基本指令: >sprintf(filename, "doc_%d.txt", d); >fileptr = fopen(fi ...
- Spring5.x源码分析 | 从踩坑到放弃之环境搭建
Spring5.x源码分析--从踩坑到放弃之环境搭建 前言 自从Spring发行4.x后,很久没去好好看过Spring源码了,加上最近半年工作都是偏管理和参与设计为主,在技术细节上或多或少有点疏忽,最 ...
- Java 分布式框架面试题合集
Java 分布式框架面试题合集 1.什么是 ZooKeeper? 答:ZooKeeper 是一个开源的分布式应用程序协调服务,是一个典型的分布式数据一致性解决方案.设计目的是将那些复杂且容易出错的分布 ...
- 表达式属性(C#6.0和C#7.0
从C#6开始,只读属性可简写为表达式属性.它使用双箭头替换了花括号,get访问器和return关键字. 例如: decimal CurrentPrice,sharedOwned; public dec ...
- t-io Java构建p2p网络
Java 构建p2p网络 这篇文章是一篇关于pbft算法实现的一篇补充文章,但是在这里不会涉及pbft的算法方面,所以可以当做一篇单独的文章食用.如果想查看关于区块链或者PBFT算法的文章,可以参考一 ...