Джанго: Вопрос о модельной архитектуре
Выглядит ли этот код фасада хорошей идеей или в дизайне есть какие-то недостатки? Что еще более важно, есть ли проблема, с которой я, вероятно, столкнусь в будущем с этим кодом? Буду признателен за любую оказанную помощь.
Я пытаюсь построить это так, чтобы у меня был класс 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)
1 ответ
Не совсем понятно, к чему стремятся ваши классы "реализации", просто взглянув на код выше. Неясно, являются ли классы реализации еще одной моделью 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/ Если вам нужен объект, который может ссылаться на один из многих типов моделей, вы можете сделать это, используя общие отношения из "типов содержимого".