Factory method for objects - best practice?
这是一个关于使用Python从同一数据的不同形式创建类或类型实例的最佳实践的问题。使用类方法更好还是使用单独的函数更好?假设我有一个用来描述文档大小的类。(注:这只是一个例子。我想知道创建类实例的最佳方法,而不是描述文档大小的最佳方法。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | class Size(object): """ Utility object used to describe the size of a document. """ BYTE = 8 KILO = 1024 def __init__(self, bits): self._bits = bits @property def bits(self): return float(self._bits) @property def bytes(self): return self.bits / self.BYTE @property def kilobits(self): return self.bits / self.KILO @property def kilobytes(self): return self.bytes / self.KILO @property def megabits(self): return self.kilobits / self.KILO @property def megabytes(self): return self.kilobytes / self.KILO |
我的
1 2 3 4 5 6 7 8 9 10 11 12 | class Size(object): """ Utility object used to describe the size of a document. """ BYTE = 8 KILO = 1024 @classmethod def from_bytes(cls, bytes): bits = bytes * cls.BYTE return cls(bits) |
或
1 2 3 | def create_instance_from_bytes(bytes): bits = bytes * Size.BYTE return Size(bits) |
这似乎不是一个问题,也许这两个例子都是有效的,但每次我需要实现类似的东西时,我都会考虑到这一点。很长一段时间以来,我更喜欢课堂教学法,因为我喜欢把课堂教学法和工厂教学法结合起来的组织效益。此外,使用类方法可以保留创建任何子类的实例的能力,因此它更面向对象。另一方面,一位朋友曾经说"当有疑问时,做标准库所做的事情",我还没有在标准库中找到这样一个例子。
首先,大多数时候你认为你需要这样的东西,但你没有;这是一个标志,你试图像Python那样对待Python,解决的办法是退后一步,问问你为什么需要一个工厂。
通常,要做的最简单的事情就是使用带有默认/可选/关键字参数的构造函数。甚至在Java中,即使是超载的构造函数会在C++或Objc中感觉错误的情况下,也可能在Python中看起来完全是自然的。例如,
1 | def __init__(self, *, bits=None, bytes=None, kilobits=None, kilobytes=None): |
或:
1 2 | BITS, BYTES, KILOBITS, KILOBYTES = 1, 8, 1024, 8192 # or object(), object(), object(), object() def __init__(self, count, unit=Size.BITS): |
但是,有时您确实需要工厂功能。那么,你会怎么做?嗯,有两种东西经常被归为"工厂"。
函数是执行"我不关心实际类是什么"工厂的惯用方法。看看,例如,内置的
您给出的示例似乎是一个完全合法的用例,并且非常清楚地适合"备用构造函数"bin(如果它不适合"带有额外参数的构造函数"bin)。