23

我目前正在用 Python 实现工厂设计模式,我有几个问题。

  1. 有什么方法可以防止直接实例化实际的具体类?例如,如果我有一个生成 Vehicles 的 VehicleFactory,我希望用户只使用该工厂,并防止任何人意外地直接实例化 Car() 或 Truck()。我也许可以在init ()中抛出异常,但这也意味着工厂无法创建它的实例......

  2. 现在在我看来,工厂越来越让人上瘾。似乎一切都应该成为工厂,这样当我更改内部实现时,客户端代码不会改变。我很想知道什么时候需要使用工厂,什么时候不适合使用。例如,我可能有一个 Window 类,而现在只有一个这种类型(没有 PlasticWindow、ReinforcedWindow 或类似的东西)。在这种情况下,我是否应该为客户端使用工厂来生成 Window,以防我将来可能添加更多类型的 Windows?

  3. 我只是想知道是否有一种通常的方式来调用工厂。例如,现在我将我的 Vehicle 工厂称为 Vehicles,因此代码将类似于 Vehicles.create(...)。我看到很多教程都在做类似 VehicleFactory 的教程,但我发现它太长了,而且有点暴露了实现。

编辑:我所说的“公开实施”的意思是它让人们知道它是一个工厂。我的感觉是客户不需要知道它是一个工厂,而是作为一个可以为你返回对象的类(这当然是一个工厂,但也许没有必要明确告诉客户?)。我知道源代码很容易暴露,所以我的意思不是“暴露源代码中实现功能的方式”。

谢谢!

4

3 回答 3

23

成为 Pythonic。不要使用添加不必要的抽象级别的“企业”语言(如 Java)解决方案使您的代码过于复杂。

您的代码应该简单、直观。您不需要委托给另一个类来实例化另一个类。

于 2010-08-18T10:39:15.610 回答
12
  1. 不要公开该类(例如将其设为私有__MyClass,或明显不想直接使用它_MyClass)。这种方式只能通过工厂函数实例化。
  2. 也许您应该回顾一下关键字参数的使用和继承。听起来你可能忽略了这些,这通常会减少你对复杂工厂的依赖(说实话,我很少需要工厂)。
  3. 在 Python 中,你不能轻易地防止暴露实现,它违背了Python 的禅宗。(在任何语言中都是一样的,一个有决心的人最终会得到他们想要的)。至多你应该尽量确保你的代码的用户不会意外地做错事,但永远不要假设知道最终用户可能决定用你的代码实现什么。不要让它混淆和难以使用。
于 2010-08-18T10:31:54.287 回答
6

有什么方法可以防止直接实例化实际的具体类?

为什么?你的程序员是拒绝遵守规则的邪恶反社会者吗?如果你提供一个工厂——并且工厂做人们需要的事情——那么他们就会使用工厂。

你不能“阻止”任何事情。记住。这是 Python——他们有源代码。

我应该为客户端使用工厂来生成窗口,以防我将来添加更多类型的窗口吗?

嗯。不好也不坏。管理所有类层次结构和工厂细节可能会很麻烦。

添加工厂并不难。这就是 Python——你随时拥有所有源代码——你可以使用它grep来查找类构造函数,并在需要时将其替换为工厂。

由于您可以使用它grep来查找和修复错误,因此您无需像在 Java 或 C++ 中那样预先计划此类事情。

我看到很多教程都在做类似 VehicleFactory 的教程,但我发现它太长了,而且有点暴露了实现。

“太长”?它很少使用,几乎不重要。使用长名称——它可以帮助其他人理解你在做什么。这不是最少击键获胜的 Code Golf。

“公开实施”?首先,它什么也不暴露。其次,这是 Python——你随时都有所有的源代码——一切都已经暴露了。

不要再想太多关于预防和隐私的事情了。这没有帮助。

于 2010-08-18T11:00:24.780 回答