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

文章目录

  • 介绍
  • 开始
    • 架构图(以穿搭举例)
    • 样例一(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();
        }
    }


}

总结

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

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

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

相关文章

开源模型应用落地-CodeQwen模型小试-集成langchain(四)

一、前言 通过学习代码专家模型&#xff0c;开发人员可以获得高效、准确和个性化的代码支持。这不仅可以提高工作效率&#xff0c;还可以在不同的技术环境中简化软件开发工作流程。代码专家模型的引入将为开发人员带来更多的机会去关注创造性的编程任务&#xff0c;从而推动软件…

webpack并行构建示例:

由于js的单线程特性&#xff0c;文件和任务时 要等待一个任务执行完成后执行下一个任务&#xff0c;但在实际开发中&#xff0c;很多任务是可以并行执行的&#xff08;如同时处理多个不同js文件或同事压缩多张图片&#xff09;&#xff0c;一些loader和插件&#xff08;thread-…

交通地理信息系统实习教程(二)

这篇文章服务于GIS背景用户以及有志于GIS的朋友 操作源数据位置&#xff1a;【免费】交通地理信息系统实习二源数据资源-CSDN文库 软件安装包位置&#xff1a;【免费】TransCad-交通地理信息系统软件资源-CSDN文库 一、最短路径分析 1.1软件启动说明 这里需要给出一个必要的…

png格式怎么压缩的更小?用这几个方法轻松搞定

png格式支持透明背景&#xff0c;因此在网页设计中经常使用&#xff0c;经常用于创建图标、按钮、徽标和其他元素&#xff0c;使其能够与不同背景颜色和图像融合&#xff0c;实现更好的视觉效果&#xff0c;所以有时候我们就会遇到需要把png图片压缩小一点的情况&#xff0c;这…

【计算机网络】Socket网络编程

&#x1f4bb;文章目录 &#x1f4c4;前言Socket编程基础概念工作原理 Socket API介绍socket函数绑定、监听函数accept、connect接受/发送函数 Socket API的应用Socket类与其派生类的设计服务器与客户端的设计使用 &#x1f4d3;总结 &#x1f4c4;前言 现今我们的日常生活当中…

【经典文献】光声立体成像的对极几何

文献标题&#xff1a;《Epipolar Geometry of Opti-Acoustic Stereo Imaging》作者列表&#xff1a;Shahriar Negahdaripour发表期刊&#xff1a;IEEE Transactions on Pattern Analysis and Machine Intelligence发表年份&#xff1a;2007DOI链接&#xff1a;10.1109/TPAMI.20…

EPS软件标注点坐标值

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

Lists.partition用法详解

文章目录 一、引入依赖二、用法三、输出 一、引入依赖 依赖于谷歌的guava 包 <!-- guava --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>28.1-jre</version></dependency&…

LeetCode算法题:49. 字母异位词分组(Java)

给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat", …

【吃透Java手写】5-RPC-简易版

【吃透Java手写】RPC-简易版-源码解析 1 RPC1.1 RPC概念1.2 常用RPC技术或框架1.3 初始工程1.3.1 Productor-common&#xff1a;HelloService1.3.2 Productor&#xff1a;HelloServiceImpl1.3.3 Consumer 2 模拟RPC2.1 Productor2.2 模拟一个RPC框架2.2.1 HttpServer2.2.2 Http…

如何安全高效地进行4S店文件分发,保护核心资产?

4S店与总部之间的文件分发是确保双方沟通顺畅、信息共享和决策支持的重要环节。4S店文件分发涉及到以下文件类型&#xff1a; 销售报告&#xff1a;4S店需要定期向总部提交销售报告&#xff0c;包括销售数量、销售额、市场份额等关键指标。 库存管理文件&#xff1a;包括车辆库…

Linux-基础IO

&#x1f30e;Linux基础IO 文章目录&#xff1a; Linux基础IO C语言中IO交互       常用C接口         fopen         fputs         fwrite         fgets 当前路径       三个文件流 系统文件IO       open函数     …

windows 环境下安装《车辆动态监控系统》支持JT808、JT1078、苏标主动安全设备接入

《车辆动态监控系统》下载安装部署包 开放端口 80/443/8800&#xff0c;web后台端口&#xff0c;nginx代理服务&#xff0c;nginx默认为8800端口8808&#xff0c;JT808专用端口6802&#xff0c;视频播放推流端口6891-6898&#xff0c;FTP端口6821&#xff0c;苏标主动安全附件…

一. Ast - 反混淆(基础篇)

目录 ​编辑 1. 什么是Ast-了解 2. 什么是反混淆-了解 3. 了解Ast结构 4. 思考 5. 前置准备 6. 什么是babel 7. 安装babel 8. ast反混淆代码基本结构 9. babel中的组件 parser与generator 组件 traverse 组件 与visitor enter与exit visitor 其他写法 traverse …

Python API和微服务的测试库之httpretty使用详解

概要 在现代软件开发中,API和微服务的测试是确保应用稳定性和功能正确性的关键环节。Python的HTTPretty库提供了一个强大的工具,允许开发者在不实际发起网络请求的情况下模拟HTTP请求和响应。本文将全面介绍HTTPretty的安装、特性、基本与高级功能,并结合实际应用场景,展示…

FebHost:什么是汤加.TO域名?

什么是.TO域名&#xff1f; 汤加域名是指在顶级域.to下注册的域名&#xff0c;.to域名是汤加的国家代码顶级域&#xff08;ccTLD&#xff09;。它类似于其他特定国家的域名后缀&#xff0c;如美国的”.us “或英国的”.uk”。 汤加国家介绍 汤加正式名称为汤加王国&#xff…

Java入门基础学习笔记19——关系运算符、逻辑运算符

关系运算符&#xff1a; 判断数据是否满足条件&#xff0c;最终会返回一个判断的结果&#xff0c;这个结果是布尔类型的值&#xff1a;true或false。 注意&#xff1a;在java中判断是否相等一定是“”&#xff0c;不要把“”写成“”&#xff0c;“”是赋值表达式。 package c…

【kubeflow文档】kubeflow介绍与架构

1. kubeflow介绍 Kubeflow项目致力于使机器学习&#xff08;ML&#xff09;工作流在Kubernetes上的部署变得简单、可移植和可扩展。目标不是重新创建其他服务&#xff0c;而是提供一种直接的方法&#xff0c;将ML的开源系统部署到不同的基础设施中。无论在哪里运行Kubernetes&a…

2.1 软件工程

第2章 信息技术知识 2.1 软件工程 现状&#xff1a; 开发软件的规模越来越大复杂度越来越高用户需求并不十分明确缺乏软件开发方法和工具方面的有效支持 软件成本日益增长、开发进度难以控制、软件质量无法保证、软件维护困难等问题日益突出。人们开始用工程的方法进行软件…

K8S -----二进制搭建 Kubernetes v1.20

目录 一、准备环境 1.1 修改主机名 1.2 关闭防火墙&#xff08;三台一起&#xff0c;这里只展示master01&#xff09; 1.3 在master添加hosts&#xff08;依旧是三台一起&#xff09; 1.4 调整内核参数并开启网桥模式 二、部署docker引擎 三、部署 etcd 集群 1.在mast…