如果我们使用工厂模式,我们应该对用户隐藏产品吗?

本文关键字:我们 隐藏 用户 工厂 模式 如果 | 更新日期: 2023-09-27 18:19:25

假设我有一个生产Dog, CatFishAnimalFactory类。使用AnimalFactory使事情变得非常简单,一切都很好。

我的问题是,是否有一个规则或良好的做法,建议我们隐藏狗,猫和鱼直接使用?我的意思是Dog myDog = new Dog();将在代码中被禁止。

如果有的话,我们如何正确地隐藏它们?

如果我们使用工厂模式,我们应该对用户隐藏产品吗?

这完全取决于消费者是否需要关心狗或猫,或者他们只需要一些动物?

也就是说,如果Animal.Speak()没问题,那么就只公开动物,而不让消费者知道实现细节。然而,如果有一些特定于dog的东西,比如Dog.BarkAtMoon(),那么你必须了解它是如何使用的。

此外,您可能希望依赖接口,例如IAnimal。然后你有一个类Dog: IAnimal,你的工厂返回IAnimals。这样,消费者对的了解就更少了,他们只知道接口。

也许你会有

class AnimalFactory
{
  IAnimal GetAnimal(AnimalTypeEnum type) { ... return IAnimal type requested ... }
  Dog GetDog(string name) { ... just give me a dog named "name" (or IDog) ... }
}

除了指出接口方面的其他答案之外,如果需要以某种方式构造复杂对象,并且希望在一个地方(即工厂)强制执行该需求,工厂模式也很有用。在这种情况下,最好也确保任何其他方式构建该对象,根据你的问题。

是的,如果您的对象应该只通过工厂创建,您应该尽量避免有人跳过此规则的可能性。

在c#中,如果Dog, Cat和Fish的消费者在不同的程序集中,你可以将构造函数设置为内部,这样只有在与你的"动物"相同的程序集中实现的工厂才能创建它们。

我相信java中也有类似的东西。

回答你的问题,是的。请允许我详细说明-

当我们直接实例化像Dog myDog = new Dog();这样的对象时,我们编写了一个依赖项。

现在让我们假设,您希望为您的函数编写一个单元测试用例,其中Dog被实例化,您将没有机会用模拟Dog对象替换实际的Dog对象。因此,我们坚持接口&从外部提供依赖。

如果我想强制使用Interface &防止使用new操作符,我可以做如下设置-

  1. 接口汇编-这将定义public interface IDog

  2. 用于具体实现的装配-这是有internal class Dog &Create函数返回IDogpublic class Factory

  3. 客户端程序集-这里Dog将不可访问,因此客户端创建dog实例的唯一方法将是通过工厂,它将返回IDogIDog dog = factory.Create();

我保持设置相当简单,只是为了传达我的观点

依赖倒置原则告诉我们客户端类应该避免依赖于具体的实现。工厂模式通过将客户端与创建逻辑隔离,从而简化了这一点,并且客户端将使用接口而不是某些具体类。使具体类的构造函数包局部而不是公共可能是一个好方法。