banner
Rick Sanchez

Rick Sanchez

OS && DB 爱好者,深度学习炼丹师,蒟蒻退役Acmer,二刺螈。

PythonのMixinデザインパターン

image

1. ミックスインデザインパターンとは#

ミックスインデザインパターンは、多重継承の一種と見なすことができます。まず、なぜこのような構文の多重継承が生じるのかについて話しましょう。

車と飛行機はどちらも交通手段に属していますが、飛行機は飛ぶことができますが、車はできません。したがって、飛行という行動は「交通手段」というクラスに書くことはできません。各交通手段がそれぞれ独自の走行方法を実装すると、コードの再利用性の原則に反します(交通手段の種類が増えるにつれて、大量のコードの重複が発生します)。

したがって、私たちは「飛行」という行動を表すために、多重継承を行う必要があります。しかし、これにより継承関係が「is-a」の原則に反します。

Java では、多重継承はありませんが、interfaceを使用して多重継承を実現することができます。

Python では、interfaceという構文はありませんが、多重継承をサポートしています。

多重継承を使用する際には、設計ミスが発生しやすく、継承チェーンが混乱し、mroの検索に影響を与える可能性があるため、プログラミングの際には、「多重継承の代わりに他の方法を使用できる場合は、できるだけ多重継承を使用しない」という原則を守る必要があります。

このような場合、Mixinデザインパターンが登場します。Mixinは、直訳すると「混入、追加」という意味であり、多重継承の一種です。多重継承では、検索の順序はmroの継承チェーンの順序に従って行われます。


2. ミックスインデザインパターンの例#

class Vehicle:
    pass

class PlaneMixin:
    def fly(self):
        print("飛行中")

class Airplane(Vehicle, PlaneMixin):
    pass

上記のコードでは、Airplaneクラスが多重継承を実装しており、継承チェーン上ではVehicleクラスとPlaneMixinクラスを継承しています。ここでは、Mixinデザインパターンの要件に従い、接尾辞にMixinを追加してコードの可読性を向上させています。

上記のコードは次のように理解することができます。Airplaneは単なるVehicleクラスであり、Planeクラスではありません。そして、Mixinの接尾辞は、他の読者に対して、このクラスが子クラスに機能を追加するためのものであり、親クラスではないことを伝えます。その役割は Java のinterfaceと同等です。

これにより、複雑で大規模な継承チェーンを持つ必要はなく、異なるクラスの機能を組み合わせるだけで、必要なサブクラスを迅速に構築することができます。


3. ミックスインデザインパターンの原則#

Mixinデザインパターンを使用して多重継承を実現する際には、次の原則に特に注意する必要があります:

  • まず第一に、Mixin クラスはある機能を表す必要があり、ある物体を表すものではありません。これは Java のRunnableCallableと同じです。
  • 次に、Mixin クラスが表す責任は単一でなければなりません。複数の機能がある場合は、複数のMixinクラスを実装する必要があります。
  • さらに、Mixin クラスは子クラスの実装に依存せず、抽象クラスであり、自体をインスタンス化することも、Mixin 以外のクラスを継承することもできません。
  • 最後に、子クラスは Mixin クラスを継承していなくても正常に動作する必要がありますが、一部の機能が欠落して使用できない場合があります。

Java のインターフェースは、「仕様」の多重継承のみを提供しています。Mixin クラスは「仕様」と「実装」の両方の多重継承を提供し、使用上はインターフェースよりも簡単です。


4. 追加情報#

他のフレームワークや言語でも、同様の Mixin 機能があります。例えば、RubyDjangoVueReactなどです。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。