Java设计模式(工厂模式)——抽象工厂模式(完整详解,附有代码+案例)

news2024/9/21 18:02:54

文章目录

    • 5.4 抽象工厂模式
      • 5.4.1 概述
      • 5.4.2 结构
      • 5.4.3 实现
      • 5.4.4 优缺点
      • 5.4.5 使用场景

5.4 抽象工厂模式

5.4.1 概述

是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

同族的不同等级的产品:通俗讲就是一个综合工厂里的不同商品种类

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级(即,同种的产品)的产品,而抽象工厂模式可生产多个等级(即,多种产品)的产品。

5.4.2 结构

抽象工厂模式的主要角色如下:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
  • 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

5.4.3 实现

现咖啡店业务发生改变,不仅要生产咖啡还要生产甜点,如提拉米苏、抹茶慕斯等,要是按照工厂方法模式,需要定义提拉米苏类、抹茶慕斯类、提拉米苏工厂、抹茶慕斯工厂、甜点工厂类,很容易发生类爆炸情况。其中拿铁咖啡、美式咖啡是一个产品等级,都是咖啡;提拉米苏、抹茶慕斯也是一个产品等级;拿铁咖啡和提拉米苏是同一产品族(也就是都属于意大利风味),美式咖啡和抹茶慕斯是同一产品族(也就是都属于美式风味)。所以这个案例可以使用抽象工厂模式实现。类图如下:

在这里插入图片描述

咖啡系列

// 抽象咖啡类
public abstract class Coffee {
    // 定义获取具体咖啡名字的规范
    public abstract String getName();

    // 咖啡加奶
    public  void addMilk(){
        System.out.println("加奶...");
    };
    // 咖啡加糖
    public void addSugar(){
        System.out.println("加糖...");
    };
}
========================================================
// 具体的 美式咖啡类  继承抽象咖啡类
public class AmericanCoffee extends Coffee{
    @Override
    public String getName() {
        return "美式咖啡";
    }
}
==========================================================
  // 具体的 拿铁咖啡类  继承抽象咖啡类
public class LatteCoffee extends Coffee{

    @Override
    public String getName() {
        return "拿铁咖啡";
    }
}

甜品系列

// 抽象甜品类
public abstract class Dessert {
    // 定义展示具体甜品的规范
    public abstract void show();
}
========================================================
  // 具体甜品--提拉米苏类 继承 抽象甜品类
public class Tiramisu extends Dessert{
    @Override
    public void show() {
        System.out.println("提拉米苏...");
    }
}
========================================================
  // 具体甜品--抹茶慕斯类  继承 抽象甜品类
public class MatchaMousse extends Dessert {
    @Override
    public void show() {
        System.out.println("抹茶慕斯...");
    }
}

工厂系列

 //抽象工厂

// 综合工厂 生产咖啡类  生产甜品类
public interface DessertFactory {

    // 生产咖啡
    public abstract Coffee createCoffee();

    // 生产甜品
    public abstract Dessert createDessert();

}
==========================================================
  //具体工厂
  
  // 意大利风味甜品工厂
  // 生产拿铁咖啡和提拉米苏甜品
public class ItalyDessertFactory implements DessertFactory{
    // 生产拿铁咖啡
    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }
    // 生产提拉米苏
    @Override
    public Dessert createDessert() {
        return new Tiramisu();
    }
}
=======================================================
  //具体工厂
  
  // 美式风味的甜品工厂
  // 生美式咖啡 和 抹茶慕斯
public class AmericanDessertFactory implements DessertFactory{
    // 生产美式咖啡
    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }

    // 生产抹茶慕斯
    @Override
    public Dessert createDessert() {
        return new MatchaMousse();
    }
}

客户端测试

public class ClientTest {
    public static void main(String[] args) {
// 客户端测试类

        // 创建意大利风味甜品工厂对象
        // 该工厂生产拿铁咖啡 和提拉米苏
        ItalyDessertFactory factory = 
          new ItalyDessertFactory();

        // 获取拿铁咖啡
        Coffee coffee = factory.createCoffee();
        System.out.println(coffee.getName());//拿铁咖啡

        // 获取提拉米苏
        Dessert dessert = factory.createDessert();
        dessert.show();//提拉米苏...


        // 创建美式风味的甜品工厂对象
        //该工厂生产美式咖啡 和抹茶慕斯
        AmericanDessertFactory factory1 = 
          new AmericanDessertFactory();

        // 获取美式咖啡
        Coffee coffee1 = factory1.createCoffee();
        System.out.println(coffee1.getName());//美式咖啡

        // 获取抹茶慕斯
        Dessert dessert1 = factory1.createDessert();
        dessert1.show();//抹茶慕斯...

    }
}

如果要加同一个产品族的话,只需要再加一个对应的工厂类即可,不需要修改其他的类。

5.4.4 优缺点

优点:

当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:

当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

5.4.5 使用场景

  • 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。

  • 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。

如:输入法换皮肤,一整套一起换。生成不同操作系统的程序。

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

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

相关文章

【保奖思路】2024年华为杯研赛F题保奖思路分享(后续会更新)

您的点赞收藏是我继续更新的最大动力! 一定要点击如下的卡片,那是获取资料的入口! 点击链接加入【2024华为杯研赛资料汇总】:https://qm.qq.com/q/TPBRkrVoQyhttps://qm.qq.com/q/TPBRkrVoQy F题X射线脉冲星光子到达时间建模 问…

STM32 通过 SPI 驱动 W25Q128

目录 一、STM32 SPI 框图1、通讯引脚2、时钟控制3、数据控制逻辑4、整体控制逻辑5、主模式收发流程及事件说明如下: 二、程序编写1、SPI 初始化2、W25Q128 驱动代码2.1 读写厂商 ID 和设备 ID2.2 读数据2.3 写使能/写禁止2.4 读/写状态寄存器2.5 擦除扇区2.6 擦除整…

【论文笔记】BEVNeXt: Reviving Dense BEV Frameworks for 3D Object Detection

原文链接:https://arxiv.org/pdf/2312.01696 简介:最近,在摄像头3D目标检测任务中,基于查询的Transformer解码器正在超越传统密集BEV方法。但密集BEV框架有着更好的深度估计和目标定位能力,能全面精确地描绘3D场景。本…

AI自动直播app盘点:2024超级实用十款应用平台,终结假AI时代!

AI自动直播app盘点:2024超级实用十款应用平台,终结假AI时代! 在2024年的科技浪潮中,AI自动直播技术迎来了前所未有的飞跃,终结了虚假AI的阴霾,为直播行业注入了全新的活力与可能。本文将为您盘点十款超级实…

el-table的树形结构结合多选框使用,实现单选父子联动,全选,反选功能

<template><div><el-table:data"tableData":row-key"rowKey":default-expand-all"defaultExpandAll":tree-props"treeProps"><!-- 开启树形多选 --><el-table-column v-if"showSelection" width…

无人机+自组网:中继通信增强技术详解

无人机与自组网技术的结合&#xff0c;特别是通过中继通信增强技术&#xff0c;为无人机在复杂环境中的通信提供了稳定、高效、可靠的解决方案。以下是对该技术的详细解析&#xff1a; 一、无人机自组网技术概述 无人机自组网技术是一种利用无人机作为节点&#xff0c;通过无…

【可测试性实践】C++单元测试:gtest gmock

引言 google test是目前C主流的单元测试框架&#xff0c;本文介绍如何在工程引入gtest和gmock&#xff0c;并提供入门参考示例。根据黄金圈思维我们先思考Why&#xff08;为什么做&#xff09;&#xff0c;为什么我们要进行单元测试&#xff0c;为什么要引入mock手段来测试代码…

Linux:路径末尾加/和不加/的区别

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 普通文件操作 首先说明这个问题只会出现在目录和符号链接中&#xff0c;因为如果想要索引普通文件但却在路径末尾加/则会出现错误&#xff0c;如例1所示。 # 例1 zhang…

Django SQL注入-漏洞分析

1.进入项目界面 图1 项目主界面 2.访问任意不存在的目录路径报错&#xff0c;提示存在demo接口 图2 提示存在接口 3.访问/demo/&#xff0c;提示有一个name参数 图3 发现隐藏参数 4.对接口参数进行fuzz&#xff08;实战思路&#xff09;&#xff0c;vulfocus已经给出了/demo?…

Innodb存储架构

Innodb整体存储架构 Innodb是一款兼顾性能及可靠性的存储引擎&#xff0c;主要分为内存存储结构和磁盘存储结构&#xff0c;二者分别扮演着提高性能和数据持久化的工作 内存结构中定义了缓冲池、变更缓冲区、日志缓冲区、自适应哈希四个缓冲区&#xff0c;它们均是为提升查询…

docker技术(上)

一、docker简介 Docker 是一个开源的应用容器引擎&#xff0c;于 2013 年由 Solomon Hykes 推出并开源。它基于 Go 语言开发&#xff0c;遵从 Apache2.0 协议。Docker 可以让开发者将应用及其依赖包打包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 或 Windows…

文件外发控制怎么做?公司文件外发管控的方法(这五种方法你一定要学会!)

还在担心重要文件发出去就"人间蒸发"&#xff1f; 或者每次发送公司机密都提心吊胆&#xff1f; 其实&#xff0c;文件外发就像放风筝&#xff0c;你需要时刻握住“线头”&#xff0c;确保它不会飞得太远&#xff01; 今天我们来揭秘五种公司文件外发的神级管控方法…

基于SpringBoot的医院挂号就诊系统【附源码】

基于SpringBoot的高校社团管理系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1界面设计原则 4.2功能结构设计 4.3.2 数据库物理设计 第5章 系统实现 5.1用户信息管理 5.2 医生信息管理 5.3公告类型管理 5.1公告信息管理 4…

C++进阶(2):多态

多态的概念 多态分为编译时多态(静态多态)和运行时多态(动态多态)。**编译时多态&#xff1a;**主要就是我们前面讲的函数重载和函数模版。之所以叫编译时多态&#xff0c;是因为实参传给形参的参数匹配是发生在编译时完成的&#xff08;ps&#xff1a;通常把编译时一般归为静…

常见项目场景题1(数据量很大时如何去重,实现超时处理)

数据很多&#xff0c;限制内存&#xff0c;如何去重 对于大数据量去重的场景&#xff0c;我们可以考虑使用位图(Bitmap) Bitmap 是使用二进制来表示某个元素是否存在的数组。用0和1来表示存在与不存在 使用Bitmap的话&#xff0c;一个数字占用1bit&#xff0c;大大减少内存消耗…

JVM 调优篇8 调优案例5- 逃逸分析

一 逃逸分析 1.1 概念 逃逸分析的基本行为就是分析对象动态作用域&#xff1a;当一个对象在方法中被定义后&#xff0c;对象只在方法内部使用&#xff0c;则认为没有发生逃逸。当一个对象在方法中被定义后&#xff0c;它被外部方法所引用&#xff0c;则认为发生逃逸。例如作为…

打造未来企业:业务能力建模的实践应用与数字化转型的落地策略

在当今数字化迅速发展的时代&#xff0c;企业的转型迫在眉睫。通过数字技术提升运营效率、增强客户体验、优化资源配置成为了企业竞争的核心战略。《业务能力指南》为企业提供了清晰的业务能力建模框架&#xff0c;并指导企业如何将其应用于实际操作中&#xff0c;帮助企业在数…

(三)代码实现:Boustrophedon Cellular Decomposition Path Planning用珊格地图生成每个cell的覆盖路径

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言算法原理方法一&#xff1a;全地图进行牛耕覆盖步骤方法二&#xff1a;区域分解地图进行牛耕覆盖步骤凸多边形基于栅格地图的…

Windows系统文件夹中的文件名排序

一天张三、李四的同事周五接到王哥的一个任务需求&#xff0c;有一个文件夹&#xff0c;里面有许多图片文件&#xff0c;网页访问某个分类展示文件的时候&#xff0c;王哥希望文件名的展示顺序可以按照Windows资源管理器中文件名升序排序的方式展示。 网站图片目录中有如下图片…

程序遇到问题错误bug时的13种解决方法途径总结以及之前的一些具体例子

目录 1 信心--没有解决不了的bug 2 耐心、不要着急、静下心来、用脑思考 2.1 开始解决问题前不要着急&#xff0c;先思考 2.2 在解决问题的过程中也不要着急&#xff0c;要冷静思考 3 网络搜索 4 大模型问答&#xff1a;必应、kimi、通义千问、文心一言 5 看芯片手册、S…