设计模式5—抽象工厂模式

news2024/11/25 13:48:51

5.抽象工厂模式

概念

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。抽象工厂又称为Kit模式,属于对象创建型模式。

抽象工厂可以将统一产品族的单独工厂封装起来,在正常使用中,客户端需要创建抽象工厂的实现,然后使用抽象工厂作为接口来创建这一主题的具体对象。客户端程序不需要知道它从这些内部的工厂方法中获得对象的具体类型,因为客户端程序仅使用这些对象的通用接口。抽象工厂模式将一组对象的实现细节与他们的一般使用分离开来。

用途

抽象工厂模式和工厂模式一样,都符合开放-封闭原则。但是不同的是,工厂模式是在新增一个具体的产品时,会增加对应的工厂。但抽象工厂模式只有在新增一个类型的具体产品时才需要新增工厂。也就是说,工厂模式的一个工厂只能创建一个产品,而抽象工厂模式的一个工厂是创建一类产品

场景:

  • 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
  • 系统中有多于一个的产品族,而每次只使用其中某一产品族。
  • 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而是客户端不依赖于具体实现。

实现方式:

抽象工厂模式包含如下角色:

  • 抽象工厂(AbstractFactory):用于声明生成抽象产品的方法。
  • 具体工厂(ConcreteFactory):实现抽象工厂声明的生成抽象产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
  • 抽象产品(AbstractProduct):为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法。
  • 具体产品(Product):定义具体工厂生成的具体类型对象,实现抽象产品接口中定义的业务方法。

举例

假如我们是一家汽车代工厂,我们负责奔驰和特斯拉两家公司制造车子。我们可以认为奔驰是加油的车子,特斯拉是充电的车子。其中奔驰和特斯拉都有跑车和商务车两种类型。

以上场景,我们就可以把跑车和商务车分别对峙,对于跑车有单独的工厂创建,商务车也有单独的工厂。这样,以后无论再帮哪家厂商造车,只要是跑车或者商务车我们就不需要再引入工厂。同样,如果要增加一种类型的车,比如越野车,我们也不需要对跑车或者商务车做任何东西的修改。

(1)抽象产品: 奔驰车和特斯拉

/**
 * 奔驰接口 - 抽象产品
 */
public interface BenzCar {
    /**
     * 加油车
     */
    public void gasUp();
}

/**
 * 特斯拉 - 抽象产品
 */
public interface TeslaCar {
    /**
     * 充电
     */
    public void charge();
}

(2)具体产品:奔驰商务车、奔驰跑车、特斯拉商务车、特斯拉跑车

/**
 * 奔驰商务车 - 具体产品
 */
public class BenzBusinessCar implements BenzCar {
    @Override
    public void gasUp() {
        System.out.println("奔驰商务车加油");
    }
}

/**
 * 奔驰跑车 - 具体产品
 */
public class BenzSportCar implements BenzCar {
    @Override
    public void gasUp() {
        System.out.println("给奔驰跑车加油");
    }
}


/**
 * 特斯拉商务车 - 具体产品
 */
public class TeslaBusinessCar implements TeslaCar {
    @Override
    public void charge() {
        System.out.println("特斯拉商务车加电");
    }
}

/**
 * 特斯拉电动车 - 具体产品
 */
public class TeslaSportCar implements TeslaCar {

    @Override
    public void charge() {
        System.out.println("特斯拉跑车充电");
    }
}

(3)抽象工厂:汽车工厂

/**
 * 汽车 - 抽象工厂
 */
public interface CarFactory {
    public BenzCar getBenzCar();
    public TeslaCar getTeslaCar();
}

(4)具体工厂:商务车工厂、跑车工厂

/**
 * 商务车工厂 - 具体工厂
 * @author <a href="zhang_gengying@dahuatech.com">zhang_gengying</a>
 * @Date: 2022/2/21
 * @Since 1.1.1
 */

public class BusinessCarFactory implements CarFactory {
    @Override
    public BenzCar getBenzCar() {
        return new BenzBusinessCar();
    }

    @Override
    public TeslaCar getTeslaCar() {
        return new TeslaBusinessCar();
    }
}

/**
 * 跑车工厂 - 具体工厂1
 */

public class SportCarFactory implements CarFactory {
    @Override
    public BenzCar getBenzCar() {
        return new BenzSportCar();
    }

    @Override
    public TeslaCar getTeslaCar() {
        return new TeslaSportCar();
    }
}

开闭原则的倾斜性

"开闭原则" 要求系统对扩展开放,对修改关闭,通过扩展达到增强的目的。对于涉及到多个产品族与多个产品等级结构的系统,其功能增强包括两方面:

增加产品族:对于增加新的产品族,工厂方法模式很好的支持了"开闭原则",对于新增加的产品族,只需要对应增加一个新的具体工厂即可,对已有代码无须做任何修改。

增加新的产品等级结构:对于增加新的产品等级结构,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法,不能很好地支持"开闭原则"。

抽象工厂模式的这种性质称为"开闭原则"的倾斜性,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,但不能为新的产品等级结构的增加提供这样的方便。

抽象工厂模式、工厂方法模式、简单工厂之间的关系

当抽象工厂模式中每一个具体工厂类只能创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式。

抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构。

当抽象工厂模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品,并将创建对象的工厂方法设计为静态方法时,抽象工厂模式就退化成简单工厂模式。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络笔记——网络层、传输层、应用层(方老师408课程)(持续更新)

文章目录 前言网络层网络层提供的两种服务网际协议——IP虚拟互联网络IP数据报格式逐一理解整体理解IP数据报分片与长度精算 IP地址IP地址概述分类的IP地址——ABCDE分类IP的子网划分不分类的IP地址——CIDRIP地址总结 IP分组的转发网际控制报文协议——ICMP下一代网络协议——…

我用 ChatGPT 干的 18 件事!【人工智能中文站创始人:mydear麦田访谈】

新建了一个网站 https://ai.weoknow.com/ 每天给大家更新可用的国内可用chatGPT 你确定你可以使用ChatGPT吗&#xff1f; 今天我整理了18种ChatGPT的使用方法&#xff0c;让大家看看你可以使用哪些。 1.语法修正 2.文本翻译 3.语言转换 4.代码解释 5.修复代码错误 6.作为百科…

初识HTML的基础知识点!!!

初识HTML&#xff01;&#xff01;&#xff01; 一、系统构架 1.B/S构架 &#xff08;1&#xff09;B/S构架&#xff08;Browser / Server) 就是&#xff08;浏览器/服务器的交互形式&#xff09; Browser支持HTML、CSS、JavaScript &#xff08;2&#xff09;优缺点 优点…

UI--基本组件

目录 1. Designer 设计师 2. Layout 布局 3. 基本组件 3.1 QWidget 3.2 ui指针 3.3 QLabel 标签&#xff08;掌握&#xff09; 示例代码&#xff1a; dialog.h dialog.cpp 3.4 QAbstractButton 按钮类&#xff08;掌握&#xff09; 示例代码&#xff1a; dialog.ui dialog.h di…

【MyBaits】SpringBoot整合MyBatis之动态SQL

目录 一、背景 二、if标签 三、trim标签 四、where标签 五、set标签 六、foreach标签 一、背景 如果我们要执行的SQL语句中不确定有哪些参数&#xff0c;此时我们如果使用传统的就必须列举所有的可能通过判断分支来解决这种问题&#xff0c;显示这是十分繁琐的。在Spring…

linux查看服务端口号、查看端口(netstat、lsof)以及PID对应服务

linux查看服务端口号、查看端口&#xff08;netstat、lsof&#xff09; netstat - atulnp会显示所有端口和所有对应的程序&#xff0c;用grep管道可以过滤出想要的字段 -a &#xff1a;all&#xff0c;表示列出所有的连接&#xff0c;服务监听&#xff0c;Socket资料 -t &…

说服审稿人,只需牢记这 8 大返修套路!

本文作者&#xff1a;雁门飞雪 如果说科研是一场修炼&#xff0c;那么学术界就是江湖&#xff0c;投稿就是作者与审稿人或编辑之间的高手博弈。 在这一轮轮的对决中&#xff0c;有时靠的是实力&#xff0c;有时靠的是技巧&#xff0c;然而只有实力和技巧双加持的作者才能长久立…

Qt--项目打包

项目打包 一款正常的软件产品应该在任何的计算机中运行&#xff0c;不需要单独安装Qt的开发环境&#xff0c;因此需要把之前的项目打包成一个安装包。 1. 设置应用图标 设置应用程序图标的操作步骤如下所示。 1. 下载一个图标图片&#xff0c;格式要求png。&#xff08;png包含…

学习Python的day.13

输入和输出 一、输入 标准输入&#xff1a;从键盘输入 input(promptNone) # prompt: 输入的提示符,可以为空 Read a string from standard input --- 译为&#xff1a;从标准输入读入一个字符串&#xff0c;输入读取的一定是字符串&#xff0c;返回值就是一个字符串 那我们…

基于知识图谱的个性化学习资源推荐系统的设计与实现(论文+源码)_kaic

摘 要 最近几年来&#xff0c;伴随着教育信息化、个性化教育和K12之类的新观念提出,一如既往的教育方法向信息化智能化的转变&#xff0c;学生群体都对这种不受时间和地点约束的学习方式有浓厚的兴趣。而现在市面上存在的推荐系统给学生推荐资料时不符合学生个人对知识获取的…

多态与虚函数

多态与虚函数 多态的引入多态与虚函数多态编译时多态运行时多态 多态的原理静态联编和动态联编 多态的引入 学过C继承的话应该都知道在继承中存在一种菱形继承&#xff0c;假设存在一个类&#xff08;person&#xff09;&#xff0c;其派生出两个子类&#xff0c;分别是studen…

Template Method模式

文章目录 &#x1f4a1;前言分类优点 &#x1f4a1;问题引入&#x1f4a1;概念&#x1f4a1;例子&#x1f4a1;总结 &#x1f4a1;前言 此文是第一篇讲解设计模式的文章&#xff0c;而笔者我又不想另起一篇来概述设计模式的分类&#xff0c;作用&#xff0c;以及优点&#xff…

MySQL笔记(四) 函数、变量、存储过程、游标、索引、存储引擎、数据库维护、指定字符集、锁机制

MySQL笔记&#xff08;四&#xff09; 文章目录 MySQL笔记&#xff08;四&#xff09;函数文本处理函数日期和时间处理函数数值处理函数类型转换函数流程控制函数自定义函数基本语法 局部变量全局变量聚集函数 aggregate functionDISTINCT 存储过程为什么要使用使用创建 删除建…

调用api实现ChatGPT接口余额查询

先打个广告&#xff1a; 推荐一款不用科学上网就可以使用的ChatGPT工具&#xff1a;智能聊天助手 体验版入口&#xff1a;智能聊天助手体验版 在ChatGPT官网可以查询接口使用额度&#xff0c;但是官方并没有提供相应的API给开发者调用。但是可以通过破解的方式找到它的API。方法…

人生在世皆有过错,来一起看看Java中的异常吧!!!

Java中的异常问题详解 一、异常的概念与分类 1.异常概念 概念&#xff1a;Java异常是一个描述在代码段中发生异常的对象&#xff0c;当发生异常情况时&#xff0c;一个代表该异常的对象被创建并且在导致该异常的方法中被抛出&#xff0c;而该方法可以选择自己处理异常或者传…

Invicti v23.5 for Windows 发布 - 企业应用安全测试

Invicti v23.5 for Windows - 企业应用安全测试 Invicti Standard 11 May 2023 v23.5.0.40516 请访问原文链接&#xff1a;https://sysin.org/blog/invicti/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Invicti 是一种自动…

[HFCTF2022]ezchain

环境分析 环境提供了docker-compose.yml&#xff0c;nginx.conf文件&#xff0c;从两个文件中可疑分析出是不出网的环境 nginx.conf&#xff1a; server { listen 80;server_name localhost;location / {root /usr/share/nginx/html; #收到/路径请求会访问/usr/sha…

Keil5----Debug时,watch1中全局变量数值不刷新问题解决方法

问题&#xff1a; 在Keil5-MDK中&#xff0c;Debug时&#xff0c;watch1中全局变量数值不刷新。 解决方法&#xff1a; 步骤1&#xff1a;进入Debug模式 将程序调试下载器&#xff08;STlink,Jlink,Ulink&#xff09;连接&#xff0c;编译程序后。 进行如下操作&#xff1a…

算法修炼之练气篇——练气十六层

博主&#xff1a;命运之光 专栏&#xff1a;算法修炼之练气篇 前言&#xff1a;每天练习五道题&#xff0c;炼气篇大概会练习200道题左右&#xff0c;题目有C语言网上的题&#xff0c;也有洛谷上面的题&#xff0c;题目简单适合新手入门。&#xff08;代码都是命运之光自己写的…

MySQL --- 多表查询

多表查询、事物、以及提升查询效率最有手段的索引 一. 多表查询 1.1 多表查询 --- 概述 1.1.1 数据准备 将资料中准备好的多表查询数据准备的SQL脚本导入数据库中。 部门表&#xff1a; 员工表&#xff1a; 1.1.2 介绍 多表查询&#xff1a;指从多张表中查询数据&#…