原文作者: alpha_panda

原文地址:设计模式之工厂模式(factory pattern)

工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。本文从一个具体的例子逐步深入分析,来体会三种工厂模式的应用场景和利弊。

1. 简单工厂模式

该模式对对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象,其UML类图如下:

下面我们使用手机生产来讲解该模式:

Phone类:手机标准规范类(AbstractProduct)

public interface Phone {void make();
}

 MiPhone类:制造小米手机(Product1)

public class MiPhone implements Phone {public MiPhone() {this.make();}@Overridepublic void make() {// TODO Auto-generated method stubSystem.out.println("make xiaomi phone!");}
}

IPhone类:制造苹果手机(Product2)

public class IPhone implements Phone {public IPhone() {this.make();}@Overridepublic void make() {// TODO Auto-generated method stubSystem.out.println("make iphone!");}
}

PhoneFactory类:手机代工厂(Factory)

public class PhoneFactory {public Phone makePhone(String phoneType) {if(phoneType.equalsIgnoreCase("MiPhone")){return new MiPhone();}else if(phoneType.equalsIgnoreCase("iPhone")) {return new IPhone();}return null;}
}

 演示:

public class Demo {public static void main(String[] arg) {PhoneFactory factory = new PhoneFactory();Phone miPhone = factory.makePhone("MiPhone");            // make xiaomi phone!IPhone iPhone = (IPhone)factory.makePhone("iPhone");    // make iphone!}
}

2. 工厂方法模式(Factory Method)

和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,其UML类图如下:

也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。接下来继续使用生产手机的例子来讲解该模式。其中和产品相关的Phone类、MiPhone类和IPhone类的定义不变。

AbstractFactory类:生产不同产品的工厂的抽象类

public interface AbstractFactory {Phone makePhone();
}

XiaoMiFactory类:生产小米手机的工厂(ConcreteFactory1)

public class XiaoMiFactory implements AbstractFactory{@Overridepublic Phone makePhone() {return new MiPhone();}
}

AppleFactory类:生产苹果手机的工厂(ConcreteFactory2)

public class AppleFactory implements AbstractFactory {@Overridepublic Phone makePhone() {return new IPhone();}
}

演示:

public class Demo {public static void main(String[] arg) {AbstractFactory miFactory = new XiaoMiFactory();AbstractFactory appleFactory = new AppleFactory();miFactory.makePhone();            // make xiaomi phone!appleFactory.makePhone();        // make iphone!}
}

3. 抽象工厂模式(Abstract Factory)

上面两种模式不管工厂怎么拆分抽象,都只是针对一类产品Phone(AbstractProduct),如果要生成另一种产品PC,应该怎么表示呢?最简单的方式是把2中介绍的工厂方法模式完全复制一份,不过这次生产的是PC。但同时也就意味着我们要完全复制和修改Phone生产管理的所有代码,显然这是一个笨办法,并不利于扩展和维护。抽象工厂模式通过在AbstarctFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干。其UML类图如下:

从上面类图结构中可以清楚的看到如何在工厂方法模式中通过增加新产品接口来实现产品的增加的。接下来我们继续通过小米和苹果产品生产的例子来解释该模式。为了弄清楚上面的结构,我们使用具体的产品和工厂来表示上面的UML类图,能更加清晰的看出模式是如何演变的:

PC类:定义PC产品的接口(AbstractPC)

public interface PC {void make();
}

MiPC类:定义小米电脑产品(MIPC)

public class MiPC implements PC {public MiPC() {this.make();}@Overridepublic void make() {// TODO Auto-generated method stubSystem.out.println("make xiaomi PC!");}
}
MAC类:定义苹果电脑产品(MAC)
public class MAC implements PC {public MAC() {this.make();}@Overridepublic void make() {// TODO Auto-generated method stubSystem.out.println("make MAC!");}
}

下面需要修改工厂相关的类的定义:

AbstractFactory类:增加PC产品制造接口


public interface AbstractFactory {Phone makePhone();PC makePC();
}

XiaoMiFactory类:增加小米PC的制造(ConcreteFactory1)

public class XiaoMiFactory implements AbstractFactory{@Overridepublic Phone makePhone() {return new MiPhone();}@Overridepublic PC makePC() {return new MiPC();}
}

AppleFactory类:增加苹果PC的制造(ConcreteFactory2)

public class AppleFactory implements AbstractFactory {@Overridepublic Phone makePhone() {return new IPhone();}@Overridepublic PC makePC() {return new MAC();}
}

演示:

public class Demo {public static void main(String[] arg) {AbstractFactory miFactory = new XiaoMiFactory();AbstractFactory appleFactory = new AppleFactory();miFactory.makePhone();            // make xiaomi phone!miFactory.makePC();                // make xiaomi PC!appleFactory.makePhone();        // make iphone!appleFactory.makePC();            // make MAC!}
}

总结:

上面介绍的三种工厂模式有各自的应用场景,实际应用时能解决问题满足需求即可,可灵活变通,无所谓高级与低级。此外无论哪种模式,由于可能封装了大量对象和工厂创建,新加产品需要修改已定义好的工厂相关的类,因此对于产品和工厂的扩展不太友好,利弊需要权衡一下。

欢迎转载博客文章,转载请标明出处!

创建型模式—工厂模式相关推荐

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

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

  2. JavaScript 设计模式核⼼原理与应⽤实践 之 创建型:工厂模式·抽象工厂——理解“开放封闭”

    JavaScript 设计模式核⼼原理与应⽤实践 之 创建型:工厂模式·抽象工厂--理解"开放封闭" 一个不简单的简单工厂引发的命案 在实际的业务中,我们往往面对的复杂度并非数个类 ...

  3. 设计模式(20):创建型-抽象工厂模式(Abstract Factory)

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...

  4. 【创建型】工厂模式(Factory Pattern)详解

    工厂模式分为简单工厂.工厂方法.抽象工厂模式. 这一篇说一下简单工厂.工厂方法: 简单工厂 :用来生产同一等级结构中的任意产品.(不支持拓展增加产品) 工厂方法 :用来生产同一等级结构中的固定产品.( ...

  5. (创建型)设计模式——工厂模式(factory)

    ps:在以下讲述工厂模式中,模仿的场景如下:我们需要生产Car,建立相对应的CarFactory.使用CarFactory工厂来生产Car,并且可以在生产过程中进行一些处理.类图和代码如下. 1.Mo ...

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

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

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

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

  8. 创建型设计模模式---原型模式

    设计模式 序号 内容 链接地址 1 设计模式七大原则 https://blog.csdn.net/qq_39668819/article/details/115390615 2 创建型设计模式–工厂模 ...

  9. 创建型设计模模式---建造者模式

    设计模式 序号 内容 链接地址 1 设计模式七大原则 https://blog.csdn.net/qq_39668819/article/details/115390615 2 创建型设计模式–工厂模 ...

  10. 设计模式-创建型模式-工厂模式(工厂三兄弟) TypeScript

    设计模式-创建型模式-工厂模式(工厂三兄弟) TypeScript 简单工厂模式 定义一个接口,三个具体类.然后书写如下,通过选择,生产出相应的对象 // 定义Shape接口 interface Sh ...

最新文章

  1. 微信公众平台消息接口API指南
  2. 利用pickle保存模型
  3. Java黑皮书课后题第7章:***7.36(游戏:八皇后问题)经典的八皇后难题是要将八个皇后放在棋盘上,任何两个皇后都不能相互攻击(没有两个皇后在同行、同列、同一对角线)。编写程序显示一个解决方案
  4. Leet Code OJ 4. Median of Two Sorted Arrays [Difficulty: Hard]
  5. 命令行下安装的tensorflow怎么打开_CourseMaker微课制作教程18:录ppt一直“正在打开……”及WPS下ppt满屏放映怎么办?...
  6. python单例模式继承_Python四种实现单例模式的方法
  7. C/C++基础语法复习(二):C++ 面向对象编程,你需要知道的点
  8. ContextLoaderListener的作用详解
  9. ora03135连接失去联系 进程id 0_Daemon 进程的创建
  10. uni一t 说明书_不输特斯拉,站在UNI-T背后的长安「超级工厂」
  11. 向eclipse中导入myeclipse项目
  12. 低延时互动直播双十一优惠活动
  13. linux内核分析与应用 -- 进程与线程(下)
  14. 《房地产周期》pdf、mobi、epub、txt下载
  15. 《谷物大脑》笔记(初稿)
  16. ROS 入门基础(二) 创建publisher
  17. bzoj5139 [Usaco2017 Dec]Greedy Gift Takers(二分答案+模拟)
  18. Deep Learning Paper读后简记
  19. 十二、Cadence 514 614 Calibre license许可问题
  20. set_global_opts全局设置

热门文章

  1. 【WIN10】移植opencc到WIN10-UWP,實現自己的繁簡轉換工具
  2. PPI是什么?pixels per inch像素密度是什么?PPI如何计算?
  3. 【附源码】计算机毕业设计SSM物流配送系统
  4. 一周AI资讯|如果深度学习成为“侦探”,会发生什么?
  5. 关于右键auto病毒清除
  6. C语言程序设计(谭浩强第五版)——习题
  7. 初学Python来用它制作一个简单的界面
  8. Wireshark 的RTMP抓包里面0x0 unknown的问题
  9. 第一章 ArcMap、ArcCatalog、 ArcToolbox基础入门操作
  10. 数据库设计第一范式(1NF)