让代码变美的第四天 - 工厂方法模式

Cadence学习之路(六)元器件封装绘制 使用Allegro PCB Designer绘制元器件封装 阅读详情

话接上回【让代码变美的第三天 - 简单工厂模式】
简单工厂其实还是不够完美,破坏了程序的开放封闭,那么看下工厂方法模式如何解决

丑陋的模样

简单工厂代码

    public static Fruit getFruit(String name) {
        if ("苹果".equals(name)) {
            Apple apple = new Apple();
            // 洗苹果 + 切苹果
            // todo other init
            return apple;
        } else if ("菠萝".equals(name)) {
            Pineapple pineapple = new Pineapple();
            // 切菠萝
            // todo other init
            return pineapple;
        } else {
            throw new RuntimeException("没有找到该水果");
        }
    }

重构

抽象工厂

public interface FruitFacory {
    Fruit getFruit();
}

定义具体工厂

public class AppleFacory implements FruitFacory {
    @Override
    public Fruit getFruit() {
        Apple apple = new Apple();
        // 洗苹果 + 切苹果
        // todo other init
        return apple;
    }
}
public class PineappleFacory implements FruitFacory {
    @Override
    public Fruit getFruit() {
        Pineapple pineapple = new Pineapple();
        // 切菠萝
        // todo other init
        return pineapple;
    }
}

使用

    public void sendApple() {
        AppleFacory appleFacory = new AppleFacory();
        Fruit apple = appleFacory.getFruit();
//        Fruit apple = FruitFacory.getFruit("苹果");
        sendPeople(apple);
    }

    public void eatApple() {
        AppleFacory appleFacory = new AppleFacory();
        Fruit apple = appleFacory.getFruit();
//        Fruit apple = FruitFacory.getFruit("苹果");
        eatPeople(apple);
    }

    public void eatPineapple() {
        AppleFacory appleFacory = new AppleFacory();
        Fruit pineapple = appleFacory.getFruit();
//        Fruit pineapple = FruitFacory.getFruit("菠萝");
        eat(apple);
    }

注释掉的是简单工厂的获取方式,可以简单进行对比,工厂方法模式无非就是对每个产品包装了一层,这一层就是具体的工厂
UML图(网上借用的)如下:
网上借用的图

新问题

每次获取产品的时候,都要精确知道是哪个工厂生产的,不管要记住产品的名字,还要记住工厂的名字,这不是给工作增加负担么?
有没有一种办法,使得客户不用关心具体是哪个工厂生产的呢?就和简单工厂模式一样简单呢?

再次重构

只讨论JAVA场景,Spring项目,利用Spring优雅的解决上面的问题。
其实在【让代码变美的第一天 - 观察者模式】中也是使用类似这种办法。
重新定义产品名(简单工厂中使用的产品名)

public interface FruitFacory {
    String getFruitName();

    Fruit getFruit();
}
@Component
public class AppleFacory implements FruitFacory {
    @Override
    public Fruit getFruit() {
        Apple apple = new Apple();
        // 洗苹果 + 切苹果
        // todo other init
        return apple;
    }

    @Override
    public String getFruitName() {
        return "苹果";
    }
}
@Component
public class PineappleFacory implements FruitFacory {
    @Override
    public Fruit getFruit() {
        Pineapple pineapple = new Pineapple();
        // 切菠萝
        // todo other init
        return pineapple;
    }

    @Override
    public String getFruitName() {
        return "菠萝";
    }
}
  • 产品名也可以使用【让代码变美的第一天 - 观察者模式】中的注解来实现,注解或许x格高一点。

构建产品名和工厂的映射关系

@Service
public class FruitService {
    public static Map<String, FruitFacory> fruitFactoryMap = new HashMap<>();

    @Autowired
    private List<FruitFacory> fruitFactoryList;

    @PostConstruct
    private void init() {
        for (FruitFacory fruitFacory : fruitFactoryList) {
            fruitFactoryMap.put(fruitFacory.getFruitName(), fruitFacory);
        }
    }

    public static Fruit getFruit(String fruitName) {
        return fruitFactoryMap.get(fruitName).getFruit();
    }
}

使用

    public void sendApple() {
        Fruit apple = FruitService.getFruit("苹果");
//        AppleFacory appleFacory = new AppleFacory();
//        Fruit apple = appleFacory.getFruit();
//        Fruit apple = FruitFacory.getFruit("苹果");
//        sendPeople(apple);
    }

    public void eatApple() {
        Fruit apple = FruitService.getFruit("苹果");
//        AppleFacory appleFacory = new AppleFacory();
//        Fruit apple = appleFacory.getFruit();
//        Fruit apple = FruitFacory.getFruit("苹果");
//        eatPeople(apple);
    }

看这里是不是又和简单工厂模式差不多了,外部不用关心产品内部细节,也不需要关心需要用哪个工厂,只要通过名称获取到产品即可
再来看有没有破坏开放封闭原则,我们新增一个产品,比如:香蕉。

  • 只需要新增Banana(产品)、BananaFacory(工厂)。

Spring帮我们解决的是扫描所有工厂类(当然我们自己利用反射也能做),让我们无需在新增工厂的时候去加if else

用python将dycom .dcm格式图像转换为nifti .nii 因为发现目前搜索到的多数中文教程并不能正确将FMRI图像正确转换,例如很多用simpleITk的seriesreader的,所以写了一下自己正确转换的方法。因为FMRI是一个4D数据,有时间轴,所以用seriesreader读写出来的图像把时间轴维度给降维了。当然你用SPM12工具的dycom import也是能正确转换的,但是我还是喜欢python这样的,代码直接简单。 阅读详情

相关推荐

LabVIEW调用.so文件的方法

LabVIEW调用.so文件的方法

m0_37878912的博客 3023

让代码变美的第三天 - 简单工厂模式

日常重构代码

帅东's Blog 6万+

从零实现地震波场模拟:交错网格有限差分法核心代码精讲

本文详细介绍了从零实现地震波场模拟的核心技术,重点讲解了交错网格有限差分法的实现过程。通过速度-应力弹性波方程的离散化处理,结合代码实例演示了应力与速度更新的关键步骤,并分享了震源加载、稳定性条件等实用技巧,为计算地球物理学研究提供实践指导。

weixin_42556197的博客 410

13、设计模式应用举例:工厂方法模式:创建药品对象

本文基于工厂方法模式设计药店药品系统,定义抽象产品Drug及具体子类Paracetamol、Amorolfine,通过DrugCreator接口与具体创建者ParaDrugCreator、AmorDrugCreator实现对象的延迟创建。药店应用仅调用工厂方法获取药品实例,避免直接调用构造函数,确保成分信息由药厂提供,符合开闭原则,提升系统可扩展性与职责分离。

博风_刺耳的博客(网络记事本) 267

httprunner V4.3.5 安装与使用--快速上手(超详细-超长篇)

HttpRunner是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。继承 Requests 的全部特性,轻松实现 HTTP(S) 的各种测试需求测试用例与代码分离,采用YAML/JSON的形式描述测试场景,保障测试用例具备可维护性测试用例支持分层机制,充分实现测试用例的复用测试用例支持参数化和数据驱动机制使用 skip 机制实现对测试用例的分组执行控制。

Dreams°的博客 3892

iOS WKWebView H5微信支付跳转

iOS WKWebView H5微信支付跳转 需求:iOS客户端实现嵌入H5进行微信支付跳转到微信客户端,支付完成后再跳转回我们的APP,解决WKWebView无法跳转回APP的BUG. 阅读前提: 了解WKWebView基本初始化及使用 了解如何利用URL Schemes进行应用间跳转 公司或个人已经在微信后台注册了一级域名 GitHub地址(附代码) :iOS WKWebView H5微信支付跳转 简书地址 :iOS WKWebView H5微信支付跳转 博客地址 :iOS WKWe...

ForeverMyheart的博客 2046

【FDE知识库】(1):AI 编程时代开发语言选型分析,云使用go,企业用java,算法python,底层c

AI 编程时代,开发语言选型需综合考量AI适配度、编译速度、跨平台与学习成本。Python以海量语料和即时执行成首选,适用于AI/ML与原型开发;TypeScript凭借类型系统与秒级构建,成为前端及应用层主流;Go以极速编译与统一风格,契合AI代理高效迭代需求。Rust/C++虽性能强,但编译慢、学习成本高,不适于快速试错。综合推荐:优先选Python、TypeScript、Go,兼顾效率与生态,实现最优AI协作体验。

freewebsys的专栏 507

【TensorRT】TensorRT C# API 项目介绍:基于C#与TensorRT部署深度学习模型(上篇)

开发了TensorRT C# API 2.0版本,该版本在开发时充分考虑了上一版本应用时出现的问题,并进行了改进。同时在本版本中,我们对接口进行了优化,使用起来更加简单,并同时提供了相关的应用案例,方便开发者进行使用。

grape_yan的博客 3038

Spring AI + GPT-5.5 + Ollama 配置教程:Base URL、超时与流式调用

由于不同 Spring AI、Spring Boot 小版本之间仍可能存在差异,创建项目时应检查 Spring Initializr、Spring AI BOM 和官方兼容矩阵,不要直接复制旧教程中的 Starter 名称和版本号。多人项目最好隔离不同客户端,并在脱敏前提下记录最终 URL、状态码、请求耗时、请求 ID 和模型 ID。Spring AI 接入模型 API,至少要同时确认 Starter、Base URL、请求路径、API Key、模型 ID、连接超时、读取超时和流式客户端这 8 项。

2601_95893075的博客 225

AI上推荐 之 NeuralCF与PNN模型(改变特征交叉方式)

1. 前言 随着信息技术和互联网的发展, 我们已经步入了一个信息过载的时代,这个时代,无论是信息消费者还是信息生产者都遇到了很大的挑战: 信息消费者:如何从大量的信息中找到自己感兴趣的信息? 信息生产者:如何让自己生产的信息脱颖而出, 受到广大用户的关注? 为了解决这个矛盾, 推荐系统应时而生, 并飞速前进,在用户和信息之间架起了一道桥梁,一方面帮助用户发现对自己有价值的信息, 一方面让信息能够展现在对它感兴趣的用户前面。 推荐系统近几年有了深度学习的助推发展之势迅猛, 从前深度学习的传统推荐模型(协

Miracle8070 1万+

深度解析电力负荷预测:基于深度学习的完整实战指南

电力负荷预测是智能电网运行中的核心技术之一,准确的负荷预测对于电网的稳定运行、电力市场交易以及能源调度具有重要意义。本文将详细介绍电力负荷预测的完整解决方案,从数据预处理、特征工程到模型构建与评估,提供完整的可执行代码。我们将使用LSTM(长短期记忆网络)和Transformer两种主流深度学习模型进行实现,并通过实际数据集验证模型效果。电力负荷预测是指根据历史负荷数据、气象因素、时间特征等多维信息,预测未来某一时段的电力需求。超短期负荷预测:未来几分钟到几小时短期负荷预测:未来1天到1周中期负荷预测。

YOLO 111

【JVM】对象内存布局

HotSpot JVM 中,Java 对象内存布局由对象头(12字节,含Mark Word与压缩Klass Pointer)、实例数据及对齐填充构成,总大小为8字节倍数。对象头支持锁状态动态复用,指针压缩使引用仅4字节,但堆超32GB时失效。实例字段按类型优先级重排序以减少间隙,最小对象大小为16字节。通过JOL工具可精准验证布局,理解锁机制、GC、伪共享等底层行为。

2301_79732484的博客 149

【蓝桥杯单片机组第八届省赛】— 基于单片机的电子钟程序设计与调试

1、初赛试题 1.1 基本要求 (1)使用 CT107D 单片机竞赛板, 完成“电子钟” 功能的程序设计与调试; (2)设计与调试过程中,可参考组委会提供的“资源数据包”; (3)Keil 工程文件以准考证号命名, 完成设计后, 提交完整、 可编译的 Keil工程文件到服务器。 1.2 硬件框图 1.3功能描述 1.3.1 初始化 (1)关闭蜂鸣器、继电器等无关外...

Fanjufei的博客 3661

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 330

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 196

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 117

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

LeetCode Hot 100 二叉树专题(二)3 题(Java)

本篇文章共 3 题:543. 二叉树的直径、102. 二叉树的层序遍历、108. 将有序数组转换为二叉搜索树。 每道题都统一按「① 题目分析 & 解题思路 → ② 常见解法(附代码)及讲解 → ③ 知识点总结」的顺序组织;代码使用 Java 编写,节点定义沿用 LeetCode 默认的 TreeNode。

2401_88612756的博客 365

Decorator

TaskDecorator 是异步场景下"跨线程传递上下文"的标准方案,主要用于传递 MDC、用户信息、数据源路由等上下文数据,核心价值是让异步任务的日志链路不中断、业务上下文不丢失。TaskDecorator 是 Spring 提供的一个钩子接口,用于在异步任务执行前对 Runnable 进行包装,常用于跨线程传递上下文。如果你在项目中遇到具体的异步上下文传递问题,可以把代码贴出来,我帮你给出最合适的 Decorator 方案 👍。✅ 核心能力:在线程切换时,把"父线程的上下文"搬到"子线程"

wlwork66的博客 104

JDK 下载安装:装完 Java 提示「不是内部或外部命令」?环境变量没配

JDK 是写 Java 程序必须装的东西。它包含运行 Java 的虚拟机(JRE)和编译 Java 的编译器(javac)——装了它,能跑、.java文件能编译成可执行程序。免费,学习和小规模生产都不花钱。

科小怪的博客 626

数据库乐观锁深度解析:MySQL、PostgreSQL 实战 + Spring Boot 集成指南

Oracle 提供了ORA_ROWSCN伪列(System Change Number),记录最后修改行的 SCN,类似 PostgreSQL 的xmin。实践中通常仍使用 version 字段方案,逻辑与 MySQL 完全相同。-- Oracle:通过 ORA_ROWSCN 实现乐观锁-- 更新时比对 SCN// 自定义注解// AOP 切面@Aspect@Component@Slf4jtry {

yjc_1111的专栏 399

C++ 多态详解:作用、原理与实战用法

多态是C++面向对象的核心特性,通过虚函数实现运行期动态绑定,使同一接口在不同对象上表现出不同行为。其核心作用包括统一接口、提升可扩展性、降低耦合、支持运行时分派与批量处理。实现依赖虚函数表(vtable)和虚指针(vptr),需注意虚析构函数、对象切片等陷阱。相比编译期多态(模板),运行期多态灵活性高但有调用开销。合理结合两者,可兼顾代码的灵活性与性能,是构建可扩展、低耦合系统的关键。

2402_85743155的博客 377

java框架大全

java框架大全

qq_39326137的博客 183

Java 多态 学习笔记

多态是面向对象编程的重要特性,指同一操作作用于不同对象时产生不同行为。其核心在于“父类引用指向子类对象”,结合方法重写实现运行时动态绑定。多态使代码更灵活、可扩展,如用Person p = new Student();统一处理各类人员注册,无需修改调用逻辑。但多态无法直接调用子类特有方法,需通过instanceof判断并强制转换。编译时看左边(类型),运行时看右边(实际对象),实现解耦与维护便利。

AA_AA114514的博客 354

SecureRandom做随机源,这个Java随机字符串工具类有3个方法

本文分享一款JDK17环境下的Java随机字符串工具类,内置3个开箱即用的方法,全部采用SecureRandom加密安全随机源,不存在弱随机、可预测、取模偏差等问题。工具类支持默认62字符集随机串、纯数字随机串、自定义字符集随机串三种生成模式,支持Unicode码点级别的字符集处理,兼容Emoji等增补字符,边界处理严格,异常信息明确,适合验证码、邀请码、盐值、随机口令、短链码等场景,源码可直接复制使用。

Java后端 | AI智能体应用实战派 | 电脑技能行家 295

Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

【代码】Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

m0_64476639的博客 319

ubuntu安装hadoop系统

本文详细介绍了基于VMware克隆虚拟机搭建三节点Hadoop分布式集群的全过程:使用同一Ubuntu镜像克隆出master、worker1、worker2三台虚拟机,依次配置主机名、固定IP(如192.168.82.10/11/12)、SSH服务及免密登录,确保节点间网络互通。随后安装Java,下载配置Hadoop并分发至各节点,最终初始化启动集群,验证其存储与计算功能,实现高效的大数据环境部署。

qq_43592674的博客 325
上一篇: 让代码变美的第三天 - 简单工厂模式
下一篇: ES如何提高召回率之【词干提取】
帅东
博客等级 码龄11年 676粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值