策略模式-工厂模式区别

策略模式和工厂模式区别

介绍#

策略模式和工厂模式是两种不同的设计模式,它们有不同的目的和使用场景。下面是它们之间的主要区别:

策略模式 (Strategy Pattern)#

  1. 目的

    • 策略模式旨在定义一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式使得算法可以独立于使用它们的客户端而变化。
  2. 结构

    • 策略模式包含一个策略接口(Strategy)和一个或多个实现该接口的具体策略类(ConcreteStrategyAConcreteStrategyB等)。
    • 上下文类(Context)持有一个策略接口的引用,并在需要时调用策略的方法。
  3. 使用场景

    • 需要在运行时选择不同的算法或行为。
    • 避免使用大量的条件语句(如if-elseswitch-case)。
    • 需要封装一系列相关的算法,使它们可以互相替换。

工厂模式 (Factory Pattern)#

  1. 目的

    • 工厂模式旨在提供一个创建对象的接口,而不是直接在代码中实例化对象。它将对象的实例化过程延迟到子类或具体的工厂类中进行。
  2. 结构

    • 工厂模式包含一个工厂接口或抽象类(Factory),以及一个或多个具体工厂类(ConcreteFactoryAConcreteFactoryB等)。
    • 客户端通过调用工厂方法来获取对象,而不是直接使用new关键字。
  3. 使用场景

    • 需要将对象的创建和使用分离。
    • 需要在创建对象时增加一些额外的逻辑或处理。
    • 需要创建一系列相关或依赖的对象。

主要区别#

  1. 关注点不同

    • 策略模式关注的是算法的替换和变化,它强调的是行为的选择和执行。
    • 工厂模式关注的是对象的创建,它强调的是实例化过程的控制和管理。
  2. 目的不同

    • 策略模式通过定义一组算法来实现行为的可替换性和灵活性。
    • 工厂模式通过提供创建对象的接口来实现对象创建过程的解耦和灵活性。
  3. 实现方式不同

    • 策略模式包含策略接口和具体策略类,通过上下文类来使用不同的策略。
    • 工厂模式包含工厂接口或抽象类和具体工厂类,通过工厂方法来创建对象。
  4. 应用场景不同

    • 策略模式适用于需要在运行时动态选择算法或行为的场景。
    • 工厂模式适用于需要控制实例化过程,或者需要创建一系列相关对象的场景。

示例#

你提到的这一点很重要。的确,工厂模式和策略模式在某些情况下可能会有些混淆。让我们更清晰地剖析它们的结合点,以及为什么要将它们结合使用。

假设我们有一款游戏,它有不同的难度级别,比如简单、中等、困难等。我们可以为每一个难度级别创建一个不同的策略,比如简单难度的策略可能是随机移动,中等难度的策略可能是随机移动和随机攻击,困难难度的策略可能是随机移动、随机攻击和随机死亡。

我们可以创建一个策略工厂,它可以根据难度级别来创建不同的策略对象。比如,简单难度的策略工厂可以创建随机移动策略对象,中等难度的策略工厂可以创建随机移动和随机攻击策略对象,困难难度的策略工厂可以创建随机移动、随机攻击和随机死亡策略对象。

我们可以创建一个上下文类,它持有策略对象,并在运行时选择不同的策略。比如,上下文类可以根据游戏难度级别来选择不同的策略对象,并在游戏运行时调用策略对象的Execute()方法来执行策略。

这样,我们就可以在运行时动态地选择不同的策略,而不需要修改上下文类和客户端代码。

策略模式#

策略模式主要用于封装算法,使得它们可以互换。其目的是在运行时选择不同的算法,而不需要修改上下文类。

工厂模式#

工厂模式主要用于创建对象,其目的是将对象创建的细节封装起来,使得代码中不直接使用new关键字,而是通过工厂方法来创建对象。

结合使用的目的#

结合使用策略模式和工厂模式,可以使系统更灵活。工厂模式用于创建具体的策略对象,而策略模式用于在运行时选择和执行这些策略。

代码示例#

下面的示例展示了如何结合使用策略模式和工厂模式。工厂模式负责创建策略对象,策略模式负责在运行时选择和执行策略。

策略接口#

// IStrategy.cs
public interface IStrategy
{
    void Execute();
}

具体策略#

// ConcreteStrategyA.cs
public class ConcreteStrategyA : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("执行策略 A");
    }
}

// ConcreteStrategyB.cs
public class ConcreteStrategyB : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("执行策略 B");
    }
}

策略工厂#

// StrategyFactory.cs
public class StrategyFactory
{
    public IStrategy CreateStrategy(string strategyType)
    {
        return strategyType switch
        {
            "A" => new ConcreteStrategyA(),
            "B" => new ConcreteStrategyB(),
            _ => throw new ArgumentException("Invalid strategy type")
        };
    }
}

上下文类#

// Context.cs
public class Context
{
    private IStrategy _strategy;

    public void SetStrategy(IStrategy strategy)
    {
        _strategy = strategy;
    }

    public void ExecuteStrategy()
    {
        _strategy.Execute();
    }
}

客户端代码#

// Program.cs
using System;

class Program
{
    static void Main()
    {
        StrategyFactory factory = new StrategyFactory();
        Context context = new Context();

        // 选择策略类型,可以从配置文件、用户输入等获取
        string strategyType = "A";
        
        // 使用工厂创建策略
        IStrategy strategy = factory.CreateStrategy(strategyType);

        // 设置上下文策略并执行
        context.SetStrategy(strategy);
        context.ExecuteStrategy();

        // 切换到另一种策略
        strategyType = "B";
        strategy = factory.CreateStrategy(strategyType);
        context.SetStrategy(strategy);
        context.ExecuteStrategy();
    }
}

结合使用的好处#

  1. 职责分离

    • 工厂模式负责创建具体的策略对象。
    • 策略模式负责在运行时选择和执行策略。
  2. 扩展性强

    • 可以很容易地添加新的策略,而不需要修改上下文类和客户端代码,只需在工厂中增加对应的策略创建逻辑即可。
  3. 代码简洁

    • 客户端代码不需要了解策略的具体实现,只需通过工厂获取策略对象,并在上下文中使用即可。

总结#

结合策略模式和工厂模式使用,可以充分利用两者的优点,使代码更加灵活、易于扩展和维护。工厂模式解耦了对象的创建过程,策略模式解耦了算法的选择和执行,两者结合使得系统既可以灵活选择算法,又可以灵活创建对象。

作者:zhuhy

出处:https://www.cnblogs.com/AILove/p/18217299

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   zhuhy  阅读(533)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示