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

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!}
}

工厂模式在 JDK-Calendar应用的源码分析

JDK 中的 Calendar 类中,就使用了简单工厂模式

// getInstance 是 Calendar 静态方法
Calendar cal = Calendar.getInstance();//源码:
if (aLocale.hasExtensions()) {String caltype = aLocale.getUnicodeLocaleType("ca"); if (caltype != null) {switch (caltype) { case "buddhist":cal = new BuddhistCalendar(zone, aLocale);break;case "japanese":cal = new JapaneseImperialCalendar(zone, aLocale);break; case "gregory":cal = new GregorianCalendar(zone, aLocale);break;}}
}

总结

上面介绍的三种工厂模式有各自的应用场景,实际应用时能解决问题满足需求即可,可灵活变通,无所谓高级与低级。

此外无论哪种模式,由于可能封装了大量对象和工厂创建,新加产品需要修改已定义好的工厂相关的类,因此对于产品和工厂的扩展不太友好,利弊需要权衡一下。

  1. 工厂模式的意义

将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。

  1. 三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式)

  2. 设计模式的依赖抽象原则

    • 创建对象实例时,不要直接 new 类, 而是把这个 new 类的动作放在一个工厂的方法中,并返回。有的书上说, 变量不要直接持有具体类的引用。

    • 不要让类继承具体类,而是继承抽象类或者是实现 interface(接口)

    • 不要覆盖基类中已经实现的方法。

简单工厂模式只需要抽象产品的实现类即可,客户端传入产品类的类型,工厂返回对应的产品实例。(参考策略模式,可以有Map或枚举的实现方式)

工厂方法模式在简单工厂的基础上,把工厂方法细分,不同实现类实现工厂方法内容也不同,客户端使用不同的工厂实现类生产对应的实例。

抽象工厂模式在工厂方法模式的基础上,把工厂也细分,子工厂内容又是工厂方法模式,多个子工厂实现类生产对应的实例。

Java设计模式(三)——工厂模式相关推荐

  1. Java 设计模式之工厂模式(二)

    原文地址:Java 设计模式之工厂模式(二) 博客地址:http://www.extlight.com 一.背景 本篇内容是 Java 设计模式创建型模式的第二篇.上一篇主题为 <Java 设计 ...

  2. java设计模式之工厂模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  3. Java设计模式(工厂模式>抽象工厂模式和原型模式)

    Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...

  4. Java设计模式之工厂模式篇 (转)

    Java设计模式之工厂模式篇 (转)[@more@]Java设计模式之工厂模式篇 作者:冯睿  本文选自:赛迪网 2003年03月07日 .NET.com.cn/servlets/ad?Pool=te ...

  5. Java设计模式之 工厂模式(简单工厂模式)

    前一阵子学习了Java 中据说是最简单的设计模式的 单例模式,想一起讨论学习的小伙伴请点击这里: Java 设计模式之单例模式 那么今天就把学习的工厂模式记录下来 工厂模式: 实现了创建者和调用者的分 ...

  6. Java设计模式之工厂模式 (工厂方法模式)

    上一篇我们学习了简单工厂模式,最后对于增加新产品的缺点,我们在工厂方法模式中解决. 为学习简单工厂模式的小伙伴点击这里Java 设计模式之工厂模式(简单工厂模式) 工厂方法模式要点: 避免简单工厂模式 ...

  7. 【JAVA进阶系列】JAVA 设计模式 -- 抽象工厂模式(Abstract Factory)

    [JAVA进阶系列]JAVA 设计模式 -- 抽象工厂模式(Abstract Factory) [1.1]抽象工厂模式简介 抽象工厂者模式的类结构图 AbstractProduct(抽象产品),Abs ...

  8. JAVA设计模式之工厂模式讲解

    目录 前言 开始表演 前言 Java中使用工厂模式的主要原因是为了实现代码的灵活性和可维护性.工厂模式是一种创建型设计模式,它提供了一种将对象的创建和使用进行分离的方式.具体来说,工厂模式可以将对象的 ...

  9. JAVA设计模式之工厂模式(三种工厂模式)

    1.工厂模式可以分为三类: 简单工厂模式(Simple Factory) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 简单工厂其实不是一个标准的的设 ...

  10. Java设计模式:工厂模式

    问题提出 Java的工厂模式与现实生活中的工厂的模型是很相似的.工厂是用来做什么?当然是用来生成产品.因此在Java的工厂模式的关键点就是如何描述好产品和工厂这2个角色之间的关系. 下面来仔细描述一下 ...

最新文章

  1. 【Pytorch学习】用pytorch搭建第一个神经网络
  2. Python类的多态
  3. No enclosing instance of type JDStudent is acAcessible. Must qualify the allocation with an enclosin
  4. BOOST_VMD_ASSERT_IS_TUPLE宏相关的测试程序
  5. Storm Trident拓扑中的错误处理
  6. V4L2用户空间和kernel层driver的交互过程
  7. mysql中主从复制包括什么意思_Mysql主从复制作用和工作原理
  8. 【例题+习题】【数值计算方法复习】【湘潭大学】(一)
  9. C#代码中背后进行的值拷贝
  10. 流计算技术实战 - 超大维表问题
  11. django migrate无效的解决方法
  12. 转---《C#画线控件的开发应用实例解析》
  13. Kisssoft软件在行星齿轮设计上的初试
  14. 研发管理02----嵌入式硬件设计流程之完善
  15. 心酸的两天(1):Nacos 启动后输入默认密码后:“用户名或密码错误”
  16. mysql知识系列:报错right syntax to use near IDENTIFIED BY
  17. 2023需要重点关注的四大AI方向
  18. python 机器学习——特征筛选实现
  19. 误删桌面文件如何恢复?
  20. 英特尔边缘计算技术白皮书

热门文章

  1. cpu上干硅脂怎么清理_cpu老硅脂怎么清理
  2. Ubuntu20.04下没有亮度调节且找不到/sys/class/backlight文件夹(backlight里为空)的解决办法
  3. Android PayPal支付的接入和SDK支付过程解析
  4. windows镜像_windows系统重装之系统镜像的选择:鱼或熊掌的无奈
  5. oracle连接失败日志文件,Oracle中的联机日志文件发生不同程度损坏的恢
  6. 【CSS 教程系列第 12 篇】什么是 CSS 中的伪类选择器
  7. Flag Engine(动画系统)学习笔记(六)——动画片段
  8. 变形金刚3 部分台词
  9. MongoDB的安全认证
  10. Android之动画全讲-刘志远-专题视频课程