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

针对上面这种情况,我们如何轻松方便地构造对象实例,而不必关心构造对象示例的细节和复杂过程?解决方案就是使用一个工厂类来创建对象。

一、什么是工厂模式:

工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,工厂模式可以分为三类:

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)

这三种模式从上到下逐步抽象,并且更具一般性。《设计模式》一书中将工厂模式分为两类:工厂方法模式与抽象工厂模式。将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。 我们先从以下案例对工厂模式做个初步的了解:

(1)在没有工厂的时代,如果客户需要一款宝马车,那么就需要客户去创建一款宝马车,然后拿来用。

(2)简单工厂模式:后来出现了工厂,用户不再需要去创建宝马车,由工厂进行创建,想要什么车,直接通过工厂创建就可以了。比如想要320i系列车,工厂就创建这个系列的车。

(3)工厂方法模式:为了满足客户,宝马车系列越来越多,如320i、523i等等系列,一个工厂无法创建所有的宝马系列,于是又单独分出来多个具体的工厂,每个具体工厂创建一种系列,即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象,你需要指定某个具体的工厂才能生产车出来。

(4)抽象工厂模式:随着客户要求越来越高,宝马车必须配置空调,于是这个工厂开始生产宝马车和需要的空调。最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车。

下面我们就针对几种不同的工厂模式进行详细的说明:

二、简单工厂模式:

简单工厂模式的核心是定义一个创建对象的接口,将对象的创建和本身的业务逻辑分离,降低系统的耦合度,使得两个修改起来相对容易些,当以后实现改变时,只需要修改工厂类即可。

如果不使用工厂,用户将自己创建宝马车,具体UML图和代码如下:

public class BMW320 {public BMW320(){System.out.println("制造-->BMW320");}
}public class BMW523 {public BMW523(){System.out.println("制造-->BMW523");}
}public class Customer {public static void main(String[] args) {BMW320 bmw320 = new BMW320();BMW523 bmw523 = new BMW523();}
}

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

1、简单工厂模式的UML图:

  • 工厂类角色: 该模式的核心,用来创建产品,含有一定的商业逻辑和判断逻辑
  • 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
  • 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。

2、代码实现:

产品类:

abstract class BMW {public BMW(){}
}public class BMW320 extends BMW {public BMW320() {System.out.println("制造-->BMW320");}
}
public class BMW523 extends BMW{public BMW523(){System.out.println("制造-->BMW523");}
}

工厂类:

public class Factory {public BMW createBMW(int type) {switch (type) {case 320:return new BMW320();case 523:return new BMW523();default:break;}return null;}
}

用户类:

public class Customer {public static void main(String[] args) {Factory factory = new Factory();BMW bmw320 = factory.createBMW(320);BMW bmw523 = factory.createBMW(523);}
}

3、简单工厂模式的优缺点:

简单工厂模式提供专门的工厂类用于创建对象,实现了对象创建和使用的职责分离,客户端不需知道所创建的具体产品类的类名以及创建过程,只需知道具体产品类所对应的参数即可,通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

但缺点在于不符合“开闭原则”,每次添加新产品就需要修改工厂类。在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展维护,并且工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。

为了解决简单工厂模式的问题,出现了工厂方法模式。

三、工厂方法模式:

工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。在使用时,用于只需知道产品对应的具体工厂,关注具体的创建过程,甚至不需要知道具体产品类的类名,当我们选择哪个具体工厂时,就已经决定了实际创建的产品是哪个了。

但缺点在于,每增加一个产品都需要增加一个具体产品类和实现工厂类,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

1、工厂方法的 UML 结构图如下:

  • 抽象工厂 AbstractFactory: 工厂方法模式的核心,是具体工厂角色必须实现的接口或者必须继承的父类,在 Java 中它由抽象类或者接口来实现。
  • 具体工厂 Factory:被应用程序调用以创建具体产品的对象,含有和具体业务逻辑有关的代码
  • 抽象产品 AbstractProduct:是具体产品继承的父类或实现的接口,在 Java 中一般有抽象类或者接口来实现。
  • 具体产品 Product:具体工厂角色所创建的对象就是此角色的实例。

2、代码实现:

产品类:

abstract class BMW {public BMW(){}
}
public class BMW320 extends BMW {public BMW320() {System.out.println("制造-->BMW320");}
}
public class BMW523 extends BMW{public BMW523(){System.out.println("制造-->BMW523");}
}

工厂类:

interface FactoryBMW {BMW createBMW();
}public class FactoryBMW320 implements FactoryBMW{@Overridepublic BMW320 createBMW() {return new BMW320();}}
public class FactoryBMW523 implements FactoryBMW {@Overridepublic BMW523 createBMW() {return new BMW523();}
}

客户类:

public class Customer {public static void main(String[] args) {FactoryBMW320 factoryBMW320 = new FactoryBMW320();BMW320 bmw320 = factoryBMW320.createBMW();FactoryBMW523 factoryBMW523 = new FactoryBMW523();BMW523 bmw523 = factoryBMW523.createBMW();}
}

四、抽象工厂模式:

在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。

在介绍抽象工厂模式前,我们先厘清两个概念:

  • 产品等级结构:产品等级结构指的是产品的继承结构,例如一个空调抽象类,它有海尔空调、格力空调、美的空调等一系列的子类,那么这个空调抽象类和他的子类就构成了一个产品等级结构。
  • 产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如,海尔工厂生产海尔空调、海尔冰箱,那么海尔空调则位于空调产品族中。

产品等级结构和产品族结构示意图如下:

1、什么是抽象工厂模式:

抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象;并且通过隔离具体类的生成,使得客户端不需要明确指定具体生成类;所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

但该模式的缺点在于添加新的行为时比较麻烦,如果需要添加一个新产品族对象时,需要更改接口及其下所有子类,这必然会带来很大的麻烦。

2、UML结构图:

  • 抽象工厂 AbstractFactory:定义了一个接口,这个接口包含了一组方法用来生产产品,所有的具体工厂都必须实现此接口。
  • 具体工厂 ConcreteFactory:用于生产不同产品族,要创建一个产品,用户只需使用其中一个工厂进行获取,完全不需要实例化任何产品对象。
  • 抽象产品 AbstractProduct:这是一个产品家族,每一个具体工厂都能够生产一整组产品。
  • 具体产品 Product

3、代码实现:

通过抽象工厂模式,我们可以实现以下的效果:比如宝马320系列使用空调型号A和发动机型号A,而宝马230系列使用空调型号B和发动机型号B,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。

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

产品类:

//发动机以及型号
public interface Engine {}  public class EngineA implements Engine{  public EngineA(){  System.out.println("制造-->EngineA");  }
}
public class EngineB implements Engine{  public EngineB(){  System.out.println("制造-->EngineB");  }
}  //空调以及型号
public interface Aircondition {} public class AirconditionA implements Aircondition{  public AirconditionA(){  System.out.println("制造-->AirconditionA");  }
}
public class AirconditionB implements Aircondition{  public AirconditionB(){  System.out.println("制造-->AirconditionB");  }
}

创建工厂类:

//创建工厂的接口
public interface AbstractFactory {  //制造发动机public Engine createEngine();//制造空调 public Aircondition createAircondition();
}  //为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{     @Override  public Engine createEngine() {    return new EngineA();  }  @Override  public Aircondition createAircondition() {  return new AirconditionA();  }
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {  @Override  public Engine createEngine() {    return new EngineB();  }  @Override  public Aircondition createAircondition() {  return new AirconditionB();  }
}

客户:

public class Customer {  public static void main(String[] args){  //生产宝马320系列配件FactoryBMW320 factoryBMW320 = new FactoryBMW320();  factoryBMW320.createEngine();factoryBMW320.createAircondition();//生产宝马523系列配件  FactoryBMW523 factoryBMW523 = new FactoryBMW523();  factoryBMW523.createEngine();factoryBMW523.createAircondition();}
}

工厂模式小结:

1、工厂方法模式与抽象工厂模式的区别在于:

(1)工厂方法只有一个抽象产品类和一个抽象工厂类,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。

(2)抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例


设计模式系列文章:

Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)

Java设计模式之创建型:建造者模式

Java设计模式之创建型:单例模式

Java设计模式之创建型:原型模式

Java设计模式之结构型:适配器模式

Java设计模式之结构型:装饰器模式

Java设计模式之结构型:代理模式

Java设计模式之结构型:桥接模式

Java设计模式之结构型:外观模式

Java设计模式之结构型:组合模式

Java设计模式之结构型:享元模式

Java设计模式之行为型:策略模式

Java设计模式之行为型:模板方法模式

Java设计模式之行为型:责任链模式

Java设计模式之行为型:观察者模式

Java设计模式之行为型:访问者模式

Java设计模式之行为型:中介者模式

Java设计模式之行为型:命令模式

Java设计模式之行为型:状态模式

Java设计模式之行为型:备忘录模式

Java设计模式之行为型:迭代器模式

Java设计模式之行为型:解释器模式


参考文章:

设计模式读书笔记----简单工厂模式_chenssy 的技术博客-CSDN博客

设计模式读书笔记----工厂方法模式_chenssy 的技术博客-CSDN博客

设计模式读书笔记----抽象工厂模式_chenssy 的技术博客-CSDN博客

JAVA设计模式之抽象工厂模式_一个本科小生的奋斗史-CSDN博客_java抽象工厂模式

Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)相关推荐

  1. Java设计模式之创建型-建造者模式 (Builder)

  2. Java设计模式之创建型:原型模式

    一.什么是原型模式: 原型模式主要用于对象的创建,使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.UML类图如下: 原型模式的核心是就是原型类 Prototype,Prototype ...

  3. Java设计模式之创建型:建造者模式

    一.什么是建造者模式: 建造者模式将复杂产品的创建步骤分解在在不同的方法中,使得创建过程更加清晰,从而更精确控制复杂对象的产生过程:通过隔离复杂对象的构建与使用,也就是将产品的创建与产品本身分离开来, ...

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

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

  5. Java设计模式之创建型:单例模式

    一.什么是单例模式: 单例模式可以确保系统中某个类只有一个实例,该类自行实例化并向整个系统提供这个实例的公共访问点,除了该公共访问点,不能通过其他途径访问该实例.单例模式的优点在于: 系统中只存在一个 ...

  6. 23种设计模式之简单工厂模式,工厂方法模式,抽象工厂模式详解

    工厂模式详解 1. 简单工厂模式 1.1 需求分析 1.2 使用传统方式实现 1.2.1 类图 1.2.2 代码实现 1.2.2.1 新建pizza抽象类 1.2.2.2 希腊披萨实现类 1.2.2. ...

  7. 设计模式之工厂模式详解(附应用举例实现)

    文章目录 1 工厂模式介绍 2 工厂模式详解 2.1 简单工厂模式 2.1.1 简单工厂模式结构 2.1.2 简单工厂模式实现 2.1.3 简单工厂模式应用举例 2.2 工厂方法模式 2.2.1 工厂 ...

  8. Java设计模式:农场不同季节生成不同蔬菜水果的一种抽象工厂模式

    Java设计模式:农场不同季节生成不同蔬菜水果的一种抽象工厂模式 /*** 农场的抽象.不同季节生产不同的蔬菜和水果.*/ public interface Farm {//不同季节,不同蔬菜和水果. ...

  9. 设计模式(五)——建造者模式详解

    设计模式(五)--建造者模式详解 概述 结构 代码案例 优缺点 使用场景 模式扩展 创建者模式对比 工厂方法模式和建造者模式 抽象工厂模式和建造者模式 概述 建造者模式就是说将一个复杂对象的构建和表示 ...

  10. C++简单工厂模式详解

    C++简单工厂模式详解 1.问题引入 2.编写代码思路的迭代 2.1 main函数主体内编写全部代码 2.2 修改上述问题后的main函数代码 2.3 引入面向对象后的代码 2.4 加上继承和多态后的 ...

最新文章

  1. 深度学习100问:什么是深监督(Deep Supervision)?
  2. Hinton最新专访:别让AI解释自己,AI寒冬不会再来
  3. 团队冲刺第二阶段-2
  4. MATLAB实战系列(二十九)-头脑风暴优化(BSO)算法求解旅行商问题(TSP)-交叉算子
  5. 人人都可以做深度学习应用:入门篇
  6. 【Leetcode】创建链表
  7. Telerik RadGridView动态增删行及行列操作
  8. Java 并发:Executor ExecutorService ThreadPoolExecutor
  9. 学会放松,也是一项了不起的技能!
  10. Shell 变量的操作方法
  11. css degrees_带有Python示例的math.degrees()方法
  12. java通信项目_Java项目中的多线程通信如何利用Socket实现
  13. 如何迁移outlook邮件到另一个硬盘_如何注册Yahoo邮箱?
  14. AD的备份与标准还原:深入浅出Active Directory系列(四)
  15. CAD中怎么配置灭火器?
  16. spotbug常见错误心得
  17. lighttpd出现mod_indexfile.so: cannot open shared object file: No such file or directory
  18. R 计算均方差MSE(mean squared error)
  19. 如何使用宝塔搭建个人网站
  20. 东梓关富春江畔有感  文/江湖一劍客

热门文章

  1. @自我怀疑的开发者:你够优秀吗?
  2. 英文地址翻译原则:先小后大。如**号**路**区,
  3. 数据库方面是知识和实战
  4. Kubeadm部署单Master节点
  5. android定时器常用方法,Android计时器的三种实现方式
  6. python做估值模型_理解债券估值中的摊销/摊余成本,利用EXCEL+Python估值建模
  7. spring boot 报 http 406多种原因问题解决的总结
  8. 广西来宾中考计算机考试考什么,来宾中考信息管理系统 http://www.lbzklq.com
  9. [Hackerrank] Floyd : City of Blinding Lights
  10. 估值3000亿,中国最神秘电商公司,征服美国年轻人