工厂方法模式和公共构造函数

发布于 2024-08-31 22:02:37 字数 379 浏览 5 评论 0原文

我正在创建一个返回对象的新实例的工厂方法。我想阻止任何使用我的代码的人在我的对象上使用公共构造函数。有什么办法可以做到这一点吗?

这通常是如何实现的:

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

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

然后我想限制/阻止其他开发人员(包括几个月后的我)制作 Mercedes4WD 的实例。但让他们调用我的工厂方法。怎样做?

Im making a factory method that returns new instances of my objects. I would like to prevent anyone using my code from using a public constructor on my objects. Is there any way of doing this?

How is this typically accomplished:

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

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

I then would like to limit/prevent the other developers (including me in a few months) from making an instance of Mercedes4WD. But make them call my factory method. How to?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

世界如花海般美丽 2024-09-07 22:02:37

您可以将类 Mercedes4WD 设为具有内部构造函数的内部类,这将阻止从包含工厂的库外部对其进行实例化。

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

您还可以将 Mercedes4WD 放在一个程序集中,将工厂放在另一个程序集中,将您的代码放在第三个程序集中,那么工厂程序集可能是 Mercedes4WD 程序集的友元,这样它就可以创建实例,但主要代码不会,所以它不能。这将缩小创建实例的范围,但一切都会变得更加复杂。

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

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

you can make the class Mercedes4WD a internal class with an internal constructor which will stop it being instantiated from outside of the library which contains the factory.

You might be better having a factory method on your class which produces the instance, which you could call from your factory class, but that is not that different from just 'newing' it up.

You could also have the Mercedes4WD on one assembly, the factory in another and your code in a third, then the factory assembly could be a friend of the Mercedes4WD assembly so it could create the instances, but the main code would not be so it couldn't. That would reduce the scope under which the instances could be created, but everything would a bit more complex.

Really you need to provide some more information. when you say you would like to stop people constructing later, are you talking about other devs working in the same codebase? If so there is not really that much you can do. You might be able to do some checking in the constructor to see if the next method up in the stack is the factory's method and throw an exception if not, but I'm not sure that is a great idea...

The real question is why do you want to do this?

2024-09-07 22:02:37

您确实需要相当于 friend 类的 C++ 类,但 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();
    }
}

You really want the C++ equivalent of friend classes, but C# does not have them. You can always make the constructor private and add a static factory method to Mercedes4WD. This would prevent "accidental" direct construction:

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();
    }
}
|煩躁 2024-09-07 22:02:37

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

You can define the default contructor of your class Mercedes4WD as internal. So the default constructor can only be called within the assembly where the type Mercedes4WD is defined.

记忆里有你的影子 2024-09-07 22:02:37

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

for a factory method, make the constructor private but it looks like you are actually implementing the factory pattern

一生独一 2024-09-07 22:02:37

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

Keep the constructors internal or implement the interfaces explicitly, so that the classes can not be instantiated directly.

戏蝶舞 2024-09-07 22:02:37

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

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

It sounds like your general question is how a class can make a method available to one or more other classes, without making it available to all classes in the assembly. Assuming that no object exposes its direct constructors in any form, you can achieve the effect you're looking for using static delegates.

Suppose class Foo wants to expose its static Wozzle method to class Bar but nobody else. Bar should have a static delegate which it uses to call Foo.Wozzle. If Bar needs to call Foo.Wozzle but the delegate hasn't been created yet, it should create a new object of a type known only to Bar (call it the "token") and pass it to static method Foo.BarRequestsWozzle. That method should create a static delegate for Foo.Wozzle if one hasn't yet been created, and pass that delegate, along with the passed-in token object, to Bar.FooSuppliesWozzle. That method should check whether the type of the passed-in token matches the one that was given to BarRequestsWozzle and, if so, set the delegate appropriately. Foo doesn't give its Wozzle method to anyone but Bar, nobody can create the proper token type except Bar, and Bar doesn't give his token to anyone but Foo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文