Java 23 种设计模式从踩坑到精通 | 番外工厂方法模式 —— 物流处理器创建实战摘要工厂方法模式定义创建对象的接口让子类决定实例化哪一个类将对象的实例化延迟到子类中进行。本文结合智能物流中“不同物流方式空运/陆运创建对应的物流处理器”的场景完整展示工厂方法的实现并与简单工厂、抽象工厂深度对比帮你掌握“子类决定创建”的设计精髓。《Java 23 种设计模式从踩坑到精通》开篇系列介绍与目录 正篇工厂方法 Factory —— 还在写一坨 if-else 创建对象吗 当前番外 · 工厂方法模式 × 物流处理器创建 返回系列总目录1. 物流处理器创建的痛点物流平台支持多种运输方式——空运、陆运、海运等。每种运输方式都有独立的处理流程、费用计算规则和时效要求。如果在一个方法里根据运输类型if-else创建处理器并执行逻辑代码会迅速膨胀且难以扩展。更麻烦的是新增一种运输方式如铁路运输需要修改所有相关判断。工厂方法模式的解决思路为每种运输方式创建独立的工厂类客户端通过抽象工厂接口获取处理器新增运输方式只需新增对应的处理器和工厂类无需修改现有代码。2. 工厂方法 UML物流处理器场景3. 完整源码实现3.1 抽象产品物流处理器接口/** * 抽象产品物流处理器接口 * 定义所有物流处理器的通用行为 */publicinterfaceLogisticsHandler{voidprocess();StringgetHandlerInfo();doublecalculateCost(doubleweight);}白话所有物流处理器都必须能走流程、报信息、算运费。3.2 具体产品A空运处理器/** * 具体产品A空运物流处理器 */publicclassAirLogisticsHandlerimplementsLogisticsHandler{Overridepublicvoidprocess(){System.out.println(✈️ 空运物流处理流程启动...);System.out.println( → 1. 货物安检航空标准);System.out.println( → 2. 打板装箱);System.out.println( → 3. 报关/清关);System.out.println( → 4. 装机起飞);System.out.println( → 5. 目的地卸货派送);}OverridepublicStringgetHandlerInfo(){return空运物流处理器 [时效1-3天适合急件/高价值货物];}OverridepublicdoublecalculateCost(doubleweight){if(weight1)return50.0;return50.0(weight-1)*30.0;}}白话空运流程多了安检和报关步骤计费也更贵——首重 50 元续重每 kg 30 元。3.3 具体产品B陆运处理器/** * 具体产品B陆运物流处理器 */publicclassGroundLogisticsHandlerimplementsLogisticsHandler{Overridepublicvoidprocess(){System.out.println( 陆运物流处理流程启动...);System.out.println( → 1. 货物揽收);System.out.println( → 2. 分拣中心分拨);System.out.println( → 3. 干线运输高速/铁路);System.out.println( → 4. 目的地网点派送);}OverridepublicStringgetHandlerInfo(){return陆运物流处理器 [时效3-7天适合普通货物/大件];}OverridepublicdoublecalculateCost(doubleweight){if(weight1)return12.0;return12.0(weight-1)*5.0;}}白话陆运流程更简单计费也更便宜——首重 12 元续重每 kg 5 元。3.4 抽象工厂物流处理器工厂接口/** * 抽象工厂物流处理器工厂接口 */publicinterfaceLogisticsHandlerFactory{LogisticsHandlercreateHandler();}白话每个工厂只负责创建一种处理器这是工厂方法的核心——工厂接口只有一个方法。3.5 具体工厂A空运处理器工厂/** * 具体工厂A空运处理器工厂 */publicclassAirLogisticsHandlerFactoryimplementsLogisticsHandlerFactory{OverridepublicLogisticsHandlercreateHandler(){System.out.println([工厂] 创建空运物流处理器...);returnnewAirLogisticsHandler();}}3.6 具体工厂B陆运处理器工厂/** * 具体工厂B陆运处理器工厂 */publicclassGroundLogisticsHandlerFactoryimplementsLogisticsHandlerFactory{OverridepublicLogisticsHandlercreateHandler(){System.out.println([工厂] 创建陆运物流处理器...);returnnewGroundLogisticsHandler();}}3.7 客户端物流系统/** * 客户端物流系统 * 只依赖抽象工厂和抽象产品 */publicclassLogisticsClient{publicvoidshipOrder(StringtransportType,doubleweight){System.out.println(\n═.repeat(60));System.out.println(【物流订单】运输方式transportType重量weightkg);System.out.println(═.repeat(60));// 根据运输方式选择对应的工厂LogisticsHandlerFactoryfactory;if(air.equalsIgnoreCase(transportType)){factorynewAirLogisticsHandlerFactory();}else{factorynewGroundLogisticsHandlerFactory();}// 通过工厂方法创建处理器客户端不直接new具体产品LogisticsHandlerhandlerfactory.createHandler();System.out.println(\n--- 处理器信息 ---);System.out.println(handler.getHandlerInfo());System.out.println(--- 运费计算 ---);System.out.printf(运费%.2f 元\n,handler.calculateCost(weight));System.out.println(--- 处理流程 ---);handler.process();}publicstaticvoidmain(String[]args){System.out.println( 工厂方法模式智能物流处理器创建 );LogisticsClientclientnewLogisticsClient();client.shipOrder(air,10.5);client.shipOrder(ground,10.5);}}白话客户端虽然仍需if-else选择工厂实际项目中通常配合简单工厂 配置来解决但不直接new具体产品。新增运输方式只需新增处理器和工厂客户端的选择逻辑可以集中到配置中。4. 运行结果 工厂方法模式智能物流处理器创建 ════════════════════════════════════════════════════════════ 【物流订单】运输方式air重量10.5kg ════════════════════════════════════════════════════════════ [工厂] 创建空运物流处理器... --- 处理器信息 --- 空运物流处理器 [时效1-3天适合急件/高价值货物] --- 运费计算 --- 运费335.00 元 --- 处理流程 --- ✈️ 空运物流处理流程启动... → 1. 货物安检航空标准 → 2. 打板装箱 → 3. 报关/清关 → 4. 装机起飞 → 5. 目的地卸货派送 ════════════════════════════════════════════════════════════ 【物流订单】运输方式ground重量10.5kg ════════════════════════════════════════════════════════════ [工厂] 创建陆运物流处理器... --- 处理器信息 --- 陆运物流处理器 [时效3-7天适合普通货物/大件] --- 运费计算 --- 运费59.50 元 --- 处理流程 --- 陆运物流处理流程启动... → 1. 货物揽收 → 2. 分拣中心分拨 → 3. 干线运输高速/铁路 → 4. 目的地网点派送5. 核心角色回顾角色职责对应代码Product定义产品的抽象接口LogisticsHandlerConcreteProduct实现具体产品AirLogisticsHandler/GroundLogisticsHandlerFactory声明工厂方法LogisticsHandlerFactoryConcreteFactory实现工厂方法创建具体产品AirLogisticsHandlerFactory/GroundLogisticsHandlerFactoryClient依赖抽象工厂获取产品LogisticsClient6. 工厂方法 vs 简单工厂 vs 抽象工厂对比项简单工厂工厂方法抽象工厂工厂结构一个具体工厂类抽象工厂接口 多个子类抽象工厂接口 多个子类创建方式静态方法通过参数判断子类重写工厂方法子类重写多个工厂方法产品数量多种产品一种产品一组产品产品族扩展性新增产品需修改工厂违反OCP新增产品只需新增工厂子类符合OCP新增产品族符合OCP新增产品类型违反OCPGoF 收录否是是7. 工厂方法的“坑”与优化问题解决方案类爆炸每产品一工厂产品种类很少时用简单工厂种类多且变化频繁时用工厂方法客户端仍需知道具体工厂类配合简单工厂 配置文件将工厂选择集中管理不适合产品间有强关联的场景升级为抽象工厂8. 六大设计原则体现原则体现单一职责工厂只负责创建处理器只负责业务开闭原则新增运输方式无需修改现有代码里氏替换所有处理器可替换LogisticsHandler接口依赖倒置客户端依赖LogisticsHandlerFactory和LogisticsHandler抽象接口隔离工厂接口只有一个createHandler()方法迪米特法则客户端只与抽象工厂和抽象产品交互附 工厂方法 UML源码物流处理器场景startuml title Java 23 种设计模式从踩坑到精通 footer 折哥 | 智能物流与Java实战 1. 全局样式配置 skinparam backgroundColor #FEFEFE skinparam shadowing false skinparam classBorderColor #333333 skinparam classFontColor #1A1A1A skinparam classFontSize 14 skinparam noteFontSize 12 skinparam noteFontColor #555555 skinparam arrowColor #555555 skinparam classBackgroundColor #F9F9F9 2. 抽象产品物流处理器 interface LogisticsHandler { void process() String getHandlerInfo() double calculateCost(double weight) } note right of LogisticsHandler b抽象产品Product/b -- 物流处理器接口定义所有物流方式 的通用处理行为 end note 3. 具体产品A空运处理器 class AirLogisticsHandler implements LogisticsHandler { void process() String getHandlerInfo() double calculateCost(double weight) } note right of AirLogisticsHandler b具体产品AConcreteProductA/b -- 空运物流处理器处理航空运输的 全流程业务逻辑 end note 4. 具体产品B陆运处理器 class GroundLogisticsHandler implements LogisticsHandler { void process() String getHandlerInfo() double calculateCost(double weight) } note right of GroundLogisticsHandler b具体产品BConcreteProductB/b -- 陆运物流处理器处理公路/铁路 运输的全流程业务逻辑 end note 5. 抽象工厂物流处理器工厂 interface LogisticsHandlerFactory { LogisticsHandler createHandler() } note right of LogisticsHandlerFactory b抽象工厂Factory/b -- 声明创建物流处理器的工厂方法 由子类决定具体创建哪个处理器 end note 6. 具体工厂A空运处理器工厂 class AirLogisticsHandlerFactory implements LogisticsHandlerFactory { LogisticsHandler createHandler() } note right of AirLogisticsHandlerFactory b具体工厂AConcreteFactoryA/b -- 负责创建空运处理器实例 客户端无需知道具体产品类 end note 7. 具体工厂B陆运处理器工厂 class GroundLogisticsHandlerFactory implements LogisticsHandlerFactory { LogisticsHandler createHandler() } note right of GroundLogisticsHandlerFactory b具体工厂BConcreteFactoryB/b -- 负责创建陆运处理器实例 客户端无需知道具体产品类 end note 8. 客户端 class LogisticsClient { void shipOrder(String transportType, double weight) } note right of LogisticsClient b客户端Client/b -- 只依赖抽象工厂和抽象产品 通过工厂方法获取处理器实例 end note 9. 关系连线 LogisticsHandler |.. AirLogisticsHandler : 实现 LogisticsHandler |.. GroundLogisticsHandler : 实现 LogisticsHandlerFactory |.. AirLogisticsHandlerFactory : 实现 LogisticsHandlerFactory |.. GroundLogisticsHandlerFactory : 实现 AirLogisticsHandlerFactory .. AirLogisticsHandler : 创建 GroundLogisticsHandlerFactory .. GroundLogisticsHandler : 创建 LogisticsClient .. LogisticsHandlerFactory : 使用 LogisticsClient .. LogisticsHandler : 调用 enduml 《Java 23 种设计模式从踩坑到精通》快速导航开篇系列介绍与目录正篇工厂方法 Factory —— 还在写一坨 if-else 创建对象吗当前番外 · 工厂方法模式 × 物流处理器创建你在这里创建型模式汇总结构型模式汇总行为型模式汇总 关注《Java 23 种设计模式从踩坑到精通》用 25 篇文章彻底吃透设计模式。福利预告全系列代码及 UML 源码将在完结时统一打包开放点击「关注」「收藏」第一时间获取。 除了设计模式我也在深挖智能物流实战WMS、托盘调度、机器学习落地。欢迎点击头像看看专栏 《出版社物流WMS智能调度实战》、《电商多平台电子面单对接实战》。技术相通思路可鉴。