Топ питань
Часова шкала
Чат
Перспективи

Домішка (програмування)

З Вікіпедії, вільної енциклопедії

Remove ads

В об'єктно-орієнтованих мовах програмування домішка (англ. mixin)[1][2][3] — це клас, який містить методи для використання іншими класами без необхідності бути батьківським класом для них. Те, як ці інші класи отримують доступ до методів домішки залежить від мови. Іноді домішки описують як «включені», а не як «успадковані».

Домішки заохочують повторне використання коду, і їх можна використовувати для уникнення неоднозначності успадкування, яку може спричинити множинне успадкування[4] (" проблема алмазу "), або для усунення відсутності підтримки множинного успадкування в мові. Домішку також можна розглядати як інтерфейс із реалізованими методами . Цей шаблон є прикладом застосування принципу інверсії залежностей .

Remove ads

Історія

Домішки вперше з'явилися в Symbolics об'єктно-орієнтованій Flavors системі (розробленій Говардом Кенноном), яка була підходом до об'єктної орієнтації, використаним у Lisp Machine Lisp . Назву було навіяно кафе-морозиво Steve's Ice Cream Parlor у Сомервіллі, штат Массачусетс:[1] власник магазину морозива запропонував основний смак морозива (ваніль, шоколад тощо) і змішав комбінацію додаткових продуктів (горіхи, печиво, помадка тощо) і назвав продукт " mix-in ", його власний термін торгової марки на той час.

Remove ads

Визначення

Домішки — це концепція мови, яка дозволяє програмісту вставляти код у клас . Програмування домішок — це стиль розробки програмного забезпечення, у якому функціональні одиниці створюються в класі, а потім змішуються з іншими класами.[5]

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

Remove ads

Переваги

  1. Він забезпечує механізм множинного успадкування, дозволяючи одному класу використовувати спільну функціональність кількох класів, але без складної семантики множинного успадкування.[6]
  2. Багаторазове використання коду: домішки корисні, коли програміст хоче поділитися функціями між різними класами. Замість того, щоб повторювати один і той самий код спільну функціональність можна просто згрупувати в домішку, а потім включити в кожен клас, який цього вимагає.[7]
  3. Домішка дозволяє успадковувати та використовувати лише бажані функції з батьківського класу, а не всі.[8]

Реалізації

Узагальнити
Перспектива

У Simula класи визначені в блоці, в якому атрибути, методи та ініціалізація класу визначені разом; Таким чином, усі методи, які можуть бути викликані в класі, визначені разом, і визначення класу завершено.

У Flavors домішка— це клас, від якого інший клас може успадковувати визначення та методи слотів. Домішка зазвичай не має прямих екземплярів. Оскільки Flavor може успадкувати від кількох інших Flavor, він може успадкувати від однієї або кількох домішок. Зауважте, що оригінальні Flavor не використовували загальні функції.

У New Flavors (спадкоємець Flavors) і CLOS методи організовані в " загальних функціях ". Ці загальні функції — це функції, які визначені в кількох випадках (методах) за допомогою класової диспетчеризації та комбінацій методів.

CLOS і Flavors дозволяють методам домішки додавати поведінку до існуючих методів: :before і :after daemons, whoppers і wrappers у Flavors. CLOS додав :around методи і можливість викликати тіньові методи через CALL-NEXT-METHOD . Так, наприклад, stream-lock-mixin може додати блокування навколо існуючих методів класу потоку. У Flavors можна було б написати wrapper або whopper, а в CLOS можна було б використовувати метод :around . І CLOS, і Flavors дозволяють обчислюване повторне використання за допомогою комбінацій методів. :before, :after і :around є ознакою стандартної комбінації методів. Надаються інші комбінації методів.

Прикладом є + метод комбінації, де результуючі значення кожного з застосовних методів загальної функції додаються арифметично для обчислення поверненого значення. Це використовується, наприклад, з border-mixin для графічних об'єктів. Графічний об'єкт може мати загальну функцію ширини. Border-mixin додає рамку навколо об'єкта та має метод обчислення його ширини. Новий клас bordered-button (який одночасно є графічним об'єктом і використовує домішку border) обчислюватиме свою ширину, викликаючи всі застосовні методи ширини — за допомогою + методу комбінації. Усі повернуті значення додаються та створюють комбіновану ширину об'єкта.

У статті OOPSLA 90[9] Гілад Брача та Вільям Кук переосмислюють різні механізми успадкування, знайдені в Smalltalk, Beta та CLOS, як спеціальні форми успадкування домішок.

Remove ads

Мови програмування, які використовують домішки

Узагальнити
Перспектива

Крім Flavors і CLOS (частина Common Lisp), деякі мови, які використовують домішки:

Деякі мови не підтримують домішки на рівні мови, але можуть легко імітувати їх, копіюючи методи з одного об'єкта в інший під час виконання, таким чином «позичаючи» методи домішок. Це також можливо зі статично типізованими мовами, але це вимагає створення нового об'єкта з розширеним набором методів.

Інші мови, які не підтримують домішки, можуть підтримувати їх обхідним шляхом через інші мовні конструкції. Наприклад, Visual Basic. NET і C# підтримують додавання методів розширення до інтерфейсів, тобто будь-який клас, що реалізує інтерфейс із визначеними методами розширення, матиме методи розширення, доступні як псевдо-члени.

// Allows for types to "speak"
trait Speak {
	fn speak();

	// Rust allows implementors to define default implementations for functions defined in traits
	fn greet() {
		println!("Hi!")
	}
}

struct Dog;

impl Speak for Dog {
	fn speak() {
		println!("Woof woof");
	}
}

struct Robot;

impl Speak for Robot {
	fn speak() {
		println!("Beep beep boop boop");
	}

	// Here we override the definition of Speak::greet for Robot
	fn greet() {
		println!("Robot says howdy!")
	}
}
Remove ads

Примітки

Див. також

Посилання

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads