它仍然是工厂方法吗?

时间:2014-09-15 20:23:43

标签: c# design-patterns factory-pattern

我发现的所有例子都基于枚举,它提供了返回正确的类。我需要一些对类的类型作出反应的东西,并且通过在每次调用时赋予它新的参数来控制新对象的构造函数。

它仍然是工厂方法吗?这是好的解决方案吗?我可以用这种方式玩设计模式吗?也许有更好的解决方案提供?

using System;

namespace ConsoleApplication1
{
  public abstract class Strategy
  {
    protected int Init;
    private static int _initA = 3;
    private static int _initB = 42;

    public static Strategy StrategyFactory(Strategy strategyType)
    {
      var tempStrategyA = strategyType as StrategyA;
      if (tempStrategyA != null)
      {
        _initA++;
        return new StrategyA(_initA);
      }

      var tempStrategyB = strategyType as StrategyB;
      if (tempStrategyB != null)
      {
        _initB = _initA * 2;
        return new StrategyB(_initB);
      }

      throw new ArgumentException();
    }
  }

  public class StrategyA : Strategy
  {
    public StrategyA(int init)
    {
      Init = init*2;
    }
  }

  public class StrategyB : Strategy
  {
    public StrategyB(int init)
    {
      Init = init*3;
    }
  }
}

2 个答案:

答案 0 :(得分:3)

这是一种非常奇怪的工厂方法。请参阅工厂方法签名:

// "strategyType"? It's not a type, but an object reference
public static Strategy StrategyFactory(Strategy strategyType)

在.NET中,有一个名为Type的类,它表示某些给定类型的类型元数据。您可以使用typeof运算符或Object.GetType()方法获取它。

您的工厂方法应为:

public static Strategy StrategyFactory(Type strategyType)

您可以使用反射实例化一个类型:

Activator.CreateInstance(strategyType);

give constructor arguments还有一个CreateInstance重载。

仿制药怎么样?

从.NET 2.0开始(我们很多年前就已经开始讨论了!),.NET有泛型。总之,它们提供了一种方法来指定不具有具体类型的参数,直到在某处实际声明或使用方法或类型,并提供哪些实际类型将具有整个参数。

例如,这将是一个现代工厂方法:

// "where ..." is a generic constraint which defines that the given generic
// argument must be Strategy or a derived class of Strategy, and it must
// have a public parameterless constructor
public TStrategy Create<TStrategy>() where TStrategy : Strategy, new()
{
    TStrategy strategy = new TStrategy();

    // more stuff

    return strategy;
}

现在你可以这样使用它:

MyStrategy strategy = StrategyFactory.Create<MyStrategy>();

我可以给你一个仿制药&#39;大师班,但这超出了你的问题的范围。无论如何,我给你一个关于如何使用正确的工具建立工厂的线索/提示。 You can learn more about generics in MSDN

答案 1 :(得分:3)

对我而言,您实际上想要为每种策略设置不同的工厂。如果您想要管理工厂创建的对象的生命周期,或者为了构造各种类型而管理依赖项/参数,那么工厂就很好。

策略工厂的定义

interface IStrategyFactory
{
    public Strategy Create(int value);
}

class StrategyAFactory : IStrategyFactory
{
    public Strategy Create(int value)
    {
        return new StrategyA(value);
    }
}

class StrategyBFactory : IStrategyFactory
{
    public Strategy Create(int value)
    {
        return new StrategyB(value);
    }
}

用法

class MyController : ApiController
{
    private IStrategyFactory _factory;

    public MyController(IStrategyFactory factory)
    {
        _factory = factory;
    }

    public HttpResponseMessage Get(int value)
    {
        // here we don't care what exact strategy is used, this is good!
        var strategy = _factory.Create(value);

        var newValue = strategy.Calculate();

        return new HttpResponseMessage(newValue);
    }
}