動的言語での継承とミックスイン?


19

動的言語のミックスインよりも継承パターンを好むのはいつですか?

ミックスインとは、実行時に関数とデータメンバーをオブジェクトに挿入する場合のように、実際に適切にミキシングすることを意味します。

たとえば、いつミックスインの代わりにプロトタイプ継承を使用しますか?mixinが意味することをより明確に説明するために、いくつかの疑似コードを示します。

asCircle(obj) {
  obj.radius = 0
  obj.area = function() {
    return this.radius * this.radius * 3.14
  }

myObject = {}
asCircle(myObject)
myObject.area() // -> 0

2
ミックスインは、まっすぐな継承というよりも横断的な側面に似ています。それはおそらくあなたのためにいくつかのユースケースを定義するでしょう。
ashes999

1
作曲、誰でも:)
OnesimusUnbound

回答:


14

プロトタイプの継承は簡単です。これには、ミックスインよりも1つの利点があります。

それはライブリンクだということです。プロトタイプを変更すると、プロトタイプを継承するすべてが変更されます。

pdを使用した例

var Circle = {
  constructor: function _constructor() {
    this.radius = 0;
    return this;
  },
  area: function _area() {
    return this.radius * this.radius * Circle.PI
  },
  PI: 3.14
};

var mixedIn = pd.extend({}, Circle).constructor();
var inherited = pd.make(Circle, {}).constructor();

Circle.perimeter = perimeter;

inherited.perimeter(); // wins
mixedIn.perimeter(); // fails

function perimeter() {
  return 2 * this.radius;
}

そのため、基本的に、「インターフェイス」サークルへの変更を、その機能を「使用する」すべてのオブジェクトに実行時に反映させたい場合は、継承します。

変更を反映させたくない場合は、混ぜてください。

ミックスインにはそれ以上の目的があることに注意してください。ミックスインは、複数の「継承」のメカニズムです。

オブジェクトに複数の「インターフェース」を実装させる場合は、いくつかを混在させる必要あります。プロトタイプ継承に使用するものは、実行時に変更を反映させたいもので、その他は混在させます。


12

私の馬の感覚はこれを教えてくれます:

  • 何かが有用である場合には全体で複数のオブジェクトまたはクラス階層-それのmixin作ります
  • 何かがある場合にのみ便利に沿って単一の階層にて -継承を使用する

関連ノート:

  • 「役に立つ」という言葉は比meta的に解釈されるべきです
  • 多重継承を持たない言語の場合、ミックスインは優れた代替手段です
  • PHP 5.4には、ミックスインと多重継承の両方の利点を備えた特性が導入されています

+ 1、Rubyでの「複数のオブジェクトまたはクラス階層にわたって有用なもの」の私のお気に入りの例はEnumerableモジュールです:ruby-doc.org/core-1.9.3/Enumerable.html
David

1
多重継承は、ミックスインに代わる(あまり良くない)選択肢になると思います。
サイモン

@Simonミックスインは、多重継承の(あまり良くない)代替手段になり得ると言うでしょう;)
Raynos

私の馬の感覚もこれを教えてくれました。:)
theringostarrs

9

「Is-a」テストを使用します。

継承は、「サブクラスはスーパークラスです」と言うことができる場合に限られます。それらは同じ種類のものです。「チーズは乳製品です」。

ミックスインは他のすべての用途に使用できます。「チーズはサンドイッチに使用できます」。チーズはサンドイッチではありませんが、サンドイッチに参加しています。

PS。これは動的言語とは関係ありません。静的コンパイルを使用する多重継承言語(C ++など)には、同じ決定ポイントがあります。


間違いなく+ 1-静的言語にもmixinがあります。
DeadMG

そうです、ミックスインは多くの言語で実行できます-これは私の質問ではありません。動的言語には、そのような言語でミックスインを異なるものにしたり、興味深いものにしたりする可能性のある特定のプロパティがあります-Raynosは1つの側面を指摘しました。さらに、mixinコンセプトよりもIS Aコンセプトを使用する必要がある特定の理由を指摘することはありません。
マグナスウルフフェルト

@MagnusWolffelt:それらは同じ種類のものです。「チーズは乳製品です」。それがIS-Aのルールです。これ以上何と言ったらいいですか?
S.Lott

私の質問は、設計の決定に関するものです。どのような状況で、どのような状況で継承が必要ですか?動的言語では、Raynosが説明したこと以外に、ミックスインよりも継承を選択する理由はほとんどありません。オブジェクト作成のパフォーマンスが理由の1つである可能性があります。
マグナスウルフフェルト

@MagnusWolffelt:「どのような状況で継承が必要ですか」2つのクラスがIS-A関係を満たす場合。「オブジェクト作成のパフォーマンス」は、どちらかを選択する理由ではありません。継承は、オブジェクトの2つのクラスについて非常に強力なステートメントを作成します。Mixinsは、より弱く、より柔軟なステートメントを作成します。2つのクラスが「IS-A」関係を満たす場合、継承が使用されます。これ以上何が言えますか?あなたの質問をよく理解できません。さらに知りたいことを明確にできますか?
S.Lott

0

まあ、私があなたにそれを与えることができる最良の例は、いくつかの基本的なものを継承しているが、共有機能のためにミックスイン / プラグインを使用するゲームのアクターです。共有機能は(ソースコードから直接!)

var plugins = {
    SingleVisualEntity : SingleVisualEntity,
    JumpBehaviour      : JumpBehaviour,
    WeaponBehaviour    : WeaponBehaviour,
    RadarBehaviour     : RadarBehaviour,
    EnergyGatherer     : EnergyGatherer,
    LifeBarPlugin      : LifeBarPlugin,
    SelectionPlugin    : SelectionPlugin,
    UpgradePlugin      : UpgradePlugin,
    BrainPlugin        : BrainPlugin,
    PlanetObjectPlugin : PlanetObjectPlugin,
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.