java抽象工厂实战与总结

文章目录

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

一、工厂模式(三种)

1.简单工厂模式

1.1 概念:

通过一个工厂类来创建对象,根据不同的参数或条件返回相应的对象实例。

隐藏了对象的创建细节,客户端只需通过工厂类获取对象而不需要直接实例化对象。

1.2 使用场景

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

1.3 模型图解:

角色:手机总工厂、参数、手机、小米手机、华为手机

后续补充:

1.4 伪代码:

java 复制代码
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 伪代码

java 复制代码
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 以品牌角度设计工厂

java 复制代码
/**
 * 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 业务方法调用
java 复制代码
/**
     * 根据业务类型计算真正需要动账的存欠类型
     *
     * @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 抽象工厂创建二级工厂,定义获取业务对象接口(二级工厂去创建具体的业务对象)
java 复制代码
/**
 * 抽象工厂解决供应商/客户来料不同的业务类型对客户钱包的动账变化
 *
 * @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 二级工厂 获得对象
java 复制代码
/**
 * 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 二级工厂 具体的业务对象
java 复制代码
/**
 * 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 处理的业务

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

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

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

}

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

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

}

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

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

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

java 复制代码
/**
 * 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大设计原则;在技术人员沟通中,只要说出某种设计模式,就能知道业务大概是怎么处理的,极大的减少了沟通成本
相关推荐
float_六七3 小时前
IntelliJ IDEA双击Ctrl的妙用
java·ide·intellij-idea
能摆一天是一天4 小时前
JAVA stream().flatMap()
java·windows
颜如玉5 小时前
🤲🏻🤲🏻🤲🏻临时重定向一定要能重定向🤲🏻🤲🏻🤲🏻
java·http·源码
程序员的世界你不懂6 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
星空寻流年6 小时前
设计模式第一章(建造者模式)
java·设计模式·建造者模式
gb42152877 小时前
java中将租户ID包装为JSQLParser的StringValue表达式对象,JSQLParser指的是?
java·开发语言·python
曾经的三心草7 小时前
Python2-工具安装使用-anaconda-jupyter-PyCharm-Matplotlib
android·java·服务器
蒋星熠7 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
Metaphor6928 小时前
Java 高效处理 Word 文档:查找并替换文本的全面指南
java·经验分享·word
ChinaRainbowSea8 小时前
7. LangChain4j + 记忆缓存详细说明
java·数据库·redis·后端·缓存·langchain·ai编程