我发现的所有例子都基于枚举,它提供了返回正确的类。我需要一些对类的类型作出反应的东西,并且通过在每次调用时赋予它新的参数来控制新对象的构造函数。
它仍然是工厂方法吗?这是好的解决方案吗?我可以用这种方式玩设计模式吗?也许有更好的解决方案提供?
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;
}
}
}
答案 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);
}
}