2010-01-06 96 views
1

這個外觀代碼看起來是個好主意,還是設計中存在固有的缺陷?更重要的是,有沒有一個問題,我可能會遇到這個代碼在道路上?任何幫助深表感謝。Django:關於模型架構的問題

我試圖建立這個,這樣我可以有一個支付類作爲我的門面,它接受cc數字等,並將貝寶類作爲我的實現,以便我可以爲該卡充電並存儲有關該信息的信息等等。

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) 

回答

2

只是通過查看上面的代碼,您的「實現」類旨在實現的目標並不完全清楚。目前還不清楚實現類是否是另一個ORM模型,或者只是一個提供save()方法的自定義類。

只是略讀了上面的幾個問題。

行:

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

來調用超(),這意味着它極有可能self.some_fieldself.account不正確你將它傳遞給其他模型的時候初始化之前。

第二個問題出現在如上所述的事實中,這兩個實例將(可能取決於如何寫入MyImplementationClass)包含彼此的循環引用。這意味着當對象超出範圍時引用計數不會爲0。循環的GC將(可能)最終垃圾收集這些對象,但是你會失去確定性的垃圾收集,這在我看來是一個非常強大的Python特性。


您似乎在試圖實現了所謂的「通用的關係」,這是已被Django的contrib.contenttypes應用程序提供的功能:http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1如果你只是想要一個對象,它可以指很多之一模型類型,你可以通過使用「contenttypes」的通用關係來實現。

+0

您能否澄清一下對象引用計數不會變爲0,以及這將如何導致循環GC不能及時完成工作。這是否意味着如果我在Facade的self.impl中引用了實現模型,那麼在完成使用外觀之後,實現模型的mem將不會是GC? – orokusaki 2010-01-06 23:08:50

+0

MyImplemenationClass是一個ORM模型。 – orokusaki 2010-01-06 23:43:31

+0

這取決於MyPaypalImplementation對第一個參數my_facade_instance的作用。如果你在'MyPaypalImplementation .__ init__'內執行'self.my_facade = my_facade_instance',那麼當兩個對象超出範圍時(沒有執行手動循環中斷),'.my_facade'將指向你的外觀實例,門面的'.impl'屬性將指向實現。 兩者的引用計數都是1.這個循環最終會被gc打破,但我並不是「最終」的粉絲。 – Crast 2010-01-07 00:53:49