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

在这里插入图片描述

创建者模式

抽象工厂模式

概念

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

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

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

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

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

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

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

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

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

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

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

实现步骤

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

  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 {
    
        @Override
        public Phone producePhone(String model) {
            return new ApplePhone(model);
        }
    
        @Override
        public 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;
        }
    
        @Override
        public 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;
        }
    
        @Override
        public void run() {
            System.out.println("我是苹果汽车,我百公里加速1秒");
        }
    }
    
  4. 按照规范打造了雪梨工厂,雪梨工厂中手机流水线生产出来的手机是雪梨手机PearPhone,汽车流水线生产出来的是雪梨汽车PearCar

    /**
     * 雪梨工厂。
     *
     * @author wanggt
     * @date 2023-06-17 11:30:21
     */
    public class PearFactory extends AbstractFactory {
    
        @Override
        public Phone producePhone(String model) {
            return new PearPhone(model);
        }
    
        @Override
        public Car produceCar(String color) {
            return new PearCar(color);
        }
    }
    
    public class PearPhone implements Phone {
        private final String model;
    
        public PearPhone(String model) {
            this.model = model;
        }
    
        @Override
        public 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;
        }
    
        @Override
        public 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秒
    

优缺点分析

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

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

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

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

架构训练营学习笔记:5-2 负载均衡架构

多级负载架构 设计关键点 性能需求、维护复杂度之间做取舍。 一可以去掉F5、LVS : F5 是成本较高,LVS 是复杂,对于性能没那么高需求,可以去掉。 二 去掉ng: 服务网关服务 适应于初创公司快速验证,内部的 小系统…

Typescript+React入门

初识Typescript 出现背景 Typescript(以下简称TS)实际上就是JavaScriptType,用数据类型的方式来约束了JS的变量定义 在JS的基础上增加了类型支持 在JS中大多数错误都是因为数据类型造成的,所以TS为了规避这个问题加入了类型限制…

C语言案例 按序输出三个整数-02

题目:输入三个整数a,b,c,按从小到大的顺序输出 步骤一:定义程序的目标 编写一个C程序,随机输入三个整数,按照从小到大的顺序输出。 步骤二:程序设计 整个程序由三个模块组成,第一个为scanf输入函数模块&a…

OA会议管理系统之会议通知(送审成功可查看人员是否参与会议)

一、前言 1.导读 在上一次的博文中我们实现了会议审批,会议通过审批后,状态就会由原来的待审核变为待开,这时候我们就可以在我的会议下的反馈详情查看人员是否参与会议的反馈情况。这篇博客就是来了解,人员是怎么接收会议通知并反…

MyBatis 查询数据库之二(增、删、改、查操作)

目录 1. 配置打印 MyBatis 执行的SQL 2. 查询操作 2.1 通过用户 ID 查询用户信息、查询所有用户信息 (1) Mapper 接口 (2)UserMapper.xml 查询所有用户的具体实现 SQL (3)进行单元测试 3. 增加操作 3.1 在 mapper(interface)里面添加增加方法的声…

unity如何手动更改脚本执行顺序

在Unity中,脚本的执行顺序是由脚本的执行顺序属性决定的。默认情况下,Unity根据脚本在项目中的加载顺序来确定它们的执行顺序。然而,你可以手动更改脚本的执行顺序,以下是一种方法: 在Unity编辑器中,选择你…

剑指Offer05.替换空格

剑指Offer05.替换空格 目录 剑指Offer05.替换空格题目描述解法一:遍历添加解法二:原地修改 题目描述 请实现一个函数,把字符串s中的每个空格都替换成“%20”。 解法一:遍历添加 由于每次替换都要把一个空格字符变成三个字符&a…

【LeetCode】516. 最长回文子序列

文章目录 1. 思路讲解1.1 创建dp表1.2 状态转移方程1.3 不需考虑边界问题 2. 整体代码 1. 思路讲解 1.1 创建dp表 此题采用动态规划的方法,创建一个二维dp表,dp[i][j]表示s[i, j]中最大回文子序列的长度。且我们人为规定 i 是一定小于等于 j 的。 1.2…

OpenAI 已为 GPT-5 申请商标,GPT-4 发布不到半年,GPT-5 就要来了吗?

据美国专利商标局(USPTO)信息显示,OpenAI已经在7月18日申请注册了“GPT-5”商标。 在这份新商标申请中,OpenAI将“GPT-5”描述为一种“用于使用语言模型的可下载计算机软件”。 继GPT-4发布之后,它预计将成为OpenAI下一…

vue响应数据为二维码如何渲染到页面

在postman测试请求后发现响应数据为一个二维码图片,不是链接,如何解决? 然后如果在vue中使用请求还会报Uncaught (in promise) SyntaxError: Unexpected token o in JSON at position 1的错误。这个就是使用了JSON.parse导致的响应格式不对),使用JSON.stringify解决…

骑砍二 ATC MOD 使用教程与应用案例解析

骑砍二 ATC MOD 使用教程与应用案例解析 作者:blibli-财不外漏 / NEXUSMODS-PuepleKarmen 案例MOD依赖:ATC - Adonnay’s Troop Changer & AEW - Adonnay’s Exotic Weaponry & New Armor 文本编辑工具:VS Code(推荐使用&…

Typescript - 索引签名

目录 1,什么是索引签名1,js 中使用对象的属性2,ts 中的索引签名3,扩展索引签名定义的类型 2,与 Record 对比3,遇到的问题1,索引 key 的类型问题,keyof2,索引 key 的类型问…

Zebec APP:构建全面、广泛的流支付应用体系

目前,流支付协议 Zebec Protocol 基本明确了生态的整体轮廓,它包括由其社区推动的模块化 Layer3 构架的公链 Nautilus Chain、流支付应用 Zebec APP 以及 流支付薪酬工具 Zebec payroll 。其中,Zebec APP 是原有 Zebec Protocol 的主要部分&a…

无向图-已知根节点求高度

深搜板子题&#xff0c;无向图&#xff0c;加边加两个&#xff0c;dfs输入两个参数变量&#xff0c;一个是当前深搜节点&#xff0c;另一个是父节点&#xff08;避免重复搜索父节点&#xff09;&#xff0c;恢复现场 ///首先完成数组模拟邻接表#include<iostream> #incl…

re学习(27)攻防世界toddler_regs(字符串函数总结+交叉引用)

找不到main&#xff08;&#xff09;函数&#xff0c;查找字符串&#xff0c;发现特殊字符串 定位字符串出现的位置&#xff0c;反汇编出代码&#xff0c;进行分析“ flag{Xp0int_1s_n1c3_but_Xp0intJNU_is_we1rd} 总结 一.CP&#xff1a;shiftF12 展示所有的字符串; ctrlx查…

python高阶技巧

目录 设计模式 单例模式 具体用法 工厂模式 优点 闭包 案例 修改闭包外部变量 闭包优缺点 装饰器 装饰器原理 装饰器写法 递归 递归的调用过程 递归的优缺点 用递归计算阶乘 设计模式 含义&#xff1a;设计模式是一种编程套路&#xff0c;通过这种编程套路可…

Linux-centos花生壳实现内网穿透

Linux-centos花生壳实现内网穿透 官网教程 1.安装花生壳 下载网址 点击复制就可以复制下载命令了 wget "https://dl.oray.com/hsk/linux/phddns_5.2.0_amd64.rpm" -O phddns_5.2.0_amd64.rpm# 下载完成之后会多一个rpm文件 [rootlocalhost HuaSheng]# ls phddns_…

Java8 list多属性去重

大家好&#xff0c;我是三叔&#xff0c;很高兴这期又和大家见面了&#xff0c;一个奋斗在互联网的打工人。 在 Java 开发中&#xff0c;我们经常会面临对 List 中的对象属性去重的需求。然而&#xff0c;当需要根据多个属性来进行去重时&#xff0c;情况会稍微复杂一些。本篇…

nodejs+vue鲜花商城销售系统 uniapp网上花店 多商家 微信小程序67m8n

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括鲜花销售微信小程序的网络应用&#xff0c;在外国各式各样的小程序已经是很普遍的方式&#xff0c;不过国内可能还处于起步阶段。鲜花销售微信小程序具有鲜花销售信息管理功能…

利用awk筛选给定时间范围内的日志

文章目录 筛选给定时间范围内的日志时间时间戳什么是时间戳&#xff1f; 系统时间 筛选日志时间示例简单示例mktime()函数是什么 进阶示例 筛选给定时间范围内的日志 时间 时间的表示方法&#xff1a; 时间戳系统时间&#xff08;年月日时间&#xff09; 时间戳 什么是时间…