https://baijiahao.baidu.com/s?id=1625606999883136508&wfr=spider&for=pc

https://blog.csdn.net/superbeck/article/details/4446177

https://blog.csdn.net/jason0539/article/details/23020989

简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式。其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性。

本文是本人对这三种模式学习后的一个小结以及对他们之间的区别的理解。

简单工厂

简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。

不修改代码的话,是无法扩展的。

工厂方法

工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。

在同一等级结构中,支持增加任意产品。

抽象工厂

抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。

应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。

小结

★工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。

★使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。

★工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。

区别

简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)

工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)   
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)

以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。

在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动。

模式的问题:你如何能轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程呢?

解决方案:建立一个工厂来创建对象

实现:

一、引言
    1)还没有工厂时代:假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用。
    2)简单工厂模式:后来出现工业革命。用户不用去创建宝马车。因为客户有一个工厂来帮他创建宝马.想要什么车,这个工厂就可以建。比如想要320i系列车。工厂就创建这个系列的车。即工厂可以创建产品。
    3)工厂方法模式时代:为了满足客户,宝马车系列越来越多,如320i,523i,30li等系列一个工厂无法创建所有的宝马系列。于是由单独分出来多个具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象。你需要指定某个具体的工厂才能生产车出来。

4)抽象工厂模式时代:随着客户的要求越来越高,宝马车必须配置空调。于是这个工厂开始生产宝马车和需要的空调。

最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车.

这就是工厂模式。

二、分类 
        工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。 
工厂模式可以分为三类:

1)简单工厂模式(Simple Factory)

简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
2)工厂方法模式(Factory Method) 
3)抽象工厂模式(Abstract Factory)

这三种模式从上到下逐步抽象,并且更具一般性。 
        GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。

将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。

三、区别 
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类可以创建多个具体产品类的实例。   
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
两者皆可。

四、简单工厂模式 
建立一个工厂(一个函数或一个类方法)来制造新的对象。
分布说明引子:从无到有。客户自己创建宝马车,然后拿来用。

 
  1. public class BMW320 {

  2. public BMW320(){

  3. System.out.println("制造-->BMW320");

  4. }

  5. }

  6. public class BMW523 {

  7. public BMW523(){

  8. System.out.println("制造-->BMW523");

  9. }

  10. }

  11. public class Customer {

  12. public static void main(String[] args) {

  13. BMW320 bmw320 = new BMW320();

  14. BMW523 bmw523 = new BMW523();

  15. }

  16. }

客户需要知道怎么去创建一款车,客户和车就紧密耦合在一起了.为了降低耦合,就出现了工厂类,把创建宝马的操作细节都放到了工厂里面去,客户直接使用工厂的创建工厂方法,传入想要的宝马车型号就行了,而不必去知道创建的细节.这就是工业革命了:简单工厂模式

即我们建立一个工厂类方法来制造新的对象。如图:

产品类:

 
  1. abstract class BMW {

  2. public BMW(){

  3. }

  4. }

  5. public class BMW320 extends BMW {

  6. public BMW320() {

  7. System.out.println("制造-->BMW320");

  8. }

  9. }

  10. public class BMW523 extends BMW{

  11. public BMW523(){

  12. System.out.println("制造-->BMW523");

  13. }

  14. }

工厂类:

 
  1. public class Factory {

  2. public BMW createBMW(int type) {

  3. switch (type) {

  4. case 320:

  5. return new BMW320();

  6. case 523:

  7. return new BMW523();

  8. default:

  9. break;

  10. }

  11. return null;

  12. }

  13. }

客户类:

 
  1. public class Customer {

  2. public static void main(String[] args) {

  3. Factory factory = new Factory();

  4. BMW bmw320 = factory.createBMW(320);

  5. BMW bmw523 = factory.createBMW(523);

  6. }

  7. }

简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。 
      先来看看它的组成: 
         1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
         2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。         
         3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在Java中由一个具体类实现。 
        
        下面我们从开闭原则(对扩展开放;对修改封闭)上来分析下简单工厂模式。当客户不再满足现有的车型号的时候,想要一种速度快的新型车,只要这种车符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。所以对产品部分来说,它是符合开闭原则的;但是工厂部分好像不太理想,因为每增加一种新型车,都要在工厂类中增加相应的创建业务逻辑(createBMW(int type)方法需要新增case),这显然是违背开闭原则的。可想而知对于新产品的加入,工厂类是很被动的。对于这样的工厂类,我们称它为全能类或者上帝类。 
        我们举的例子是最简单的情况,而在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以这可能会把我们的上帝累坏了,也累坏了我们这些程序员。
        于是工厂方法模式作为救世主出现了。 工厂类定义成了接口,而每新增的车种类型,就增加该车种类型对应工厂类的实现,这样工厂的设计就可以扩展了,而不必去修改原来的代码。
五、工厂方法模式 
        工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。 
工厂方法模式组成: 
       1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。 
       2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。 
       3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。 
       4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。 
       工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的!

代码如下:

产品类:

 
  1. abstract class BMW {

  2. public BMW(){

  3. }

  4. }

  5. public class BMW320 extends BMW {

  6. public BMW320() {

  7. System.out.println("制造-->BMW320");

  8. }

  9. }

  10. public class BMW523 extends BMW{

  11. public BMW523(){

  12. System.out.println("制造-->BMW523");

  13. }

  14. }

创建工厂类:

 
  1. interface FactoryBMW {

  2. BMW createBMW();

  3. }

  4. public class FactoryBMW320 implements FactoryBMW{

  5. @Override

  6. public BMW320 createBMW() {

  7. return new BMW320();

  8. }

  9. }

  10. public class FactoryBMW523 implements FactoryBMW {

  11. @Override

  12. public BMW523 createBMW() {

  13. return new BMW523();

  14. }

  15. }

客户类:

 
  1. public class Customer {

  2. public static void main(String[] args) {

  3. FactoryBMW320 factoryBMW320 = new FactoryBMW320();

  4. BMW320 bmw320 = factoryBMW320.createBMW();

  5. FactoryBMW523 factoryBMW523 = new FactoryBMW523();

  6. BMW523 bmw523 = factoryBMW523.createBMW();

  7. }

  8. }

工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。

工厂方法模式:

一个抽象产品类,可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类只能创建一个具体产品类的实例。(对于一类产品(接口),想增加不同的实例(接口的实现类)时直接增加对应的工厂类就行,不需修改以前工厂类的代码)

六,抽象工厂模式

随着客户的要求越来越高,宝马车需要不同配置的空调和发动机等配件。于是这个工厂开始生产空调和发动机,用来组装汽车。这时候工厂有两个系列的产品:空调和发动机。宝马320系列配置A型号空调和A型号发动机,宝马230系列配置B型号空调和B型号发动机。

概念:

抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。

比如宝马320系列使用空调型号A和发动机型号A,

而宝马230系列使用空调型号B和发动机型号B,那么使用抽象工厂模式,

在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。

针对百度百科上对于抽象工厂模式的简介,结合本例如下:

当每个抽象产品都有多于一个的具体子类的时候(空调有型号A和B两种,发动机也有型号A和B两种),工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产品角色都有两个具体产品(产品空调有两个具体产品空调A和空调B)。抽象工厂模式提供两个具体工厂角色(宝马320系列工厂和宝马230系列工厂),分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

抽象工厂模式代码

产品类:

 
  1. //发动机以及型号

  2. public interface Engine {

  3. }

  4. public class EngineA extends Engine{

  5. public EngineA(){

  6. System.out.println("制造-->EngineA");

  7. }

  8. }

  9. public class EngineBextends Engine{

  10. public EngineB(){

  11. System.out.println("制造-->EngineB");

  12. }

  13. }

  14. //空调以及型号

  15. public interface Aircondition {

  16. }

  17. public class AirconditionA extends Aircondition{

  18. public AirconditionA(){

  19. System.out.println("制造-->AirconditionA");

  20. }

  21. }

  22. public class AirconditionB extends Aircondition{

  23. public AirconditionB(){

  24. System.out.println("制造-->AirconditionB");

  25. }

  26. }

创建工厂类:

 
  1. //创建工厂的接口

  2. public interface AbstractFactory {

  3. //制造发动机

  4. public Engine createEngine();

  5. //制造空调

  6. public Aircondition createAircondition();

  7. }

  8. //为宝马320系列生产配件

  9. public class FactoryBMW320 implements AbstractFactory{

  10. @Override

  11. public Engine createEngine() {

  12. return new EngineA();

  13. }

  14. @Override

  15. public Aircondition createAircondition() {

  16. return new AirconditionA();

  17. }

  18. }

  19. //宝马523系列

  20. public class FactoryBMW523 implements AbstractFactory {

  21. @Override

  22. public Engine createEngine() {

  23. return new EngineB();

  24. }

  25. @Override

  26. public Aircondition createAircondition() {

  27. return new AirconditionB();

  28. }

  29. }

客户:

 
  1. public class Customer {

  2. public static void main(String[] args){

  3. //生产宝马320系列配件

  4. FactoryBMW320 factoryBMW320 = new FactoryBMW320();

  5. factoryBMW320.createEngine();

  6. factoryBMW320.createAircondition();

  7. //生产宝马523系列配件

  8. FactoryBMW523 factoryBMW523 = new FactoryBMW523();

  9. factoryBMW320.createEngine();

  10. factoryBMW320.createAircondition();

  11. }

  12. }

多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类可以创建多个具体产品类的实例。

总结:

无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。

所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。

JAVA设计模式之工厂模式(简单,工厂,抽象)相关推荐

  1. JavaScript 设计模式核⼼原理与应⽤实践 之 创建型:工厂模式·简单工厂——区分“变与不变”

    JavaScript 设计模式核⼼原理与应⽤实践 之 创建型:工厂模式·简单工厂--区分"变与不变" 先来说说构造器 在介绍工厂模式之前,为了辅助大家的理解,我想先在这儿给大家介绍 ...

  2. 设计模式-创建型模式-简单工厂模式

    工程地址:设计模式-简单工厂源码-C++文档类资源-CSDN下载C++设计模式-创建型模式-简单工厂模式源码更多下载资源.学习资料请访问CSDN下载频道.https://download.csdn.n ...

  3. JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)

    在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一 ...

  4. java web简单工厂模式_JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)

    在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一 ...

  5. Java设计模式(二)简单工厂模式—设计模式六大原则

    文章目录 设计模式六大原则 1. 开闭原则 2. 里氏代换原则 3. 依赖倒转原则 4. 接口隔离原则 5. 迪米特法则(最少知道原则) 6. 合成复用原则 工厂设计模式 什么是工厂模式 工厂模式的好 ...

  6. java 三种工厂模式(简单工厂+工厂方法+抽象工厂)

    一.简单工厂模式 概述   简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同类的 实例,被创建的实例通常都具有共同的父类.因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因 ...

  7. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)

    园子里关于23种设计模式的博文已经可以说是成千上万.车载斗量.屯街塞巷.不计其数.数不胜数.摩肩接踵.汗牛充栋.车水马龙.门庭若市.琳琅满目直至让人眼花缭乱了.在这样的大环境下之所以来写设计模式类的博 ...

  8. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂) v阅读目录

    1楼留头头大神:http://www.cnblogs.com/toutou/p/4899388.html v阅读目录 v写在前面 v简单工厂模式 v工厂方法模式 v抽象工厂模式 v博客总结 v博客前言 ...

  9. 工厂模式 工厂方法模式 抽象工厂模式 简单工厂模式 工厂模式于抽象工厂的区别 设计模式

    工厂模式 定义一个用于创建对象的接口,让子类实现具体类的创建.工厂将类的实例化延迟的子类. 良好的分装性.对于具体产品,只要知道产品名称即可(类名或字符串),封闭了对产品创建的细节. 屏蔽具体产品类. ...

  10. 从零开始学习Java设计模式 | 创建型模式篇:抽象工厂模式

    在本讲,我们来学习一下创建型模式里面的第三个设计模式,即抽象工厂模式. 前言 前面介绍的工厂方法模式中考虑的是一类产品,如畜牧场只养动物.电视机厂只生产电视机(不生产空调.冰箱等其它的电器).计算机学 ...

最新文章

  1. Nature年度十大杰出论文公布:机器狗算法、近室温超导等入选,复旦中科院上榜...
  2. mysql unsupported data type._数据查询Unsupported command错误
  3. 十三种基于直方图的图像全局二值化算法原理、实现、代码及效果。
  4. 打造云上金融!网易云信入选「2021 数字化转型最佳案例 Top10」
  5. bgrfc entry point
  6. saxparser_使用SaxParser和完整代码进行XML解析
  7. 内部服务并行调用_25行以下代码中的并行SOAP调用的Express服务
  8. python mssqlserver_python for MSSQLserver
  9. java.lang.NoClassDefFoundError: org/apache/log4j/Priority的问题解决
  10. .net 跳出Frameset框架
  11. mysql ssd优化测试_MySQL服务器SSD性能问题分析与测试
  12. 二元函数偏导数公式_高等数学六:(3)复合函数与微分性质
  13. 数据库设计工具-----PD
  14. 五大常用算法之贪心算法
  15. matlab灵敏度分析操作,灵敏度分析 使用MATLAB编写.doc
  16. JavaSE(J2SE)入门学习笔记(二)
  17. Auto.js逆向分析-提取脚本文件(附源码)
  18. 评估智能对话机器人的7大数据指标
  19. 计算机网络运输层知识点,计算机网络复习——Ch6传输层
  20. ProcessOn‘s Bug--完善个人资料无限扩容

热门文章

  1. sessionStorage跨标签取值
  2. Ayoa:让思维导图更简单,在线使用 无需安装客户端
  3. Python 正则表达式模块详解
  4. 通过JS制作一个简易数码时钟
  5. LVM 的创建,扩展,缩减及建立快照
  6. Android播放音频的两种方式
  7. 【转】使用AIDL实现进程间的通信之复杂类型传递
  8. ios7中的UILabel自适决定大小
  9. logstash+elasticsearch +kibana 日志管理系统
  10. Ubuntu Server Nginx 下配置 mono 下运行 asp.net mvc