3

我有许多实现相同接口的算法类;另一个“工厂”类负责通过配置参数实例化正确的算法类,然后在该实例上调用 start 方法。

我想将算法类的构造函数(或任何其他实例创建机制)的可见性仅限于工厂类。

我该如何解决这个问题?我能想到的唯一干净的解决方案是将这些类移动到不同的 .dll 中并将算法类更改为私有,但这不是我现在想要做的。

4

2 回答 2

3

这不是你想听到的答案,但是:不要。

通过构造该构造函数private/internal/protected,您很难测试算法,并且还阻止了 API 的任何消费者手动选择他们自己的实现而不是使用工厂。

我想说让构造函数公开,只要确保在构造函数中声明了所需的每个依赖项。这是我对构造函数的各种修饰符的看法:

  • public- 每个人都可以访问你的构造函数,并且你可以测试这个类 -这很好
  • protected- 子类可以访问构造函数。这没关系,但仅真正用于抽象类和/或构造函数链接。
  • internal- 您将构造函数的使用限制为InternalsVisibleTo(朋友)程序集。这意味着您的程序集中的任何人都可以正常构造它,但其他程序集必须明确地使用InternalsVisibleTo被迫使用您的工厂,从而将算法与工厂耦合。
  • private- 用于隐藏默认构造函数(尽管如果创建具有至少一个参数的构造函数,则不需要这样做),或仅创建可链接的构造函数。

TL; DR - 我建议不要制作constructor internal。通过这样做,您还不如创建 internal(您通过它们的接口而不是它们的类引用算法,对吗?)

另一种解决方案是实现类private并将它们嵌套在工厂中。让他们都实现一个通用接口(他们应该已经这样做了)并将接口暴露给应用程序的其余部分。这仍然不能避免难以测试的问题。

于 2014-09-11T08:26:29.673 回答
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 创建算法实例,而不是通过新算法。

于 2014-09-11T08:24:24.970 回答