.net 工厂方法模式与公共构造函数

.net 工厂方法模式与公共构造函数,.net,design-patterns,factory,public-method,.net,Design Patterns,Factory,Public Method,我正在制作一个工厂方法,返回我的对象的新实例。我想阻止任何使用我的代码的人在我的对象上使用公共构造函数。有没有办法做到这一点 这通常是如何实现的: public abstract class CarFactory { public abstract ICar CreateSUV(); } public class MercedesFactory : CarFactory { public override ICar CreateSUV() { return new Merc

我正在制作一个工厂方法,返回我的对象的新实例。我想阻止任何使用我的代码的人在我的对象上使用公共构造函数。有没有办法做到这一点

这通常是如何实现的:

public abstract class CarFactory
{
  public abstract ICar CreateSUV();
}

public class MercedesFactory : CarFactory
{
  public override ICar CreateSUV()
  {
    return new Mercedes4WD();
  }
}

然后,我想限制/阻止其他开发人员(包括几个月后的我)制作Mercedes4WD的实例。但让他们称之为我的工厂方法。如何?

您可以将Mercedes4WD类的默认构造函数定义为internal。因此,只能在定义了Mercedes4WD类型的程序集中调用默认构造函数。

对于工厂方法,将构造函数设置为私有,但看起来您实际上是在实现工厂模式。

将构造函数保留在内部或显式实现接口,因此,类不能直接实例化。

您可以使类
Mercedes4WD
成为具有内部构造函数的内部类,该构造函数将阻止它从包含工厂的库外部实例化

您最好在类上使用一个工厂方法来生成实例,您可以从工厂类调用该实例,但这与“更新”实例并没有什么不同

您还可以将
Mercedes4WD
放在一个程序集上,将工厂放在另一个程序集上,将代码放在第三个程序集上,然后工厂程序集可以是
Mercedes4WD
程序集的朋友,这样它就可以创建实例,但主代码不是这样,它就不能创建实例。这将减少创建实例的范围,但一切都会稍微复杂一些

你真的需要提供更多的信息。当你说你想停止人们以后的构建时,你是在说其他开发人员在同一个代码库中工作吗?如果是这样的话,你真的没有什么可以做的。您可以在构造函数中进行一些检查,以查看堆栈中的下一个方法是否是工厂的方法,如果不是,则抛出异常,但我不确定这是一个好主意


真正的问题是你为什么要这么做?

你真的想要C++等价于代码>朋友< /Cuff>类,但是C没有。您可以始终将构造函数设置为私有,并将静态工厂方法添加到
Mercedes4WD
。这将防止“意外”直接施工:

public class Mercedes4WD : ICar
{
    private Mercedes4WD()
    {
        // ...
    }

    public static Mercedes4WD Create()
    {
        return new Mercedes4WD();
    }
}

public abstract class CarFactory
{
    public abstract ICar CreateSUV();
}

public class MercedesFactory : CarFactory
{
    public override ICar CreateSUV()
    {
        return Mercedes4WD.Create();
    }
}

听起来您的一般问题是,一个类如何使一个方法可用于一个或多个其他类,而不使其可用于程序集中的所有类。假设没有对象以任何形式公开其直接构造函数,则可以使用静态委托实现所需的效果


假设类Foo希望将其静态Wozzle方法公开给类Bar,而不是其他任何人。Bar应该有一个静态委托,用于调用Foo.Wozzle。如果Bar需要调用Foo.Wozzle,但委托尚未创建,它应该创建一个只有Bar知道的类型的新对象(称为“标记”),并将其传递给静态方法Foo.BarRequestsWozzle。如果尚未创建Foo.Wozzle的静态委托,则该方法应为Foo.Wozzle创建静态委托,并将该委托与传入的令牌对象一起传递给Bar.FooSuppliesWozzle。该方法应该检查传入标记的类型是否与提供给BarreQuestSwowzzle的类型匹配,如果匹配,则适当地设置委托。Foo不会将其Wozzle方法提供给Bar以外的任何人,除了Bar之外,没有人可以创建正确的令牌类型,Bar也不会将其令牌提供给Foo以外的任何人。

刚刚检查过。不可选择进行单独的集会(公司政治)。我最初的想法是限制团队中的其他开发人员在应用程序中更新对象。我想我想成为这里的密码警察。我的解决方案可能更像是一种“教育性”的方法,教其他开发人员只使用工厂……那么我认为您最好的选择可能是通过代码审查来实施这一点。通过查找构造函数的用法,这是相当容易检查的,如果它在多个地方(工厂)使用,那么您需要更改它。这可能会更好,因为它让你有机会解释为什么他们应该使用工厂。或者,尝试使用诸如NDepend之类的工具强制执行这些规则。这是专门设计来进行此类验证的。@Steven:+1表示独立。也可以使用自定义FXCop规则执行此操作。FXCop规则为+1。请注意,编写FxCop规则相当困难。另一方面,FxCop是免费的。独立投资当然不是。这与直接建设相同,只需再打一次电话。因此,这不会阻止任何人创建Mercedes4WD,但会阻止没有查看界面就尝试它的人。@PoweRoy,对,我们的想法是不鼓励直接创建,因为考虑到问题的限制,在程序集中禁止直接创建是不可能的。您是否正在尝试创建一个单例工厂,即创建其他类实例的单例工厂?