本文目录导读:

我将为您展示一个工厂方法模式的完整案例,以物流运输系统为例。
案例背景
假设我们正在开发一个物流管理系统,需要支持多种运输方式(卡车、轮船、飞机),每种运输方式都有不同的运输方式和运费计算逻辑。
完整代码实现
// ==================== 1. 产品接口 ====================
// 运输方式接口
interface Transport {
void deliver();
double calculateCost(double distance, double weight);
}
// ==================== 2. 具体产品类 ====================
// 卡车运输
class Truck implements Transport {
@Override
public void deliver() {
System.out.println("使用卡车在公路上运输");
}
@Override
public double calculateCost(double distance, double weight) {
// 卡车运费:每公里2元 + 每公斤0.5元
return distance * 2 + weight * 0.5;
}
}
// 轮船运输
class Ship implements Transport {
@Override
public void deliver() {
System.out.println("使用轮船在海上运输");
}
@Override
public double calculateCost(double distance, double weight) {
// 轮船运费:每公里1元 + 每公斤0.3元(海运便宜)
return distance * 1 + weight * 0.3;
}
}
// 飞机运输
class Plane implements Transport {
@Override
public void deliver() {
System.out.println("使用飞机在空中运输");
}
@Override
public double calculateCost(double distance, double weight) {
// 飞机运费:每公里5元 + 每公斤2元(空运贵)
return distance * 5 + weight * 2;
}
}
// ==================== 3. 工厂接口 ====================
// 物流工厂接口
abstract class LogisticsFactory {
// 工厂方法:创建运输方式
public abstract Transport createTransport();
// 通用业务方法
public void planDelivery(double distance, double weight) {
Transport transport = createTransport();
System.out.println("=== 物流配送计划 ===");
transport.deliver();
double cost = transport.calculateCost(distance, weight);
System.out.println("运输距离: " + distance + "公里");
System.out.println("货物重量: " + weight + "公斤");
System.out.println("运输费用: $" + String.format("%.2f", cost));
System.out.println();
}
}
// ==================== 4. 具体工厂类 ====================
// 公路物流工厂
class RoadLogisticsFactory extends LogisticsFactory {
@Override
public Transport createTransport() {
return new Truck();
}
}
// 海运物流工厂
class SeaLogisticsFactory extends LogisticsFactory {
@Override
public Transport createTransport() {
return new Ship();
}
}
// 航空物流工厂
class AirLogisticsFactory extends LogisticsFactory {
@Override
public Transport createTransport() {
return new Plane();
}
}
// ==================== 5. 客户端代码 ====================
public class FactoryMethodPatternDemo {
public static void main(String[] args) {
System.out.println("========== 工厂方法模式演示 ==========\n");
// 创建不同物流工厂
LogisticsFactory roadFactory = new RoadLogisticsFactory();
LogisticsFactory seaFactory = new SeaLogisticsFactory();
LogisticsFactory airFactory = new AirLogisticsFactory();
// 模拟不同配送需求
System.out.println("--- 陆运需求:距离500km,重量100kg ---");
roadFactory.planDelivery(500, 100);
System.out.println("--- 海运需求:距离2000km,重量5000kg ---");
seaFactory.planDelivery(2000, 5000);
System.out.println("--- 空运需求:距离1000km,重量50kg ---");
airFactory.planDelivery(1000, 50);
// 动态选择运输方式的示例
System.out.println("========== 动态选择运输方式 ==========\n");
LogisticsFactory selectedFactory = selectFactory("紧急");
selectedFactory.planDelivery(300, 30);
}
// 根据需求动态选择工厂
public static LogisticsFactory selectFactory(String requirement) {
// 模拟根据需求选择工厂的场景
if (requirement.contains("紧急")) {
return new AirLogisticsFactory();
} else if (requirement.contains("大批量")) {
return new SeaLogisticsFactory();
} else {
return new RoadLogisticsFactory();
}
}
}
设计模式结构图
┌─────────────────────────────────────┐
│ LogisticsFactory (抽象工厂) │
├─────────────────────────────────────┤
│ + planDelivery() (业务方法) │
│ + createTransport() (抽象工厂方法) │
└─────────────────────────────────────┘
▲
│
┌─────────┼─────────┐
│ │ │
┌───────┐ ┌───────┐ ┌───────┐
│ Road │ │ Sea │ │ Air │
│Factory│ │Factory│ │Factory│
└───────┘ └───────┘ └───────┘
│ │ │
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│ Truck │ │ Ship │ │ Plane │
└───────┘ └───────┘ └───────┘
▲ ▲ ▲
└─────────┼─────────┘
│
┌─────────────────────────────────────┐
│ Transport (产品接口) │
├─────────────────────────────────────┤
│ + deliver() │
│ + calculateCost() │
└─────────────────────────────────────┘
运行结果
========== 工厂方法模式演示 ==========
--- 陆运需求:距离500km,重量100kg ---
=== 物流配送计划 ===
使用卡车在公路上运输
运输距离: 500.0公里
货物重量: 100.0公斤
运输费用: $1050.00
--- 海运需求:距离2000km,重量5000kg ---
=== 物流配送计划 ===
使用轮船在海上运输
运输距离: 2000.0公里
货物重量: 5000.0公斤
运输费用: $3500.00
--- 空运需求:距离1000km,重量50kg ---
=== 物流配送计划 ===
使用飞机在空中运输
运输距离: 1000.0公里
货物重量: 50.0公斤
运输费用: $5100.00
========== 动态选择运输方式 ==========
=== 物流配送计划 ===
使用飞机在空中运输
运输距离: 300.0公里
货物重量: 30.0公斤
运输费用: $1560.00
扩展案例:带参数和条件的工厂方法
// 更复杂的需求,支持配置文件配置运输方式
abstract class AdvancedLogisticsFactory {
// 工厂方法支持自定义参数
public abstract Transport createTransport(String... options);
// 检查订单状态的方法
public void processOrder(String orderId, double distance, double weight) {
Transport transport = createTransport(null);
System.out.println("处理订单: " + orderId);
transport.deliver();
// 附加服务
if (weight > 1000) {
System.out.println("大件货物,建议购买保险");
}
if (distance > 100) {
System.out.println("长距离运输,建议锁定价格");
}
}
}
// 高级工厂实现
class SmartLogisticsFactory extends AdvancedLogisticsFactory {
private boolean isExpress = false;
public SmartLogisticsFactory(boolean express) {
this.isExpress = express;
}
@Override
public Transport createTransport(String... options) {
// 根据选项动态选择
if (options != null && options.length > 0) {
if (options[0].equals("air")) {
return new Plane();
} else if (options[0].equals("sea")) {
return new Ship();
}
}
// 根据是否加急选择
if (isExpress) {
return new Plane();
}
return new Truck();
}
}
优点与适用场景
优点:
- 开闭原则:增加新产品不需要修改现有代码
- 灵活性:客户端通过工厂获取产品,屏蔽了具体实现
- 解耦:产品创建与使用分离
适用场景:
- 创建对象需要大量重复代码
- 客户端不需要知道具体产品类
- 希望通过子类来定制创建过程
这个案例完整展示了工厂方法模式的核心思想:定义一个创建对象的接口,让子类决定实例化哪个类,通过这种方式,系统可以在不修改现有代码的情况下灵活扩展新的运输方式。