1

这个外观代码看起来是个好主意,还是设计本身有什么缺陷?更重要的是,我可能会在这段代码中遇到问题吗?任何帮助深表感谢。

我正在尝试构建它,以便我可以有一个 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)
4

1 回答 1

2

仅通过查看上面的代码,还不清楚您的“实现”类的目标是什么。目前尚不清楚实现类是另一个 ORM 模型,还是只是提供 save() 方法的自定义类。

浏览上面的内容有几个问题。

该行:

self.impl = MyImplementationClass(my_facade_class_instance=self, some_field=self.some_field, account=self.account)

出现在对 super() 的调用之前,这意味着它很可能在您将它传递给另一个模型self.some_fieldself.account没有正确初始化。

第二个问题在于,如上所述,两个实例将(可能取决于 MyImplementationClass 的编写方式)包含对彼此的循环引用。这意味着当对象超出范围时引用计数不会为 0。循环 GC(可能)最终会垃圾收集这些对象,但您会失去确定性垃圾收集,这(在我看来)是 Python 的一个非常强大的特性。


看来您正在尝试实现所谓的“通用关系”,这是 django 的 contrib.contenttypes 应用程序已经提供的功能:http: //docs.djangoproject.com/en/dev/ref/contrib/contenttypes/# id1 如果您只想要一个可以引用多种模型类型之一的对象,您可以使用“contenttypes”中的通用关系来实现。

于 2010-01-06T22:54:05.300 回答