Спадщина проти міксин в динамічних мовах?


19

Коли вам слід віддати перевагу моделям успадкування над комбінаціями в динамічних мовах?

Під mixins я маю на увазі фактичне правильне змішання, як при вставці функцій та членів даних в об’єкт під час виконання.

Коли ви використовували б, наприклад, прототипічне успадкування замість міксинів? Щоб більш наочно проілюструвати, що я маю на увазі під місіном, деяким псевдокодом:

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

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

2
Міксини більше схожі на наскрізні аспекти, ніж на пряме спадкування. Це, ймовірно, визначить деякі випадки використання для вас.
ashes999

1
Склад, хто
завгодно

Відповіді:


14

Прототипне успадкування просте. Він має єдину перевагу перед міксинами.

Це означає, що це пряма посилання. якщо змінити прототип, все, що його успадковує, буде змінено.

Приклад з використанням 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

Мій почуття коня говорить мені це:

  • Якщо щось корисне для кількох об'єктів або ієрархій класів - зробіть це міксином
  • Якщо що - то тільки корисно по одній ієрархії - використання успадкування

Пов'язані примітки:

  • Слово «корисний» слід сприймати метафорично
  • Для тих мов, які не мають багаторазового успадкування, міксини є хорошою альтернативою
  • PHP 5.4 вводить риси, які мають користь як з міксинів, так і з кількох світів спадкування

+1, мій улюблений приклад "чогось корисного для декількох об'єктів або ієрархій класів" у Ruby - це численний модуль: ruby-doc.org/core-1.9.3/Enumerable.html
Девід

1
Я б сказав, що багаторазове успадкування може бути (не настільки хорошою) альтернативою міксинам.
Саймон Берго

@Simon Я б сказав, що міксини можуть бути (не такою гарною) альтернативою багатократному успадкуванню;)
Raynos

Мій почуття коня мені теж сказав це. :)
theringostarrs

9

Скористайтеся тестом "Is-a".

Спадщина обмежується випадком, коли можна сказати "Підклас - це суперклас". Вони однакові речі. "Сир - молочний продукт".

Міксини - для всього іншого. "Сир можна вживати в бутерброді". Сир - це не сендвіч, але він бере участь у сендвічі.

PS. Це не має нічого спільного з динамічними мовами. Будь-яка декілька мов успадкування зі статичною компіляцією (тобто C ++) має однаковий пункт рішення.


Однозначно + 1– статичні мови теж мають міксин.
DeadMG

Правильно, міксин можна робити багатьма мовами - це не було моїм питанням. Динамічні мови мають певні властивості, які можуть або не можуть зробити комбінації різними та / або більш цікавими в таких мовах - Райнос вказав на один аспект. Крім того, ви не вказуєте жодних конкретних причин, чому слід використовувати концепцію IS A над концепцією mixin.
Магнус Вольфельт

@MagnusWolffelt: Вони однакові речі. «Сир - молочний продукт». Це правило для IS-A. Що ще я повинен сказати?
S.Lott

Моє питання більше стосується дизайнерських рішень - в яких ситуаціях ви хочете отримати спадщину та з яких причин? У динамічних мовах я бачу мало причин для отримання спадку над міксинами, окрім того, що описав Райнос. Продуктивність створення об'єкта може бути однією з причин.
Магнус Вольфельт

@MagnusWolffelt: "в яких ситуаціях ти хочеш успадкування", коли два класи задовольняють відносини IS-A. "Продуктивність створення об'єкта" не є підставою для вибору одного над іншим. Спадкування робить дуже сильне твердження про два класи об’єктів. Мікінс робить слабкіше і гнучкіше твердження. Спадкування використовується тоді, коли два класи задовольняють співвідношення "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,
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.