简单工厂模式缺陷

大白话简单工厂模式(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)的更多相关文章

  1. 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)

    原文:乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pa ...

  2. 【设计模式】工厂方法模式 Factory Method Pattern

    在简单工厂模式中产品的创建统一在工厂类的静态工厂方法中创建,体现了面形对象的封装性,客户程序不需要知道产品产生的细节,也体现了面向对象的单一职责原则(SRP),这样在产品很少的情况下使用起来还是很方便 ...

  3. 工厂方法模式-Factory Method(Java实现)

    工厂方法模式-Factory Method 工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法让实例化的具体内容交给子类工厂来进行. 本文中的例子是这样的. 生产一个身份证, ...

  4. 二十四种设计模式:工厂方法模式(Factory Method Pattern)

    工厂方法模式(Factory Method Pattern) 介绍定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类. 示例有SqlMes ...

  5. 设计模式-03工厂方法模式(Factory Method Pattern)

    插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背 ...

  6. IOS设计模式浅析之工厂方法模式(Factory Method)

    概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何隔离出这个易变对象的变化,使得系统中“其它依赖该对象的对 ...

  7. 大话设计模式--工厂方法模式 Factory Method -- C++实现

    1. 工厂方法模式 定义一个用于创建对象的接口, 让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 和简单工厂模式相比: A: 简单工厂模式最大的优点在于工厂类中包含有必要的逻辑判断, ...

  8. 六个创建模式之工厂方法模式(Factory Method Pattern)

    问题: 在使用简单工厂模式的时候,如果添加新的产品类,则必需修改工厂类,违反了开闭原则. 定义: 定义一个用于创建对象的接口,让子类决定具体实例化哪个产品类.此时工厂和产品都具有相同的继承结构,抽象产 ...

  9. 工厂方法模式(Factory Method Pattern)

    工厂方法模式概述 工厂方法模式是为了弥补简单工厂模式的不足并且继承它的优点而延生出的一种设计模式,属于GoF中的一种.它能更好的符合开闭原则的要求. 定义:定义了一个用于创建对象的接口,但是让子类决定 ...

  10. 设计模式之工厂方法模式(Factory Method Pattern)

    一.工厂方法模式的诞生 在读这篇文章之前,我先推荐大家读<设计模式之简单工厂模式(Simple Factory Pattern)>这篇文档.工厂方法模式是针对简单工厂模式中违反开闭原则的不 ...

随机推荐

  1. synchronized的使用

    概念: 是利用锁的机制来实现同步的. 锁机制有如下两种特性: 互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操 ...

  2. Codeforces940掉分记

    掉分经过 难得这次时间比较好,下午17:35开始. 本来还很高兴,心想这回肯定不会犯困,没准排名能再上升一些呢,,可惜事与愿违-- 上来a题,光看懂题就花了一些时间. 然后开始写,结果第一遍CE,第二 ...

  3. 【杂项】各类文件头结合winhex使用-转载

    ———常用文件头——— JPEG (jpg),文件头:FFD8FFE1 PNG (png),文件头:89504E47 (0D0A1A0A) GIF (gif),文件头:47494638 ZIP Arc ...

  4. 嗯 想写个demo 苦于没数据

    step 1: 来点数据: 各种数据 随你便了. step 2: 来个 服务端 step 3 : 客户端 调用

  5. python基础[1]——python运算符&python数据类型之数值型

    python常用运算符&数字&布尔值 上节回顾 一.变量名和标识符 变量名的命名规范 (1)只能包含数字,字母和下划线 (2)只能以字母和下划线开头(不能以数字开头) (3)标识符是区 ...

  6. Stopping service [Tomcat] Disconnected from the target VM, address:XXXXXX解决方案

    原文出处:https://blog.csdn.net/u013294097/article/details/90677049 Stopping service [Tomcat] Disconnecte ...

  7. Linux用户在第一次登录时强制更改初始密码

    迫使用户更改密码 如果你想迫使用户更改其密码,请使用下面这个命令. $ sudo chage -d0 <user-name>   最初,“-d <N>”选项应该被设成密码的“有 ...

  8. Spring(五)核心容器 - 注册 Bean、BeanDefinitionRegistry 简介

    目录 前言 正文 1.BeanDefinitionRegistry 简介 2.registerBeanDefinition 方法注册 Bean 最后 前言 上篇文章我们对 BeanDefinition ...

  9. python 内置模块之os、sys、shutil

    一.OS模块 用于提供系统级别的操作. OS 目录和文件 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改 ...

  10. [flask]邮件配置-20171227

    环境变量配置: # PowerShell设置环境变量: $env:MAIL_USERNAME = "" $env:MAIL_PASSWORD = "" 国内: ...