工厂模式和策略模式区别以及使用

1. 概述

工厂模式(Factory Pattern)和策略模式(Strategy Pattern)都是软件设计中常用的行为型设计模式,它们在解决软件设计中的问题时,各有其特点和适用场景。

2. 工厂模式

工厂模式的核心目的是用于创建对象,而不将对象的创建逻辑暴露给客户端。客户端不需要直接实例化对象,而是通过一个共同的接口来获取对象。工厂模式通常用于以下场景:

  • 当创建对象的逻辑比较复杂时。
  • 当创建对象需要大量的参数,或者这些参数具有不同的数据类型时。
  • 当对象的创建依赖于系统环境或者配置信息时。
  • 当需要对创建的对象进行管理时。

工厂模式主要分为两种:简单工厂模式和工厂方法模式。简单工厂模式集中了所有对象的创建逻辑,而工厂方法模式将创建对象的具体逻辑推迟到子类中实现。

3. 策略模式

策略模式定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。

策略模式通常用于以下场景:

  • 系统中有很多类,它们之间的区别仅在于它们的行为。
  • 需要使用组合而非继承的方式来实现算法的多样性。
  • 需要动态地选择算法的行为。

策略模式通常涉及以下几个角色:策略接口、具体策略类、上下文环境和客户端。客户端可以根据需要选择具体策略类来实现策略接口。

4. 区别

  • 核心思想不同:
    工厂模式的核心是创建对象,而策略模式的核心是定义一系列可互相替换的算法。
    工厂模式关注的是对象的创建过程,策略模式关注的是如何使用这些对象。
  • 应用场景不同:
    工厂模式通常用于对象的创建和管理。
    策略模式用于定义算法族,让它们之间可以互相替换。
  • 目的和结构:
    工厂模式目的是为了降低对象创建的复杂性,结构上通常包含一个工厂类和多个产品类。
    策略模式目的是为了定义策略的多样性,结构上包含策略接口、具体策略类、上下文环境和客户端。
  • 使用时机:
    工厂模式在对象创建时被调用。
    策略模式在对象使用时被调用,以决定具体使用哪个策略。
  • 灵活性和可扩展性:
    工厂模式可以很容易地引入新的产品类型,但可能会导致工厂类的复杂性增加。
    策略模式可以很容易地引入新的策略,而且不会影响到已有的策略实现。

总的来说,工厂模式和策略模式都是为了提高代码的灵活性和可维护性,但它们适用的场景和解决的问题不同。工厂模式侧重于创建对象,而策略模式侧重于定义行为的多样性。

5. 代码实现

5.1 工厂模式

假设我们有一个简单的例子,需要根据不同的参数来创建不同类型的 Car 对象。

// Car 接口
public interface Car {
    void drive();
}

// 具体 Car 类
public class Sedan implements Car {
    @Override
    public void drive() {
        System.out.println("Sedan is driving");
    }
}

public class Truck implements Car {
    @Override
    public void drive() {
        System.out.println("Truck is driving");
    }
}

// 工厂类
public class CarFactory {
    public static Car createCar(String type) {
        if ("sedan".equalsIgnoreCase(type)) {
            return new Sedan();
        } else if ("truck".equalsIgnoreCase(type)) {
            return new Truck();
        }
        throw new IllegalArgumentException("Unknown car type: " + type);
    }
}

// 客户端代码
public class FactoryPatternDemo {
    public static void main(String[] args) {
        Car car = CarFactory.createCar("sedan");
        car.drive(); // 输出 "Sedan is driving"
    }
}

5.2 策略模式

假设我们有一个需要进行计算的例子,根据不同的策略来计算数值。

// 策略接口
public interface Strategy {
    double doOperation(double num1, double num2);
}

// 具体策略类
public class Addition implements Strategy {
    @Override
    public double doOperation(double num1, double num2) {
        return num1 + num2;
    }
}

public class Subtraction implements Strategy {
    @Override
    public double doOperation(double num1, double num2) {
        return num1 - num2;
    }
}

public class Multiplication implements Strategy {
    @Override
    public double doOperation(double num1, double num2) {
        return num1 * num2;
    }
}

// 上下文环境
public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public double executeStrategy(double num1, double num2) {
        return strategy.doOperation(num1, num2);
    }
}

// 客户端代码
public class StrategyPatternDemo {
    public static void main(String[] args) {
        Context context = new Context(new Addition());
        System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

        context.setStrategy(new Subtraction());
        System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

        context.setStrategy(new Multiplication());
        System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
    }
}

区别说明

  • 工厂模式 关注于对象的创建,客户端代码不直接创建对象,而是通过工厂类来创建。在工厂模式中,客户端只需要知道传入工厂类的参数,而不需要关心对象的创建细节。

  • 策略模式 关注于定义一系列可互相替换的算法,客户端代码在运行时可以根据需要选择具体的算法。策略模式将算法的选择与算法的实现分离开来,使得算法可以独立于使用它们的客户变化。

在代码实现上,工厂模式通常包含一个或多个工厂类和多个产品类,而策略模式则包含一个策略接口、多个具体策略类、一个上下文环境和客户端。工厂模式在编译时确定具体产品的类型,而策略模式在运行时根据需要切换策略。

5.3 简单工厂模式 + 策略模式

  1. 首先,我们定义一个交通工具接口和它的实现类,这些类将作为策略模式中的算法。
  2. 接下来,我们实现简单工厂模式,用于创建不同的交通工具对象。
  3. 创建一个上下文环境,它将使用简单工厂模式来获取交通工具对象,并使用策略模式来选择不同的移动方式。
  4. 编写客户端代码来使用这个上下文环境。
// 交通工具接口
public interface Vehicle {
    void move();
}

// 具体交通工具类
public class Car implements Vehicle {
    @Override
    public void move() {
        System.out.println("Car is moving");
    }
}

public class Train implements Vehicle {
    @Override
    public void move() {
        System.out.println("Train is moving");
    }
}

// 工厂接口
public interface VehicleFactory {
    Vehicle create();
}

// 具体工厂类
public class CarFactory implements VehicleFactory {
    @Override
    public Vehicle create() {
        return new Car();
    }
}

public class TrainFactory implements VehicleFactory {
    @Override
    public Vehicle create() {
        return new Train();
    }
}

// 工厂管理类
public class VehicleFactoryManager {
    private final Map<String, VehicleFactory> factories = new HashMap<>();

    public void registerFactory(String type, VehicleFactory factory) {
        factories.put(type, factory);
    }

    public Vehicle createVehicle(String type) {
        VehicleFactory factory = factories.get(type);
        if (factory == null) {
            throw new IllegalArgumentException("Unknown vehicle type: " + type);
        }
        return factory.create();
    }
}

// 上下文环境
public class Context {
    private Vehicle vehicle;

    public Context(Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    public void setVehicle(Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    public void executeMove() {
        vehicle.move();
    }
}

// 客户端代码
public class SimpleFactoryStrategyDemo {
    public static void main(String[] args) {
        // 创建工厂管理实例
        VehicleFactoryManager manager = new VehicleFactoryManager();

        // 注册工厂
        manager.registerFactory("car", new CarFactory());
        manager.registerFactory("train", new TrainFactory());

        // 使用工厂管理实例创建交通工具
        Vehicle car = manager.createVehicle("car");
        Vehicle train = manager.createVehicle("train");

        // 将交通工具设置到上下文环境中
        Context carContext = new Context(car);
        Context trainContext = new Context(train);

        // 执行移动操作
        carContext.executeMove(); // 输出 "Car is moving"
        trainContext.executeMove(); // 输出 "Train is moving"
    }
}
  • 51
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值