在客户端程序中过多的使用new去实例化就会造成耦合过强的问题。使用工厂模式可以有效地将这些实例化工作抽离到客户程序之外,使程序更多的依赖抽象类而不是具体的类,从而解耦。

简单工厂

简单工厂将同源类的实例化工作(new)归类一个独立的“工厂类”中执行,好让具体实例化的过程从客户代码中移除,起到解耦的作用。

书中以Pizza店为例,架构写的比较庞大,因为需要偷懒,这里以文具店卖笔为例。
Stationer为文具店实例,一共卖3种笔,Pen是所有笔的超类。客户需要获取其中一种笔时,只需向Stationer.getPen方法传入具体的type,即可获取到对应的Pen实例。

public class SimplePenFactory {public static Pen getPen(String type){if("art".equals(type)){return new ArtPen();}else if ("ink".equals(type)){return new InkPen();}else if("ballpoint".equals(type)){return new BallPointPen();}System.out.println("Invalid Type");return null;}
}

简单工厂是常见的一种用法,但书中认为“简单工厂”并不算真正的设计模式,而更像一种编程习惯。

工厂方法模式

“工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。”

通俗地来讲,就是将“工厂类”中创建对象的方法变成抽象的,并由继承它的子“工厂类”来实现,这样就可以由子类来具体决定实例化哪些类。

接着以文具店的例子来看,如果Pen的子类增多并有质量一般和质量较好的差别,商家增开到2家“文具店”并各自售卖不同质量的笔。使用工厂方法模式,这里要将“工厂类”分成2个(同超类),各自负责实例化不同质量的笔。

那么将原来的工厂类的接口getPen(String type)转成abstract,并创建2个子类GeneralStationer和DeluxeStationer,各自售卖一般和贵的文具笔,Pen的实例化工作也由这2个子类来实现(各自实现了getPen接口)。

public abstract class Stationer {public abstract Pen getPen(String type);
}

2个Stationer的子类,各自负责实例化不同质量的笔。尽管对客户来说,传入的type参数是一样的,但是实际上这2个“工厂”产生的实例并不同:

class GeneralStationer extends Stationer{@Overridepublic Pen getPen(String type) {if("art".equals(type)){return new ArtPen();}else if ("ink".equals(type)){return new InkPen();}else if("ballpoint".equals(type)){return new BallPointPen();}System.out.println("Invalid Type");return null;}}class DeluxeStationer extends Stationer{@Overridepublic Pen getPen(String type) {if("art".equals(type)){return new GoodArtPen();}else if ("ink".equals(type)){return new GoodInkPen();}else if("ballpoint".equals(type)){return new GoodBallPointPen();}System.out.println("Invalid Type");return null;}}

工厂方法模式通过让工厂子类决定创建的具体对象时哪些,来达到将对象创建过程封装的目的。组成元素有:
1)创建者(工厂类)
2)产品类(单一产品类型,所有产品均继承自同一个父类)。

抽象工厂模式

“抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类”

抽象工厂与前面2种概念有点区别,抽象工厂模式目的是创建一组对象。
文具店当然不止有笔(Pen)卖,现在种类增加了橡皮擦(Eraser)和笔盒(PencilCase),而所有这些种类的文具都有好坏,有2个不同的文具工厂生产:

工厂方法模式只负责一种类型的创建,而抽象工厂模式可以创建一个产品的家族。事实上它们比较容易互相配合的,试想Pen类需要笔芯,笔头,笔壳组装而成,那么抽象工厂模式就可以为上游笔厂提供这些原料。

PS:例子中将Factory和各种文具设计成接口,是这本书推崇的原则——“少用继承多用组合”

“依赖倒置原则”

作者特意提到了这个原则:

“要依赖抽象,不要依赖具体类”

尽量依赖抽象,不要依赖具体类,便于得到更松耦合并有弹性的实现。

小结

  • 所有工厂都是用来封装对象创建的
  • 工厂方法使用继承,将创建对象的任务交给子类。
  • 抽象工厂使用对象组合,且创建对象的任务实现在接口中。
  • 工厂帮助我们针对抽象编程,不依赖具体类。所有工厂模式都通过减少程序和具体类之间的依赖促进松耦合。

HeadFirst设计模式笔记——工厂模式相关推荐

  1. 狂神设计模式笔记-工厂模式

    文章目录 一.简单工厂模式 二.工厂方法模型 核心本质: 实例化对象不使用new,用工厂方法代替 将选择实现类,创建对象统一管理和控制.从而将调用者跟我们的实现类解耦 详细分类: 简单工厂模式:用来生 ...

  2. 设计模式 - 学习笔记 - 工厂模式Factory Pattern

    设计模式 - 学习笔记 - 工厂模式Factory Pattern 1. 简单工厂 1.1 应用场景 1.2 UML 1.3 优劣分析 好处 缺点 1.4 代码示例 抽象产品 AbstractProd ...

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

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

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

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

  5. JavaScript设计模式--简单工厂模式例子---XHR工厂

    JavaScript设计模式--简单工厂模式例子---XHR工厂 第一步,Ajax操作接口(目的是起一个接口检测作用) (1)引入接口文件 //定义一个静态方法来实现接口与实现类的直接检验 //静态方 ...

  6. 三角形圆形创建与擦除java_设计模式---------------简单工厂模式

    设计模式---------------简单工厂模式 一.题目(Question) 使用简单工厂模式设计一个可以创建不同几何形状(如圆形.方形和三角形等)的绘图工具,每个几何图形都要有绘制draw()和 ...

  7. 策略模式和工厂模式的区别_设计模式之工厂模式-工厂方法模式

    设计模式之工厂模式-工厂方法模式 大家好,欢迎来到污污弹公司,今天司小司又接到了一个新活-披萨项目. 来源:凯哥Java(kaigejava) 需求: 披萨项目: 要方便披萨品种的扩展.要便于维护.要 ...

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

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

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

    上一次我们已经通过代码,简单的认识了工厂方法模式,具体的思路请移步到设计模式之工厂模式(二),进行查看.这次,让我们通过设计模式的思想,来好好认识下工厂方法模式. 创建者和产品 所有工厂模式都用来封装 ...

最新文章

  1. java 进程睡眠_Linux进程的睡眠和唤醒简析
  2. 织梦DEDE后台定时分时段自动更新发布文章插件
  3. 在scala中访问postgresql(使用sbt)
  4. Robots on a Grid CodeForces - 1335F(拓扑排序+正反建图+判环)
  5. Docker(一):基础入门篇
  6. Java 算法 邮票
  7. Python交互界面方向键、退格键乱码
  8. 基于SSM的NBA篮球球队运营系统
  9. 智能电能计量管理系统
  10. 新品齐聚CES 各家首发预示2013智能机大屏四核走向(转)
  11. php网站登录界面验证码打不开,php网站无法显示验证码
  12. 注册表关闭计算机默认共享,4种方法教你彻底关闭WINDOWS默认共享
  13. 心知天气数据API 产品的高并发实践
  14. 硬件设计之DDS AD9854
  15. Command python setup.py egg_info failed with error code 1 in /private/var/folders/14/4hz051qx0wqd3
  16. eclipse打开报错:Failed to load the JNI shared library
  17. 涉密系统集成资质办理条件 企业认证有哪些好处?
  18. oppo r17听筒测试软件,扔掉工具尺子!OPPO R17 Pro实用功能到来:
  19. Unity大魔王私藏的开发2D游戏的常用插件合集
  20. 一个轻巧高效的多线程c++stream风格异步日志(一)

热门文章

  1. 法卡斯定理(Fakars' Lemma)
  2. 崩坏3服务器维护2月8号,《崩坏3》2月8日更新内容 符华月轮正式上线
  3. 继续分享最新版本的autohotkey自己编写的快捷键
  4. IGRP/EIGRP 内部网管路由选择协议
  5. 共享办公室,推送企业紧密合作
  6. 自动透视校正为四边形对象
  7. PE文件格式系列译文之
  8. HR面试,你需要注意什么?
  9. 谈谈对springioc的理解
  10. 数据扒一扒《隐秘的角落》到底怎么火的?