1

このファサードコードは良いアイデアのように見えますか、それともデザインに本質的に欠陥があるものがありますか?さらに重要なことに、このコードで将来遭遇する可能性のある問題はありますか?どんな助けでも大歓迎です。

これを構築して、ファサードとしてcc番号などを受け入れるPaymentクラスを作成し、実装として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()の呼び出しの前に来ます。これは、他のモデルに渡すときに、super()が適切に初期化されていない可能self.some_field性が高いことを意味します。self.account

2番目の落とし穴は、上記のように、2つのインスタンスに(おそらく、MyImplementationClassの記述方法に応じて)相互への循環参照が含まれるという事実にあります。これは、オブジェクトがスコープ外になったときに参照カウントが0にならないことを意味します。サイクリックGCは(おそらく)最終的にこれらのオブジェクトをガベージコレクションしますが、決定論的なガベージコレクションを失うことになります。これは(私の意見では)Pythonの非常に強力な機能です。


「一般的な関係」と呼ばれるものを実装しようとしているようです。これは、djangoのcontrib.contenttypesアプリによってすでに提供されている機能です:http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/# id1 多くのモデルタイプの1つを参照できるオブジェクトが必要な場合は、「contenttypes」の汎用リレーションを使用して行うことができます。

于 2010-01-06T22:54:05.300 に答える