一文学透设计模式——抽象工厂模式

在这里插入图片描述

创建者模式

抽象工厂模式

概念

抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这是很多地方对于抽象工厂模式的描述,说实话感觉不是特别好懂。

按我的理解,用大白话讲,就是定义一套工厂的规范,按照这套规范可以创建很多的工厂,生产出不同的产品。

我们拿牛马人生公司为例。

假如苹果公司找到了牛马人生公司,跟牛马人生公司说,你帮我代加工生产手机和汽车等等一系列苹果公司的产品,但是要求生产苹果产品的工厂内必须只能生产苹果公司的产品。

牛马人生公司满口答应,多大点事对吧。

第二天,又有一个雪梨公司也找到了牛马人生公司,也要求代加工雪梨公司的产品,要求跟苹果公司一样。

牛马人生公司想了想也同意了。

牛马人生公司找到了工厂设计人员,总工程师想了想,苹果公司跟雪梨公司生产的产品都是一样的,何不设计一套工厂的规范,按照此工厂规范建造的工厂,就能满足苹果、雪梨这类的科技公司,后面还有什么西瓜公司、南瓜公司,也都可以按照这套规范来建造工厂。

于是乎,工厂创建规范出炉了,规范定义了,必须要有手机生产流水线、汽车组装流水线等等。

这一套定义工厂创建规范,并按照规范创建工厂,生产对应产品的思路就是抽象工厂模式。

实现步骤

下面我们用代码来表示这个逻辑。

  1. 首先我们定义了一个抽象类AbstractFactory,用来表示工厂的创建规范,如下面的代码所示,我们定义了这一类的工厂,必须要有生产手机和汽车的能力。规范里并没有告诉工厂要怎么生产产品,这些在具体的工厂中去完成。

    /*** 抽象工厂。* 抽象工厂里定义了这个工厂所能获取的所有产品(对象)。具体创建这些产品的行为在子类中实现。** @author wanggt* @date 2023-06-17 11:19:21*/
    public abstract class AbstractFactory {/*** 生产手机。** @param model 型号** @author wanggt* @date 2023-06-17 11:22:34*/public abstract Phone producePhone(String model);/*** 生产汽车。** @param color 颜色** @author wanggt* @date 2023-06-17 11:26:02*/public abstract Car produceCar(String color);
    }
    
  2. 我们的规范中除了定义了工厂的规范,还简单地定义了生产出来的产品有什么功能。例如,手机得可以打电话吧,汽车得能走吧。这些功能可能不同的公司实现的方式不同,比如有些汽车用油,有些汽车用电。规范里不管,我只说明,得有这个功能,才能叫做汽车。

    /*** 手机的接口定义。** @author wanggt* @date 2023-06-17 11:26:37*/
    public interface Phone {/*** 拨打电话。** @author wanggt* @date 2023-06-17 11:27:28*/void call(String targetNum);
    }
    
    /*** 汽车的接口定义。** @author wanggt* @date 2023-06-17 11:27:45*/
    public interface Car {/*** 往前冲。** @author wanggt* @date 2023-06-17 11:28:28*/void run();
    }
    
  3. 现在开始按照规范来打造工厂了。苹果工厂中手机流水线生产出来的手机是苹果手机ApplePhone,汽车流水线生产出来的是苹果汽车AppleCar

    /*** 苹果工厂。** @author wanggt* @date 2023-06-17 11:29:43*/
    public class AppleFactory extends AbstractFactory {@Overridepublic Phone producePhone(String model) {return new ApplePhone(model);}@Overridepublic Car produceCar(String color) {return new AppleCar(color);}
    }
    
    /*** 苹果手机** @author wanggt* @date 2023-06-17 11:32:44*/
    public class ApplePhone implements Phone {private final String model;public ApplePhone(String model) {this.model = model;}@Overridepublic void call(String targetNum) {System.out.println("你好,我是苹果手机,型号 " + model + ",你是" + targetNum);}
    }
    
    /*** 苹果汽车** @author wanggt* @date 2023-06-17 16:57:03*/
    public class AppleCar implements Car {private final String color;public AppleCar(String color) {this.color = color;}@Overridepublic void run() {System.out.println("我是苹果汽车,我百公里加速1秒");}
    }
    
  4. 按照规范打造了雪梨工厂,雪梨工厂中手机流水线生产出来的手机是雪梨手机PearPhone,汽车流水线生产出来的是雪梨汽车PearCar

    /*** 雪梨工厂。** @author wanggt* @date 2023-06-17 11:30:21*/
    public class PearFactory extends AbstractFactory {@Overridepublic Phone producePhone(String model) {return new PearPhone(model);}@Overridepublic Car produceCar(String color) {return new PearCar(color);}
    }
    
    public class PearPhone implements Phone {private final String model;public PearPhone(String model) {this.model = model;}@Overridepublic void call(String targetNum) {System.out.println("你好,我是雪梨手机,型号 " + model + ",你是" + targetNum);}
    }
    
    public class PearCar implements Car {private final String color;public PearCar(String color) {this.color = color;}@Overridepublic void run() {System.out.println("我是雪梨汽车,百公里加速100秒");}
    }
    
  5. 苹果公司看到雪梨公司也建了一个跟他一样的公司,这还得了,立马联系上了牛马人生公司的商务部门,要求多增加一套苹果工厂。牛马人生公司的商务部门向高层领导投诉,设计部门写的规范太难懂了,这不是他们商务部门要去研究的东西。这个时候,设计部门给商务部门提供了一套规则。如果是apple公司,就创建AppleFactory工厂,如果是pear公司,就创建PearFactory工厂。商务很满意,设计这么简单,这不是有手就行。

    public class FactoryProducer {/*** 获取工厂。** @param company 公司** @author wanggt* @date 2023-06-17 14:11:05*/public static AbstractFactory getFactory(String company) {if ("apple".equalsIgnoreCase(company)) {return new AppleFactory();} else if ("pear".equalsIgnoreCase(company)) {return new PearFactory();} else {return null;}}
    }
    
  6. 工厂红红火火开工了,工厂建好之后,又试运行了下流水线,一台台手机,一辆辆汽车从工厂里生产出来,总设计师感到很满足。终于又为公司干了点实事,今年的裁员应该轮不到他了吧。

    public class AbstractFactoryPatternDemo {public static void main(String[] args) {// 创建一个苹果公司的工厂,并生产对应的产品AbstractFactory appleFactory = FactoryProducer.getFactory("apple");Phone phone = appleFactory.producePhone("11");phone.call("1234567890");Car appleCar = appleFactory.produceCar("白色");appleCar.run();System.out.println("====================");// 创建一个雪梨公司的工厂,并生产对应的产品AbstractFactory pearFactory = FactoryProducer.getFactory("pear");Phone pearPhone = pearFactory.producePhone("30");pearPhone.call("12343453464562");Car pearCar = pearFactory.produceCar("黄色");pearCar.run();}
    }
    
    你好,我是苹果手机,型号 11,你是1234567890
    我是苹果汽车,我百公里加速1秒
    ====================
    你好,我是雪梨手机,型号 30,你是12343453464562
    我是雪梨汽车,百公里加速100秒
    

优缺点分析

我们现在来分析下总工程师设计的这一套工厂创建规范。

优点就是按照这套工厂创建规范打造出来的工厂,生产出来的产品都是同一个产品族的,要么都是苹果公司的产品,要么都是雪梨公司的产品。进入苹果工厂,闭着眼睛也能知道,里面生产的全部苹果公司的产品。手机必定是苹果手机,而不可能是雪梨手机。

而且接下来如果有类似的公司找到牛马人生公司的时候,完全可以按照这套工厂创建规范,再创建一个西瓜工厂即可。

但是缺点也是有的。总工程师摸了摸下巴,没有告诉其他人这个缺点。

那就是假如以后苹果公司增加了一些产品,例如苹果飞机,那必然就要修改工厂创建规范。修改了工厂创建规范之后,还得去扩建苹果工厂,去增加这个流水线。

但是雪梨公司并不会生产飞机,那么这个时候,雪梨工厂里面出现了一点问题,雪梨工厂里面有为生产飞机的预留位置,实际上并不会生产飞机,这多少让雪梨公司的人不爽。因为那为生产飞机预留的位置,似乎一直在提醒他们,你雪梨公司就是比苹果公司差。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/77695.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云二级域名配置

阿里云二级域名配置 首先需要进入阿里云控制台的域名管理 1.选择域名点击解析 2.添加记录 3.选择A类型 4.主机记录设置【可以aa.bb或者aa.bb.cc】 到时候会变成:aa.bb.***.com 5.解析请求来源设置为默认 6.记录值 设置为要解析的服务器的ip地址 7.TTL 默认即…

linux Ubuntu 更新镜像源、安装sudo、nvtop

1.更换镜像源 vi ~/.pip/pip.conf在打开的文件中输入: pip.conf [global] index-url https://pypi.tuna.tsinghua.edu.cn/simple按下:wq保存并退出。 2.安装nvtop 如果输入指令apt install nvtop报错: E: Unable to locate package nvtop 需要更新一下apt&a…

<C/C++>日期和时间的使用(time相关函数大全)

1、函数详解及示例 1- time_t time(time_t *time); 1)功能:获取或设置系统时间。 2)参数:若给定参数,则将当前时间保存到该参数中;若不给定参数,参数填NULL。 3)返回值&#xff1…

RTT(RT-Thread)时钟管理

目录 时钟管理 时钟节拍 RTT工程目录结构介绍 配置文件:rtconfig.h 获取系统节拍 获取系统节拍数函数 实例 定时器 RT_Thread定时器介绍 定时器源码分析(了解即可) rt_system_timer_init (硬件定时器初始化) rt_system_timer_thr…

pycharm出现python test运行报错(pytest模式)

pycharm出现python test运行报错 一、python test 执行代码报错二、删除运行配置三、修改pycharm默认配置为 unittests四、成功! 一、python test 执行代码报错 二、删除运行配置 三、修改pycharm默认配置为 unittests 四、成功!

怎么修改pdf文件中的文字?分享几种编辑方法

怎么修改pdf文件中的文字?PDF格式的文件通常具有很高的可读性和稳定性,但是如果需要修改其中的文字,就需要使用专门的PDF编辑器。本文将介绍几种PDF编辑的方法,下面就跟着我一起来看看这几款工具吧。 方法一:使用迅捷P…

python爬虫1:基础知识

python爬虫1:基础知识 前言 ​ python实现网络爬虫非常简单,只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点,方便以后复习。 目录结构 文章目录 python爬虫1:基础知识1. 基础认知1.1 什么是爬虫&…

servlet生命周期和初始化参数传递

servlet生命周期和初始化参数传递 1、servlet生命周期 只有第一次访问才会初始化,之后访问都只执行service中的。 除非tomcat关闭重新启动: 2、初始化参数传递

Rust 编程小技巧摘选(6)

目录 Rust 编程小技巧(6) 1. 打印字符串 2. 重复打印字串 3. 自定义函数 4. 遍历动态数组 5. 遍历二维数组 6. 同时遍历索引和值 7. 迭代器方法的区别 8. for_each() 用法 9. 分离奇数和偶数 10. 判断素数(质数) Rust 编程小技巧(6) 1. 打印…

SpringBoot+Vue 实现图片验证码功能需求

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 前言 写过验证码保存到Redis中的需求开发、也写过验证码调用第三方接口…

阿里云瑶池 PolarDB 开源官网焕新升级上线

导读近日,阿里云开源云原生数据库 PolarDB 官方网站全新升级上线。作为 PolarDB 开源项目与开发者、生态伙伴、用户沟通的平台,将以开放、共享、促进交流为宗旨,打造开放多元的环境,以实现共享共赢的目标。 立即体验全新官网&…

MacOS上配置docker国内镜像仓库地址

背景 docker官方镜像仓库网速较差,我们需要设置国内镜像服务 我的MacOS docker版本如下 设置docker国内镜像仓库地址 点击Settings点击Docker Engine修改配置文件,添加registry-mirrors {"builder": {"gc": {"defaultKeepS…

IDEA基础使用

IDEA基础使用 1、IDEA中显示用法和用户截图展示有调用显示无调用显示 对应方法 2、如何找出项目中所有不被调用方法截图展示对应方法 3、常用代码(Code)说明及快捷键:4、未完待续待日后更新。。。总结:欢迎指导,也祝码友们代码越来越棒,技术越…

SpringCloud Gateway获取请求响应body大小

前提 本文获取请求、响应body大小方法的前提 : 网关只做转发逻辑,不修改请求、相应的body内容。 SpringCloud Gateway内部的机制类似下图,HttpServer(也就是NettyServer)接收外部的请求,在Gateway内部请求将会通过Htt…

五、JVM-垃圾回收算法

常见的回收算法:标记清除算法、复制算法、标记-整理算法、分代收集算法 1、标记清除算法 第一步:标记(找出内存中需要回收的对象,并且把它们标记出来) 第二步:清除 (清除掉被标记需要回收的对…

Windows下JDK安装与环境变量配置

文章目录 每日一句正能量前言安装步骤配置环境变量验证环境变量是否配置成功后记 每日一句正能量 生命,就像一场永无休止的苦役,不要惧怕和拒绝困苦,超越困苦,就是生活的强者。任何经历都是一种累积,累积的越多,人就越成熟;经历的越多,生命就越有厚度。 本来不想写JDK的安装的&…

全国高校招投标信息在哪里看?

很多投标人在查询招标信息的时候常常没有找到合适的,但是现在网上查询投标信息的网站是很多的。而学校招标信息获取的渠道是比较少的,企业的反而更多一些,那么我们能在那些渠道获取这些信息? 1.教育部网站 教育部提供了招标信息…

8.Winform界面打包成DLL提供给其他的项目使用

背景 希望集成一个Winform的框架,提供权限菜单,根据权限出现各个Winform子系统的菜单界面。不希望把所有的界面都放放在同一个解决方案下面。用各个子系统建立不同的解决方案,建立代码仓库,进行管理。 实现方式 将Winform的UI界…

微信小程序页面传值为对象[Object Object]详解

微信小程序页面传值为对象[Object Object]详解 1、先将传递的对象转化为JSON字符串拼接到url上2、在接受对象页面进行转译3、打印结果 1、先将传递的对象转化为JSON字符串拼接到url上 // info为对象 let stationInfo JSON.stringify(info) uni.navigateTo({url: /pages/statio…

开源进展 | WeBASE v3.1.0发布,新增多个实用特性

WeBASE是一个友好、功能丰富的区块链中间件平台,通过一系列通用功能组件和实用工具,助力社区开发者更快捷地与区块链进行交互。 目前WeBASE已更新迭代至v3.1.0版本,本次更新中,WeBASE带来了最新的合约Java脚手架导出功能&#xff…