gpt4 book ai didi

c# - 工厂的正确实现

转载 作者:行者123 更新时间:2023-11-30 21:29:45 25 4
gpt4 key购买 nike

我正在尝试以正确的方式实现工厂模式,但我不确定这是否正确。我有三个从基类派生的模型类,如下所示:

class BaseStyle
{
public string Name
{
get;
set;
}
}

class PointStyle : BaseStyle
{
public PointStyle(string name)
{
Name = name;
}
}

class LineStyle : BaseStyle
{
public LineStyle(string name)
{
Name = name;
}
}

class PolyStyle : BaseStyle
{
public PolyStyle(string name)
{
Name = name;
}
}

然后我有一个名为 StyleFactory 的类。此类采用 string 来确定要创建的 Style 类型并返回该 Style。

public class StyleFactory
{
public static BaseStyle CreateStyle(string styleType)
{
if (styleType == "point")
{
return CreatePointStyle();
}
if (styleType == "line")
{
return CreateLineStyle();
}
if (styleType == "poly")
{
return CreatePolytStyle();
}
}

private static PointStyle CreatePointStyle()
{
//creates a pointstyle
}

private static LineStyle CreateLineStyle()
{
//creates a linestyle
}

private static PolyStyle CreatePolyStyle()
{
//creates a polystyle
}
}

然后在代码中这样调用它:

PointStyle pointStyle = StyleFactory.CreateStyle("point");

这是解决问题的最佳方法吗?我应该将三个“创建”函数拆分为它们自己的单独类吗?使用泛型会更有意义吗?

最佳答案

考虑调用者必须使用该方法的方式:

//Existing
BaseStyle someStyle = factory.CreateStyle("point", name);

这里有两个问题。其中之一是没有对字符串“point”进行编译时评估;为了缓解这个问题,您可以使用常量字符串或类似的东西。第二个是返回的对象只是一个BaseStyle;为了做任何有趣的事情,客户总是不得不施放它。所以实际上代码看起来像这样:

//Practical use of existing
PointStyle pointStyle = (PointStyle)factory.CreateStyle(Constants.StylesPoint, name);

我们可以用泛型来解决这两个问题。如果我们以正确的方式定义方法,返回类型会在编译时自动为我们选择。这也意味着类型的选择是在编译时检查的,所以我们不必担心字符串是错误的。调用的示例:

//Using generics
PointStyle pointStyle = factory.CreateStyle<PointStyle>(name);

为了允许调用者以这种方式使用该方法,我们定义了一个类型参数:

public T CreateStyle<T>(string name) where T : BaseStyle
{
var type = typeof(T);
if (type == typeof(PointStyle))
{
return new PointStyle(name) as T;
}
if (type == typeof(LineStyle))
{
return new LineStyle(name) as T;
}
if (type == typeof(PolyStyle)
{
return new PolyStyle(name) as T;
}
throw new Exception("The type {0} is not supported.", typeof(T).FullName);
}

或者如果你想聪明一点:

public T CreateStyle<T>(string name) where T : BaseStyle
{
try
{
return Activator.CreateInstance(typeof(T), new [] { name } );
}
catch(MissingMethodException exception)
{
throw new InvalidOperationException("The specified style does not have an appropriate constructor to be created with this factory.", exception);
}
}

最后一种方法不需要维护以在以后添加其他样式;只要它们继承自 BaseStyle,并且包含一个接受名称作为单个字符串参数的构造函数,工厂就能够自动生成它们。

补充说明:

虽然静态工厂方法在几年前风靡一时,但如今它们通常作为实例 方法实现,因此您可以在IoC 下注入(inject)工厂。 .如果将方法设为静态,则任何调用它的代码都将具有静态依赖性,这很难进行 stub 和单元测试。

关于c# - 工厂的正确实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55108958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com