java抽象工厂实战与总结

news2024/11/17 23:25:19

文章目录

  • 一、工厂模式(三种)
    • 1.简单工厂模式
      • 1.1 概念:
      • 1.2 `使用场景`:
      • 1.3 模型图解:
      • 1.4 伪代码:
    • 2.工厂方法模式
      • 2.1 概念:
      • 2.2 `使用场景`:
      • 2.3 模型图解:
      • 2.4 伪代码
    • 3.抽象工厂模式
      • 3.1 概念
      • 3.2 `使用场景`
      • 3.3 模型图解:以两层模型做例子
      • 3.4 伪代码
      • 3.4.1 以品牌角度设计工厂
      • 3.5 实战:抽象工厂+策略模式
        • 3.5.1 业务方法调用
        • 3.5.2 抽象工厂创建二级工厂,定义获取业务对象接口(二级工厂去创建具体的业务对象)
        • 3.5.3 二级工厂 获得对象
        • 3.5.3 二级工厂 具体的业务对象
        • 3.5.3 处理的业务
    • 补充:6大设计原则
    • 3.6 总结:


一、工厂模式(三种)

1.简单工厂模式

1.1 概念:

通过一个工厂类来创建对象,根据不同的参数或条件返回相应的对象实例。
隐藏了对象的创建细节,客户端只需通过工厂类获取对象而不需要直接实例化对象。

1.2 使用场景

使用者:根据不同的参数或条件返回相应的对象实例

1.3 模型图解:

角色:手机总工厂、参数、手机、小米手机、华为手机
后续补充:

1.4 伪代码:

public class SimpleFactoryTest {

    static class SimpleFactory {
        static SimpleFactoryTest.Mobile createMobile(int mobileType) throws Exception {
            if (mobileType == 1) {
                return new SimpleFactoryTest.HuaWei();
            } else if (mobileType == 2) {
                return new SimpleFactoryTest.XiaoMi();
            } else {
                throw new Exception("手机类型不存在!!!");
            }
        }
    }

    public static class Mobile {
        protected void call() {
            System.out.println("mobile...");
        }
    }

    public static class HuaWei extends Mobile {
        public void call() {
            System.out.println("huaWei...");
        }
    }

    public static class XiaoMi extends Mobile {
        public void call() {
            System.out.println("xiaomi...");
        }

    }

    public static void main(String[] args) throws Exception {
        SimpleFactoryTest.Mobile mobile = SimpleFactory.createMobile(1);
        mobile.call();
    }
}

2.工厂方法模式

2.1 概念:

定义了一个创建对象的接口,具体对象的创建由对象工厂决定。
使得对象的创建延迟到子类工厂,从而实现了对扩展开放、对修改关闭的原则。

2.2 使用场景

使用者:根据不同的子工厂创建相应的对象实例

2.3 模型图解:

角色:手机总工厂、小米手机工厂、华为手机工厂、手机、小米手机、华为手机
后续补充

2.4 伪代码

public class FactoryMethodTest {

    interface FactoryMethod {
        Mobile createMobile();
    }

    static class HuaweiFactory implements FactoryMethod {
        @Override
        public Mobile createMobile() {
            return new Huawei();
        }
    }

    static class XiaomiFactory implements FactoryMethod {
        @Override
        public Mobile createMobile() {
            return new Xiaomi();
        }
    }

    static class Mobile {
        protected void call() {
            System.out.println("mobile...");
        }
    }

    static class Huawei extends Mobile {
        @Override
        public void call() {
            System.out.println("huawei...");
        }
    }

    static class Xiaomi extends Mobile {
        @Override
        public void call() {
            System.out.println("xiaomi...");
        }
    }

    public static void main(String[] args) {
        final HuaweiFactory huaweiFactory = new HuaweiFactory();
        final Mobile mobile = huaweiFactory.createMobile();
        mobile.call();
    }
}

3.抽象工厂模式

3.1 概念

抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象。
通过使用抽象工厂及其产品接口来创建对象,从而将客户端与具体的产品实现解耦。

3.2 使用场景

适用:三层关系

产品品牌子品牌
手机华为手机mate60手机
手机小米手机红米手机

适用:两层关系

产品品牌
手机华为
电脑小米

3.3 模型图解:以两层模型做例子

角色::总工厂、小米工厂、华为工厂、小米手机、华为手机、小米路由器、华为路由器

3.4 伪代码

3.4.1 以品牌角度设计工厂


/**
 * descr: 以品牌角度设计工厂
 *
 * @date: 2024/1/24
 **/
public interface AbstractFactory {

    Phone createPhone();

    Computer createComputer();

    class HuaweiFactory implements AbstractFactory {
        @Override
        public Phone createPhone() {
            return new HuaweiPhone();
        }

        @Override
        public Computer createComputer() {
            return new HuaweiComputer();
        }
    }

    class XiaomiFactory implements AbstractFactory {

        @Override
        public Phone createPhone() {
            return new XiaomiPhone();
        }

        @Override
        public Computer createComputer() {
            return new XiaomiComputer();
        }

    }

    class HuaweiPhone implements Phone {
        @Override
        public void call() {
            System.out.println("huawei call...");
        }
    }

    class HuaweiComputer implements Computer {
        @Override
        public void play() {
            System.out.println("huawei play...");
        }
    }

    class XiaomiPhone implements Phone {
        @Override
        public void call() {
            System.out.println("xiaomi play...");
        }
    }

    class XiaomiComputer implements Computer {
        @Override
        public void play() {
            System.out.println("xiaomi play...");
        }
    }

    interface Phone {
        void call();
    }

    interface Computer {
        void play();
    }
}

3.5 实战:抽象工厂+策略模式

3.5.1 业务方法调用
/**
     * 根据业务类型计算真正需要动账的存欠类型
     *
     * @param materialInboundDO
     * @param walletTypeAndWeight
     * @return
     */
    private Map<String, BigDecimal> doBizType(MaterialInboundDO materialInboundDO, Map<String, BigDecimal> walletTypeAndWeight) {
        final AbstractFactory factory = AbstractFactory.getFactory(materialInboundDO.getBillType());
        final MaterialWalletHandler materialInboundBean = factory.getMaterialInboundOutboundBean(materialInboundDO.getBizType());
        return materialInboundBean.doBizType(walletTypeAndWeight);
    }
3.5.2 抽象工厂创建二级工厂,定义获取业务对象接口(二级工厂去创建具体的业务对象)
/**
 * 抽象工厂解决供应商/客户来料不同的业务类型对客户钱包的动账变化
 *
 * @date: 2023/7/18
 **/
public abstract class AbstractFactory {

    /**
     * 获得单据类型工厂
     *
     * @param billType 单据类型
     * @return
     */
    public static AbstractFactory getFactory(String billType) {
        if (BillTypeEnum.MATERIAL_CUSTOMER_IN.getKey().equals(billType)) {
            return new InboundCustomerFactory();
        } else if ( BillTypeEnum.MATERIAL_SUPPLIER_IN.getKey().equals(billType)) {
            return new InboundSupplierFactory();
        }  else if (BillTypeEnum.MATERIAL_CUSTOMER_OUT.getKey().equals(billType)) {
            return new OutboundCustomerFactory();
        }  else if (BillTypeEnum.MATERIAL_SUPPLIER_OUT.getKey().equals(billType)) {
            return new OutboundSupplierFactory();
        }
        throw new ServiceException("原料业务工厂不存在");
    }

    /**
     * 获得业务对象
     *
     * @param bizType 业务类型
     * @return
     */
    public abstract MaterialWalletHandler getMaterialInboundOutboundBean(String bizType);
}

3.5.3 二级工厂 获得对象
/**
 * descr 客户来料工厂
 *
 * @date: 2023/7/18
 **/
public class InboundCustomerFactory extends AbstractFactory {

    @Override
    public InboundCustomerHandler getMaterialInboundOutboundBean(String bizType) {
        if (BizTypeEnum.M_CUSTOMER_IN.getKey().equals(bizType)) {
            return new InboundCustomerIn();
        }
        throw new ServiceException("客户来料业务类型不存在");
    }
}
3.5.3 二级工厂 具体的业务对象
/**
 * descr 客户:客户来料
 *
 * @date: 2023/7/18
 **/
public class InboundCustomerIn implements InboundCustomerHandler {
    @Override
    public Map<String, BigDecimal> doBizType(Map<String, BigDecimal> walletTypeAndWeight) {
        return walletTypeAndWeight;
    }
}
3.5.3 处理的业务

顶层接口,如下子业务处理方式

/**
 * descr 来料/出料业务定义接口
 *
 * @date: 2023/7/18
 **/
public interface MaterialWalletHandler {

    Map<String, BigDecimal> doBizType(Map<String, BigDecimal> walletTypeAndWeight);

}

在这里插入图片描述

中间层子接口之一:用于规范业务

/**
 * descr 客户来料接口
 *
 * @date: 2023/7/18
 **/
public interface InboundCustomerHandler extends MaterialWalletHandler {

}

中间层接口实现1:用于处理业务

/**
 * descr 客户:客户来料
 *
 * @date: 2023/7/18
 **/
public class InboundCustomerIn implements InboundCustomerHandler {
    @Override
    public Map<String, BigDecimal> doBizType(Map<String, BigDecimal> walletTypeAndWeight) {
        return walletTypeAndWeight;
    }
}

中间层接口实现2:用于处理业务

/**
 * descr 供应商:发料兑料
 *
 * @date: 2023/7/18
 **/
public class OutboundSupplierMix implements OutboundSupplierHandler {
    @Override
    public Map<String, BigDecimal> doBizType(Map<String, BigDecimal> walletTypeAndWeight) {
        final HashMap<String, BigDecimal> walletTypeAndWeightMap = new HashMap<>(walletTypeAndWeight);
        walletTypeAndWeightMap.remove(WalletTypeEnum.CASH.getKey());
        return walletTypeAndWeightMap;
    }
}

补充:6大设计原则

1.单一职责
2.开放封闭
3.接口隔离
4.里氏替换
5.依赖倒置
6.迪米特法则

转送:java常用设计模式

3.6 总结:

  1. 以上实战中,代码没有写的很完美,还有许多改善的地方
  2. 抽象工厂在实际运用中比一般都例子都相对复杂;或可能写的理解的有所欠缺
  3. 抽象工厂定义了对象怎么创建;策略模式定义了业务怎么实现
  4. 设计模式的使用主要是对业务代码进行简化或抽象,尽量符合6大设计原则;在技术人员沟通中,只要说出某种设计模式,就能知道业务大概是怎么处理的,极大的减少了沟通成本

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

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

相关文章

动态库和静态库的理解 Linux

其实库文件里面的内容就是函数的实现方法&#xff0c;向我们包含的头文件其实就是函数的生命&#xff0c;而我们编译链接程序时会自动加载库文件&#xff0c;最终形成可执行程序。其实我们在编译链接时不仅仅会将文件的库文件加载进来&#xff0c;其实头文件也是需要加载进来的…

工作进入第八年,还在成长的一年

这一年没有写太多的技术博客&#xff0c;是因为工作内容发生了较大的改变&#xff0c;岗位也发生了调整。随着ChatGPT的爆火&#xff0c;无论从公司的领导层&#xff0c;还是从现场的用户&#xff0c;人工智能算是被彻底颠覆了&#xff0c;每个人对生成式人工智能的期待太高&am…

架构篇24:排除架构可用性隐患的利器-FMEA方法

文章目录 FMEA 介绍FMEA 方法FMEA 实战小结 前面的专栏分析高可用复杂度的时候提出了一个问题&#xff1a;高可用和高性能哪个更复杂&#xff0c;根据墨菲定律“可能出错的事情最终都会出错”&#xff0c;架构隐患总有一天会导致系统故障。因此&#xff0c;我们在进行架构设计的…

Intel Atom + Artix-7 100T FPGA,CompactRIO单板控制器

模拟和数字I/O&#xff0c;RMC&#xff0c;DisplayPort&#xff0c;1.33 GHz双核CPU&#xff0c;1 GB DRAM&#xff0c;4 GB存储容量&#xff0c;Artix-7 100T FPGA&#xff0c;CompactRIO单板控制器 CompactRIO控制器是搭载了实时处理器和用户可编程FPGA的嵌入式控制器。其产…

低代码(Low-Code)技术简化开发难度,快速搭建应用

目录 一、低代码技术定义 二、低代码技术优势 1.提高企业的工作效率 2.降低企业的开发成本 3.提高应用程序和业务流程的质量 三、稳定性和生产率的最佳实践 三、最后 随着数字化时代的到来&#xff0c;低代码&#xff08;Low-Code&#xff09;技术已经成为了企业数字化转…

如何使用Docker本地部署Jupyter Notebook并结合内网穿透实现远程访问

&#x1f4d1;前言 本文主要是Linux下通过使用Docker本地部署Jupyter Notebook并结合内网穿透实现远程访问的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;…

别不信❗️你离数据专家只差一个CDMP证书

1⃣️为什么选择CDMP证书&#xff1f; &#x1f31f;&#x1f31f;亲爱的朋友们&#xff0c;如果你在寻找一个能让你在数据管理领域大展拳脚的证书&#xff0c;那么CDMP&#xff08;Certified Data Management Professional&#xff09;证书就是你的不二之选&#xff01;&#…

JavaScript进阶:WebAPIs重点知识整理2

目录 1 对节点的相关操作 1.1 查找节点 1.1.1 查找节点的父节点 1.1.2 查找节点的子节点 1.1.3 查找节点的兄弟节点 1.2 新增节点&#xff08;先创建&#xff0c;后追加&#xff09; 1.3 克隆节点 1.4 删除节点 2 M 端&#xff08;移动端&#xff09;事件 3 JS清空表…

hadoop集群规划部署

一、集群规划 三台硬件资源&#xff0c;部署hadoop版本&#xff0c;hadoop-3.3.5 &#xff0c;部署后配置文件。 Hadoop配置文件分两类&#xff1a;默认配置文件和自定义配置文件。 hadoop102hadoop103hadoop104HDFS NameNode DataNode DataNode SecondaryNameNode DataN…

深度强化学习Task3:A2C、A3C算法

本篇博客是本人参加Datawhale组队学习第三次任务的笔记 【教程地址】 文章目录 Actor-Critic 算法提出的动机Q Actor-Critic 算法A2C 与 A3C 算法广义优势估计A3C实现建立Actor和Critic网络定义智能体定义环境训练利用JoyRL实现多进程 练习总结 Actor-Critic 算法提出的动机 蒙…

Matlab|基于改进遗传算法的储能选址定容(可任意设定储能数量)

目录 主要内容 部分代码 结果一览&#xff08;以3个储能为例&#xff09; 下载链接 主要内容 该模型采用改进遗传算法优化配电网系统中储能选址位置和容量&#xff0c;程序以IEEE33节点系统为分析对象&#xff0c;以网损最小为目标&#xff0c;采用matpower实现系…

谷粒商城-微服务架构图

整体架构 分布式划分图

蓝牙运动耳机什么牌子的好?蓝牙运动耳机品牌排行榜前十名

​运动耳机是耳机中使用场景最广泛的一类&#xff0c;特别适合户外运动、健身和骑行等场景。在众多运动耳机中&#xff0c;哪一款更值得入手呢&#xff1f;今天我将向大家推荐几款相当不错的运动耳机&#xff0c;它们不仅音质上乘&#xff0c;还能满足不同运动场景的需求。 1.…

ozon促销活动100+店铺如何多店铺批量加入活动产品?ozon促销产品怎么删除?

很多Ozon卖家为实现店铺引流&#xff0c;会参与许多官方促销活动&#xff0c;如果每个活动都需要单独管理&#xff0c;会消耗不少的时间成本&#xff0c;操作起来也会非常困难。 尤其是随着运营店铺数量的增加&#xff0c;多个店铺多个促销活动来回切换管理&#xff0c;不仅耗…

modbus poll测试工具测试modbus tcp与PLC设备连接使用方法

socket默认端口是502&#xff0c;socket连上之后&#xff0c; 按照modbuspoll工具设置的读写参数 生成的RTU命令格式去组装读PLC的设备数据 modbuspoll工具配置&#xff0c;以v9.9.2中文破解版为例&#xff1a; 首先点连接菜单&#xff08;connection&#xff09;建立连接&…

Database history tablesupgraded

zabbix升级到6之后&#xff0c;配置安装完成会有一个红色输出&#xff0c;但是不影响zabbix使用&#xff0c;出于强迫症&#xff0c;找到了该问题的解决方法。 Database history tables upgraded: No. Support for the old numeric type is deprecated. Please upgrade to nume…

C++:优先队列-Priority_queue

目录 1.关于优先队列 2.priority_queue的使用 1.构造方法 2.empty();判空 3.size(); 4.top(); 5.push(val); 6.pop(); 3.优先队列模拟实现 4.用优先队列解决数组中第K个大的元素 1.关于优先队列 在C中&#xff0c;可以使用STL&#xff08;标准模板库&#xff09;中的p…

【第十五课】数据结构:堆 (“堆”的介绍+主要操作 / acwing-838堆排序 / 时间复杂度的分析 / c++代码 )

目录 关于堆的一些知识的回顾 数据结构&#xff1a;堆的特点 "down" 和 "up"&#xff1a;维护堆的性质 down up 数据结构&#xff1a;堆的主要操作 acwing-838堆排序 代码如下 时间复杂度分析 确实是在写的过程中频繁回顾了很多关于树的知识&…

C++基础语法和用法

文章目录 1.hello world2.引入namespace(命名空间/域问题)3.输入输出4.缺省参数/默认参数5.函数重载6.引用7.内联函数8.auto关键字&#xff0c;基于范围的for循环&#xff0c;空指针NULL8.1 auto8.2 基于范围的for循环8.3 nullptr 1.hello world #include <iostream> us…

diffusion入门

1. diffusion model 概念 https://zhuanlan.zhihu.com/p/638442430 这篇博客写得很好&#xff0c;顺便做一点笔记记录一下。 原博客附带的代码也很清晰易懂。 1.1 前向过程 后一个过程等于前一个结果的均值乘上sqrt(1-beta_t), 再加上方差beta_t的噪声。 这样下去可以得到 x…