1.工厂模式简介

1.1定义

简单工厂模式(Simple Factory Pattern):专门定义一个类(工厂类)来负责创建其他类的实例。可以根据创建方法的参数来返回不同类的实例,被创建的实例通常都具有共同的父类。

1.2作用

实现了创建者和调用者的分离

1.3详细分类

  • 简单工厂模式(静态工厂方法模式)
    用于生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)
  • 工厂方法模式
    用于生产同一等级结构中的任意产品(支持增加任意产品)## 标题
  • 抽象工厂模式
    围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂

1.4核心本质

  • 实例化对象不使用new,用工厂方法代替
  • 将选择实现类,创建对象统一管理和控制。从而将调用者跟实现类解耦

1.5为什么要用工厂模式

(1) 解耦 :把对象的创建和使用的过程分开
(2) 降低代码重复: 如果创建某个对象的过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。
(3) 降低维护成本 :由于创建过程都由工厂统一管理,所以发生业务逻辑变化,不需要找到所有需要创建某个对象的地方去逐个修正,只需要在工厂里修改即可,降低维护成本。

1.6应用场景

  • JDK中Calendar的getInstance方法
  • JDBC中的Connection对象的获取
  • Spring中IOC容器创建管理bean对象
  • 反射中Class对象的newInstance方法

2.简单工厂模式

2.1简介

严格的说,简单工厂模式并不是23种常用的设计模式之一,它只算工厂模式的一个特殊实现。简单工厂模式在实际中的应用相对于其他2个工厂模式用的还是相对少得多,因为它只适应很多简单的情况。

最重要的是它违背了我们在概述中说的 开放-封闭原则 (可以通过反射的机制来避免) 。因为每次你要新添加一个功能,都需要在生switch-case 语句(或者if-else 语句)中去修改代码,添加分支条件。

2.2适用场景

(1)需要创建的对象较少。
(2)客户端不关心对象的创建过程。

2.3角色分配

  • 工厂(Factory)角色 :简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
  • 抽象产品(Product)角色 :简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
  • 具体产品(Concrete Product)角色:简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

2.4 实例

创建一个可以绘制不同形状的绘图工具,可以绘制圆形,正方形,三角形,每个图形都会有一个draw()方法用于绘图.
(1)创建可乐接口(抽象产品(Product)角色)
(2)创建实现该接口的具体类(具体产品(Concrete Product)角色)
(3)创建工厂类(工厂(Factory)角色)
(4)测试方法
简单工厂模式像一个代工厂,一个工厂可以生产多种产品。举个例子,一个饮料加工厂同时帮百事可乐和可口可乐生产,加工厂根据输入参数Type来生产不同的产品。

(1)创建可乐接口

public interface Cola{void colaType();
}

(2)创建实现该接口的具体实现类

//可口可乐
public class CocaCola implements Cola{public CocaCola () {System.out.println("CocaCola ");}@Overridepublic void colaType() {System.out.println("可口可乐");}
}
//百事可乐
public class Pepsicola () {public Pepsicola () {System.out.println("Pepsicola ");}@Overridepublic void colaType() {System.out.println("百事可乐");}
}

(3)创建工厂类

public class ColaFactory {// 使用 getCola 方法获取可乐类型的对象public static Cola getCola(String type) {if (type.equalsIgnoreCase("CocaCola")) {return new CocaCola();} else if (type.equalsIgnoreCase("Pepsicola")) {return new Pepsicola();} else{return null;}        }
}

(4)测试方法

public class Test {public static void main(String[] args) {// 获取 CocaCola的对象,并调用它的 colaType 方法Cola cola= ColaFactory.getCola("CocaCola");      cola.colaType();// 获取 Rectangle 的对象,并调用它的 draw 方法Cola cola= ColaFactory.getCola("PepsiCola"); cola.colaType();    }
}

这样的实现有个问题,如果我们新增产品类的话,就需要修改工厂类中的getShape()方法,这很明显不符合开放-封闭原则

2.5使用反射机制改善简单工厂

将工厂类改为下面的形式:

package factory_pattern;
/*** 利用反射解决简单工厂每次增加新了产品类都要修改产品工厂的弊端*/
public class ColaFactory2 {public static Object getClass(Class<? extends Cola> clazz) {Object obj = null;try {obj = Class.forName(clazz.getName()).newInstance();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return obj;}
}

测试方法

package factory_pattern;
public class Test2 {public static void main(String[] args) {CocaCola cola = (CocaCola )ColaFactory2.getClass(CocaCola .class);cola.colaType();Pepsicola cola= (CocaCola )ColaFactory2.getClass(Pepsicola .class);cola.colaType();}}

这种方式的虽然符合了 开放-关闭原则 ,但是每一次传入的都是产品类的全部路径,这样比较麻烦。如果需要改善的话可以通过 反射+配置文件 的形式来改善,这种方式使用的也是比较多的。

2.6优缺点

优点:

  • 使用者只需要给工厂类传入一个正确的约定好的参数,就可以获取你所需要的对象,而不需要知道其创建细节,一定程度上减少系统的耦合。
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,减少开发者的记忆成本。

缺点:

  • 如果业务上添加新产品的话,就需要修改工厂类原有的判断逻辑,这其实是违背了开闭原则的。
  • 在产品类型较多时,有可能造成工厂逻辑过于复杂。所以简单工厂模式比较适合产品种类比较少而且增多的概率很低的情况。

3.工厂方法模式

3.1定义

  • 工厂方法模式(Factory Method Pattern)又称为工厂模式,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,即通过不同的工厂子类来创建不同的产品对象。
  • 工厂方法模式是简单工厂的仅一步深化, 在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。也就是说每个对象都有一个与之对应的工厂

3.2 适用场景

  • 一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。
  • 一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏
  • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无需关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。

3.3 工厂方法模式角色分配

  1. 抽象工厂(Abstract Factory)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
  2. 具体工厂(Concrete Factory)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建某一种产品对象。
  3. 抽象产品(AbstractProduct)角色 :工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
  4. 具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应

3.4实例


举例:
工厂方法和简单工厂有一些区别,简单工厂是由一个代工厂生产不同的产品,而工厂方法是对工厂进行抽象化,不同产品都由专门的具体工厂来生产。可口可乐工厂专门生产可口可乐,百事可乐工厂专门生产百事可乐。
(1)创建可乐接口。(2)创建实现该接口的实现类。(与简单工厂模式相同)
(3)创建一个工厂接口

public interface Factory {public Cola getCola();
}

(4)创建相关工厂类

//可口可乐工厂类
public class CocaColaFactory implements Factory {@Overridepublic Cola getCola () {// TODO Auto-generated method stubreturn new CocaCola();}
}
//百事可乐工厂类
public class PersicolaFactory implements Factory {@Overridepublic Cola getCola () {// TODO Auto-generated method stubreturn new Persicola();}
}

(5)测试

public class Test {public static void main(String[] args) {Factory cocaColafactory = new CocaColaFactory();Cola cocaCola= cocaColafactory .getCola();cocaCola.colaType();}}

3.5优缺点

优点:

  • 用户只需要关心其所需产品对应的具体工厂是哪一个即可,不需要关心产品的创建细节,也不需要知道具体产品类的类名。
  • 当系统中加入新产品时,不需要修改抽象工厂和抽象产品提供的接口,也无须修改客户端和其他的具体工厂和具体产品,而只要添加一个具体工厂和与其对应的具体产品就可以了,符合了开闭原则。

缺点:

  • 当系统中加入新产品时,除了需要提供新的产品类之外,还要提供与其对应的具体工厂类。因此系统中类的个数将成对增加,增加了系统的复杂度。

4.抽象工厂方法

4.1定义

  • 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
  • 在工厂方法模式中,其实我们有一个潜在意识的意识。那就是我们生产的都是同一类产品。抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一种产品,而是可以创建一组产品。

4.2 适用场景

  • 和工厂方法一样客户端不需要知道它所创建的对象的类。
  • 需要一组对象共同完成某种功能时,并且可能存在多组对象完成不同功能的情况。(同属于同一个产品族的产品)
  • 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码
  • 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
  • 系统结构稳定,不会频繁的增加对象。(因为一旦增加就需要修改原有代码,不符合开闭原则)

4.3 抽象工厂方法模式角色分配

  1. 抽象工厂(AbstractFactory)角色 :是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
  2. 具体工厂类(ConreteFactory)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建某一种产品对象。
  3. 抽象产品(Abstract Product)角色 :工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
  4. 具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。在抽象工厂中创建的产品属于同一产品族,这不同于工厂模式中的工厂只创建单一产品。

4.4 抽象工厂的工厂和工厂方法中的工厂有什么区别呢?

抽象工厂是生产一整套有产品的(至少要生产两个产品),这些产品必须相互是有关系或有依赖的,而工厂方法中的工厂是生产单一产品的工厂。

4.5 实例

抽象工厂和工厂方法不同的地方在于,生产产品的工厂是抽象的。举例,可口可乐公司生产可乐的同时,也需要生产装可乐的瓶子和箱子,瓶子和箱子也是可口可乐专属定制的,同样百事可乐公司也会有这个需求。这个时候我们的工厂不仅仅是生产可乐饮料的工厂,还必须同时生产同一主题的瓶子和箱子,所以它是一个抽象的主题工厂,专门生产同一主题的不同商品。
(1)创建相关接口

//可乐接口
public interface Cola{//可乐类型public void getType();
}
//瓶子接口
public interface Bottle{//瓶子标志public void logo();
}

(2)创建接口对应的实现类

//CocaCola类
public class CocaCola implements Cola{@Overridepublic void getType() {System.out.println("可口可乐");}
}
//Persicola类
public class Persicola implements Cola{@Overridepublic void getType() {System.out.println("百事可乐");}
}
//CocaBottle类
public class CocaBottle implements Bottle{@Overridepublic void logo() {System.out.println("可口可乐瓶子");}
}
//PepsiBottle类
public class PepsiBottle implements Bottle{@Overridepublic void logo() {System.out.println("百事可乐瓶子");}
}

(3)创建工厂接口

public interface Factory {public Cola produceCola();public Bottle produceBottle();
}

(4)创建具体工厂

//可口可乐工厂
public class Coca_Factory implements Factory{@Overridepublic Cola produceCola() {return new CocaCola();}@Overridepublic Bottle produceBottle() {return new CocaBottle();}}
//百事可乐工厂
public class Pepsi_Factory implements Factory{@Overridepublic Cola produceCola() {return new Pepsicola();}@Overridepublic Bottle produceBottle() {return new PepsiBottle();}}

(5)测试

public class Test {public static void main(String[] args) {      Factory factory;Cola cola;Bottle bottle;factory=new Coca_Factory();cola=factory.produceCola();cola.getType();bottle=factory.produceBottle();bottle.logo();}
}

4.6优缺点

优点:

  • 具体产品在应用层代码隔离,不需要关心产品细节。只需要知道自己需要的产品是属于哪个工厂的即可
  • 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。

缺点:

  • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。
  • 增加了系统的抽象性和理解难度

[深入理解工厂模式(https://juejin.im/post/5b08f9866fb9a07aad17f771#heading-4)

设计模式之二——工厂模式相关推荐

  1. 虚无空间java下载_Java进阶篇设计模式之二 ----- 工厂模式

    前言 在上一篇中我们学习了单例模式,介绍了单例模式创建的几种方法以及最优的方法.本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式.工厂方法和抽象工厂模式. 简单工厂模式 简单工厂模式是属于创建型模 ...

  2. getinstance方法详解_二、设计模式总览及工厂模式详解

    二.架构师内功心法之设计模式 2.架构师内功心法之设计模式 2.1.课程目标 1.通过对本章内容的学习,了解设计模式的由来. 2.介绍设计模式能帮我们解决哪些问题. 3.剖析工厂模式的历史由来及应用场 ...

  3. 设计模式系列·抽象工厂模式

    前言 以小说的笔法写的设计模式系列文章,你绝对看得懂![首发于公众号:"聊聊代码"] 设计模式系列·王小二需求历险记(一) 设计模式系列·王小二需求历险记(二) 设计模式系列·封装 ...

  4. 设计模式三—抽象工厂模式

    设计模式三-抽象工厂模式 一.定义 抽象工厂模式是工厂方法模式的进一步抽象.如果产品簇中只有一种产品,则退化为工厂方法模式. 二.原理图 三.代码实例 * 苹果和土豆是园丁1的杰作 * 葡萄和西红柿是 ...

  5. C#设计模式(2)——简单工厂模式

    一.引言 这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理解的模式--简单工厂模式. 二.简单工厂 ...

  6. java设计模式3种工厂模式

    java设计模式3种工厂模式 2010-01-08 16:06:36|  分类: JAVA技术|举报|字号 订阅 下载LOFTER客户端 工厂模式分为三种: Simple Factory模式 专门定义 ...

  7. 软件设计模式之路-----工厂模式抽象工厂模式

    系统开发和现实生活是一样的.在现实生活中一个复杂的商品都是通过一个工厂产生,具体工厂怎么产生的我们不需在乎.在软件设计上也可如此,如果一个对象的创建过程比较复杂,便可考虑使用工厂模式. 简单工厂模式 ...

  8. C#设计模式(4)——抽象工厂模式

    C#设计模式(4)--抽象工厂模式 一.引言 在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法 ...

  9. 设计模式——单例模式、工厂模式

    设计模式--单例模式.工厂模式 一.六大设计原则 开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭.在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热 ...

最新文章

  1. iPhone 13 终于等到了!降价、新颜色、电池续航性能大提升
  2. 浅谈图分析商业化的机遇与挑战,你注意到了吗?
  3. 时域和频域变换之---傅里叶级数的数学推导
  4. STM32开发 -- 低功耗模式详解(3)
  5. 深藏不露,挖掘4种大脑网络中的管理工具
  6. 在Windows Mobile模拟器(Emulator)建立网络连接
  7. mac 下安装jenkins
  8. C程序中如何获取shell命令执行结果和返回值
  9. 【转】C# WebAPI中为自定义模型设置JSonConverter
  10. python 代码片段9
  11. 2021全球权威AI性能竞赛MLPerf最新榜单: 浪潮获18项冠军几近半壁江山
  12. ASN.1编解码:ORAN-E2AP分析
  13. 突破验证,安装Media Player11.
  14. python中函数startswith的用法_Python中的startswith和endswith函数使用实例
  15. Physical Plausible Shading
  16. 机器学习模型可解释性进行到底——特征重要性(四)
  17. ASP.NET:返回按钮的解决方案摸索
  18. 【Arduino】WIN7装不上arduino驱动解决办法
  19. Pixhawk飞行模式注解(苍穹四轴)
  20. 一文讲透智慧农业,一滴水也没有的超级干货

热门文章

  1. 中文分词算法及python代码实现(持续更新中)
  2. 怎么修改artifact_《Artifact》卡牌描述与游戏UI文字修改教程
  3. YOYOPlayer:linux下开源的千千静听 (转载)
  4. 01 mybatis框架
  5. 沉痛悼念!网站快速变黑白灰色的4种方法
  6. 美团打车15城体验:王兴不再挑战程维
  7. 高并发高性能 面试收集
  8. 实现手机验证码功能(Redis)
  9. 数据挖掘项目总结文档
  10. ServletFileUpload 图片上传