2010-01-06 5 views
1

Этот код фасада выглядит как хорошая идея или есть что-то по своей сути ошибочное в дизайне? Что еще более важно, есть ли проблема, с которой я, вероятно, столкнусь с этим кодом? Буду признателен за любую оказанную помощь.Django: Вопрос о моделировании архитектуры

Я пытаюсь построить это, чтобы у меня был класс оплаты как мой фасад, который принимает номера 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) 

ответ

2

Не совсем ясно, какие цели «реализации» стремятся достичь, просто взглянув на код выше. Неясно, являются ли классы реализации еще одной моделью ORM или просто настраиваемым классом, который предоставляет метод save().

Пару gotchas только от скимания, что выше.

Линия:

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

приходит перед вызовом супер(), что означает, что весьма вероятно, self.some_field и self.account не инициализированы на момент передать его на другую модель.

Вторая полученная информация приходит в том, что, как написано выше, два экземпляра (вероятно, зависит от того, как написан MyImplementationClass) содержат циклические ссылки друг на друга. Это означает, что счетчик ссылок не будет равен 0, когда объекты выйдут из области видимости. Циклический GC (вероятно) в конечном итоге мусор собирает эти объекты, но вы теряете детерминированную сборку мусора, которая (на мой взгляд) является действительно мощной функцией Python.


Похоже, вы пытаетесь осуществить то, что известно как «родовое отношение», которая является характерной чертой уже предусмотрено приложением contrib.contenttypes Джанго: http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1 Если вы просто хотите, объект, который может относиться к одному из многих типы моделей, вы можете сделать это, используя общие отношения из «contenttypes».

+0

Можете ли вы уточнить, что счетчик ссылок на объекты не будет равен 0, и как это приведет к тому, что циклический GC не будет выполнять свою работу в ближайшее время. Означает ли это, что если у меня есть ссылка в self.impl фасада на модель реализации, то mem-модель модели реализации не будет GC после того, как я закончил использовать фасад? – orokusaki

+0

MyImplemenationClass - это модель ORM. – orokusaki

+0

Это зависит от того, что делает MyPaypalImplementation с его первым аргументом, аргументом my_facade_instance. Если вы делаете что-то вроде 'self.my_facade = my_facade_instance' внутри' MyPaypalImplementation .__ init__', тогда, когда оба объекта выходят из сферы действия (без выполнения ручного циклического разрыва) '.my_facade' укажет на экземпляр вашего фасада, а Свойство '.impl' фасада вернется к реализации. У обоих будет счетчик ссылок 1. Этот цикл будет * в конечном итоге * разбит на gc, но я не поклонник «в конце концов». – Crast

Смежные вопросы