banner
Rick Sanchez

Rick Sanchez

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

PythonにおけるMixinデザインパターン

image

1. Mixin デザインパターンとは#

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

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

したがって、飛行という行動を表現するためには、多重継承が必要です。しかし、そうすると、継承関係はis-aの原則に反することになります。

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

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

多重継承を使用する際には、設計が不適切になりやすく、継承チェーンが混乱し、mroの検索に影響を与える可能性があります。したがって、プログラミングの際の原則は、他の方法で多重継承を代替できる場合は、できるだけ多重継承を使用しないことです。

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


2. Mixin デザインパターンの例#

class Vehicle:
    pass

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

class Airplane(Vehicle, PlaneMixin):
    pass

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

上記のコードはこう理解できます。AirplaneVehicleクラスの一種であり、Planeクラスではありません。そして、Mixin接尾辞は、他の読者に対して、このクラスは機能を子クラスに追加するためのものであり、親クラスとしてではないことを示しています。その役割は Java のinterfaceに相当します。

こうすることで、複雑で巨大な継承チェーンを必要とせず、異なるクラスの機能を組み合わせるだけで、必要な子クラスを迅速に構築できます。


3. Mixin デザインパターンを使用する際の原則#

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

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

Java のインターフェースは、「仕様」の多重継承のみを提供します。Mixin クラスは「仕様」と「実装」の多重継承を同時に提供し、インターフェースに比べて使用が簡単です。


4. 補足#

他のフレームワークや言語にも、RubyDjangoVueReactなど、類似の Mixin 機能があります。

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