我有许多实现相同接口的算法类;另一个"工厂" class有责任通过config参数实例化正确的算法类,然后在该实例上调用start方法。
我想将算法类的构造函数(或任何其他实例创建机制)的可见性限制为仅限工厂类。
我该如何解决这个问题?我能想到的唯一干净的解决方案是将这些类移动到不同的.dll中并将算法类更改为私有类,但这不是我现在想要做的。
答案 0 :(得分:3)
这不是您希望听到的答案,但是:不要。
通过创建构造函数private/internal/protected
,您很难测试算法,并且您也阻止API的任何使用者手动选择他们自己的实现而不是使用工厂。
我想说将构造函数保留为public,只需确保构造函数中声明了所需的每个依赖项。这是我对构造函数的各种修饰符的看法:
public
- 每个人都可以访问您的构造函数,您可以测试该类 - 这很好。protected
- 子类可以访问构造函数。这没关系,但实际上只用于抽象类和/或构造函数链接。internal
- 您将构造函数的使用限制为InternalsVisibleTo
(朋友)程序集。这意味着程序集中的任何人都可以正常构造它,但其他程序集必须明确地InternalsVisibleTo
或强制使用您的工厂,从而将算法耦合到工厂。private
- 用于隐藏默认构造函数(尽管如果创建具有至少一个参数的构造函数则不需要执行此操作),或仅创建可链接构造函数。 TL; DR - 我建议不要制作构造函数 internal
。通过这样做你也可以制作类 internal
(你 通过他们的界面引用算法而不是他们的类,对吗?)
另一个解决方案是创建类private
的实现并将它们嵌套在Factory中。让它们都实现一个通用接口(它们应该已经在做)并将接口暴露给应用程序的其余部分。这仍然无法避免使其难以测试的问题。
答案 1 :(得分:2)
也许你会对以下样本感到满意(是的,我知道不应该正常使用什么反射......)
public class Algorithm
{
private Algorithm()
{
}
public void SomeMethod()
{
}
}
public static class Factory
{
public static Algorithm Create()
{
var constructor = typeof(Algorithm).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null);
return (Algorithm)constructor.Invoke(null);
}
}
在这里,您可以通过Factory.Create创建算法实例,而不是通过新算法。