这个外观代码看起来是个好主意,还是设计上存在任何固有的缺陷?更重要的是,有一个问题,我可能会遇到这个代码吗?非常感谢任何帮助。
我正在尝试构建这个,以便我可以将Payment类作为我的外观,它接受cc数字等,并将PayPal类作为我的实现,这样我就可以为卡充电并存储有关的信息,等
class MyFacadeClass(models.Model):
account = models.ForeignKey('Account') # Account omitted from example for brevity.
implementation = CharField(max_length=255, choices=IMPL_CHOICES) # IMPL_CHOICES omitted for brevity
some_field = models.CharField(max_length=255)
def __init__(self, *args, **kwargs):
super(MyFacadeClass, self).__init__(*args, **kwargs)
if self.implementation == 'PAYPAL':
from somewhere import MyPayPalImplementationModelClass
self.impl = MyPayPalImplementationModelClass(my_facade_instance=self, some_field=self.some_field, account=self.account)
# Then MyPayPalImplementationModelClass does stuff with PayPal and has its own attributes such as ack, and datetime and fee_amount behind the scenes.
def save(self, force_insert=False, force_update=False)
if self.impl.is_valid():
self.impl.save()
super(MyFacadeClass, self).save(force_insert, force_update)
答案 0 :(得分:2)
通过查看上面的代码,您的“实现”类的目标并不完全清楚。目前还不清楚实现类是否是另一个ORM模型,或者只是一个提供save()方法的自定义类。
通过略读上述内容,可以解决几个问题。
该行:
self.impl = MyImplementationClass(my_facade_class_instance=self, some_field=self.some_field, account=self.account)
在调用super()之前出现,这意味着很有可能self.some_field
和self.account
在您将其传递给其他模型时未正确初始化。
第二个问题是,如上所述,这两个实例(可能取决于MyImplementationClass的编写方式)是否包含彼此的循环引用。这意味着当对象超出范围时,引用计数不会为0。循环GC将(可能)最终垃圾收集这些对象,但你会失去确定性的垃圾收集,这在我看来是Python的一个非常强大的功能。
您似乎正在尝试实现所谓的“通用关系”,这是django的contrib.contenttypes应用程序已经提供的功能:http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1如果您只想要一个可以引用其中一个的对象模型类型,您可以使用“contenttypes”中的泛型关系来实现。