上一节我们已经学习了原型模式,稍微复习一下:通过重写Object 类的clone() 方法实现浅克隆,浅克隆也要实现Cloneable 标记接口。而深克隆则是将对象通过序列化和反序列化 的方式进行创建和还原。

本小结将学习的是工厂模式,这个模式在平时是特别常用的,还需好好理解。我也将举一些例子给大家

从生活出发

假设我们今天不想做饭,想出去吃饭、肯定选定一家好吃的川菜馆,然后我们找好位置坐下,给厨师说,我想吃糖醋排骨。 稍微等待几分钟、菜就可以做好,然后给你呈上来。

这是一个很经典的例子,我们平时也经常有这样的实际问题,你发现了么?

  • 我只需要告诉厨师菜名,我要吃啥就行了
  • 我不关注这个菜是怎么生产的 new()

开始撸代码

  1. /**
  2. * 抽象产品 菜
  3. */
  4. public interface FoodProduct {
  5. void show();
  6. }
  7. ------------
  8. /**
  9. * 具体产品
  10. */
  11. public class HongShao implements FoodProduct {
  12. @Override
  13. public void show() {
  14. System.out.println("红烧排骨");
  15. }
  16. }
  17. ------------
  18. public class TangCu implements FoodProduct {
  19. @Override
  20. public void show() {
  21. System.out.println("糖醋鱼");
  22. }
  23. }

创建厨房工厂

创建一个厨房类,厨房可以用来生产食物产品,我们只需要告诉厨房,这里是通过id 编号的形式告诉厨房的。我们只需要告诉厨房所需要的食物 而不关心这个食物产品是如何创建出来的。

  1. public class KitchenFactory {
  2. /**
  3. * id=1 上菜红烧肉 id=2 糖醋鱼
  4. * @param id
  5. */
  6. public FoodProduct cooking(int id) {
  7. if (1 == id) {
  8. return new HongShao();
  9. } else {
  10. return new TangCu();
  11. }
  12. }
  13. }
  1. KitchenFactory kitchen = new KitchenFactory();
  2. FoodProduct food = kitchen.cooking(1);
  3. food.show();
  4. --------
  5. 红烧排骨

理解工厂模式

通过这个简单的例子,我们可以学习到:

  • 无需关注对象是如何创建的。只需通过指定的关键字 就能拿到我需要的产品,这就是简单工厂模式。

抽象工厂

http://c.biancheng.net/view/1351.html

抽象工厂,就是简单工厂的抽象版、如何理解呢?我们上面的工厂(厨房)它已经是一个确定的对象 了。而抽象工厂,则是在厨房 的基础上,再次衍生出一个接口,我们的厨房 则是这个抽象类的一个具体实例化。

代码源于生活

我又要开始举栗子了。请细细品

我们都知道小米 小米既可以生产手机 也可以生产电器用品 那么这就是一个很好的例子。

小米抽象工厂 是一个巨大的工厂,它里面有小米手机工厂 以及小米电器工厂 而不同的工厂,则生产不同的产品

代码教学开始

首先,我们得需要一个抽象工厂,这个工厂可以包含手机工厂和电器工厂。

  1. public interface AbstractFactory {
  2. /**
  3. * 创建手机工厂
  4. * @return
  5. */
  6. PhoneFactory phoneFactory();
  7. /**
  8. * 创建电器工厂
  9. * @return
  10. */
  11. ElectricalFactory electricalFactory();
  12. }

当然,手机工厂不知道是具体哪个工厂,反正它可以做一些事情,比如创建手机。

  1. public interface PhoneFactory {
  2. /**
  3. * 手机工厂可以做的事情
  4. */
  5. void show();
  6. }
  7. -----------
  8. public interface ElectricalFactory {
  9. /**
  10. * 电器工厂可以生产电器
  11. */
  12. void show();
  13. }

上手实际创建一个小米工厂


  1. public class XiaoMiFactory implements AbstractFactory {
  2. @Override
  3. public PhoneFactory phoneFactory() {
  4. return new XiaoMiPhoneFactory();
  5. }
  6. @Override
  7. public ElectricalFactory electricalFactory() {
  8. return new XiaoMiElectricalFactory();
  9. }
  10. }
  11. -------------
  12. public class XiaoMiElectricalFactory implements ElectricalFactory {
  13. @Override
  14. public void show() {
  15. System.out.println("小米电器工厂可以生产电器。。比如小米扫地机器人");
  16. }
  17. }
  18. -------------
  19. public class XiaoMiPhoneFactory implements PhoneFactory {
  20. @Override
  21. public void show() {
  22. System.out.println("小米手机工厂可以生产小米手机。。。");
  23. }
  24. }

当然,小米工厂实现抽象工厂,那小米工厂就必须要包含两个子工厂,手机工厂和电器工厂了。我们也可以创建一个华为工厂,其实是一样的道理。

  1. AbstractFactory factory = new XiaoMiFactory();
  2. PhoneFactory phoneFactory = factory.phoneFactory();
  3. phoneFactory.show();
  4. --------
  5. 小米手机工厂可以生产小米手机。。。

我们从创建的小米工厂中拿出小米手机工厂 然后再执行手机工厂可以做事情,抽象工厂,就是在上面的简单工厂的层次上进行了再次的抽象,将具体的工厂进行抽象。

假设我们按照上面的逻辑。对于一个工厂,我想要一部手机 我给工厂说一声就行了。我不关心这个手机 是如何生产出来的。我该怎么操作?

我稍微将之前的几个接口作为稍微的改造。

  1. public interface PhoneFactory {
  2. /**
  3. * 手机工厂可以做的事情
  4. */
  5. PhoneProduct show();
  6. }
  7. ---------------
  8. public class XiaoMiPhoneFactory implements PhoneFactory {
  9. @Override
  10. public PhoneProduct show() {
  11. return new PhoneProduct(1, "小米10 Pro");
  12. }
  13. }
  14. ----------
  15. //手机对象
  16. public class PhoneProduct {
  17. private int id;
  18. private String name;
  19. }

我们可以创建这样一个访问器,通过访问器对象,将我们需要的对象名称传入就好比下单 它能自动匹配工厂,并且调用工厂创建产品 的方法,将我们需要的产品进行创建。

  1. public class AbstractFactoryClient {
  2. public PhoneProduct createPhone(String name) {
  3. AbstractFactory factory = null;
  4. if ("xiaomi" == name) {
  5. factory = new XiaoMiFactory();
  6. } else {
  7. factory = new HuaweiFactory();
  8. }
  9. PhoneFactory phoneFactory = factory.phoneFactory();
  10. return phoneFactory.show();
  11. }
  12. }

测试一下

  1. AbstractFactoryClient factoryClient = new AbstractFactoryClient();
  2. PhoneProduct product = factoryClient.createPhone("xiaomi");
  3. System.out.println(product);
  4. -----------
  5. 手机铭牌 编号:1,型号:小米10 Pro

小结

学习完本节,是否对于工厂模式和抽象工厂有了一个深入的了解呢?工厂模式其实在平时的代码中,还是比较常用的。所以还是需要更加努力学习和使用!

代码示例

https://gitee.com/mrc1999/Dev-Examples

参考

http://c.biancheng.net/view/1351.html

欢迎关注

JAVA设计模式 3【创建型】理解工厂模式与抽象工厂模式的更多相关文章

  1. Java设计模式之创建型模式

    创建型模式分为五类:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 一.工厂方法模式:接口-实现类.工厂类

  2. Java设计模式_创建型模式_单例模式

    单例模式的实现: 定义一个类,在类中定义该类的静态变量,再定一个一个获取该类的静态变量的方法. UML图:

  3. Java设计模式(3)——创建型模式之抽象工厂模式(Abstract Factory)

    一.概述 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象. UML图: 其他的过多概念不再 ...

  4. java设计模式 -------- 创建模式 之 抽象工厂模式

    本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 工厂方法模式和抽象工厂模式不好区分清楚: 工厂方法模式特点: 1. 一个抽象产品 ...

  5. Typescript玩转设计模式 之 创建型模式

    作者简介 joey 蚂蚁金服·数据体验技术团队 前言 我们团队的工作是用单页面应用的方式实现web工具.涉及到数万到十数万行的前端代码的管理,而且项目周期长达数年. 怎么样很好地管理好这种量级的前端代 ...

  6. GoF的23种设计模式之创建型模式的特点和分类

    创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”.这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成.就像我们去商场购买商品时, ...

  7. Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  8. Java设计模式之【工厂模式】(简单工厂模式,工厂方法模式,抽象工厂模式)

    Java设计模式之[工厂模式](简单工厂模式,工厂方法模式,抽象工厂模式) 工厂模式出现的原因 在java中,创建一个对象最简单的方法就是使用new关键字.但在一些复杂的业务逻辑中,创建一个对象不只需 ...

  9. 设计模式01 创建型模式 - 建造者模式(Build Pattern)

    参考 1. Builder Design Pattern | Youtube 2. 建造者模式(Builder和Director)| 博客园 3. 深入理解Builder模式 | 简书 建造者模式(B ...

随机推荐

  1. 【Linux】CentOS7安装tomcat8.5.45,这方法也太简单了吧!

    1.下载tomcat https://tomcat.apache.org/download-80.cgi 选择tar.gz.下载完大概9495kb大小的压缩包 2.将文件从Windows复制到Cent ...

  2. (Java实现) 友好城市

    1263:[例9.7]友好城市 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 1867 通过数: 1032 [题目描述] Palmia国有一条横贯东西的大河,河有笔直的南北两岸, ...

  3. Java实现 LeetCode 691 贴纸拼词(DFS+map记录)

    691. 贴纸拼词 我们给出了 N 种不同类型的贴纸.每个贴纸上都有一个小写的英文单词. 你希望从自己的贴纸集合中裁剪单个字母并重新排列它们,从而拼写出给定的目标字符串 target. 如果你愿意的话 ...

  4. Java实现 LeetCode 373 查找和最小的K对数字

    373. 查找和最小的K对数字 给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k. 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2. 找 ...

  5. Java实现 LeetCode 202 快乐数

    202. 快乐数 编写一个算法来判断一个数是不是"快乐数". 一个"快乐数"定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过 ...

  6. Java实现 LeetCode 85 最大矩形

    85. 最大矩形 给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积. 示例: 输入: [ ["1","0","1 ...

  7. java实现 蓝桥杯 算法提高 Problem S4: Interesting Numbers 加强版

    1 问题描述 Problem Description We call a number interesting, if and only if: 1. Its digits consists of o ...

  8. TZOJ 数据结构实验--静态顺序栈

    描述 创建一个顺序栈(静态),栈大小为5.能够完成栈的初始化.入栈.出栈.获取栈顶元素.销毁栈等操作. 顺序栈类型定义如下: typedef struct {  int data[Max];    i ...

  9. Php-webdriver 的安装与使用教程

    Php-webdriver 是 Facebook 开发的基于 PHP 语言实现的 Selenium WebDriver 客户端组件,可以用它来操作浏览器.常见的操作包括:自动化测试.采集数据等. 安装 ...

  10. js实现点击切换checkbox背景图片

    在制作网页的过程中,经常需要实现点击切换背景图片的效果,本文关注的是表单中checkbox背景图片切换的实现.如图,在输入用户名和密码后,用户需要选择是否记住密码 图片背景为白色表示未勾选状态 ,背景 ...