工厂方法案例

wen java案例 2

本文目录导读:

工厂方法案例

  1. 案例背景
  2. 完整代码实现
  3. 设计模式结构图
  4. 运行结果
  5. 扩展案例:带参数和条件的工厂方法
  6. 优点与适用场景

我将为您展示一个工厂方法模式的完整案例,以物流运输系统为例。

案例背景

假设我们正在开发一个物流管理系统,需要支持多种运输方式(卡车、轮船、飞机),每种运输方式都有不同的运输方式和运费计算逻辑。

完整代码实现

// ==================== 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();
    }
}

优点与适用场景

优点:

  1. 开闭原则:增加新产品不需要修改现有代码
  2. 灵活性:客户端通过工厂获取产品,屏蔽了具体实现
  3. 解耦:产品创建与使用分离

适用场景:

  • 创建对象需要大量重复代码
  • 客户端不需要知道具体产品类
  • 希望通过子类来定制创建过程

这个案例完整展示了工厂方法模式的核心思想:定义一个创建对象的接口,让子类决定实例化哪个类,通过这种方式,系统可以在不修改现有代码的情况下灵活扩展新的运输方式。

抱歉,评论功能暂时关闭!