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

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

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

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

Історія

[ред. | ред. код]

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

Визначення

[ред. | ред. код]

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

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

Переваги

[ред. | ред. код]
  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, як спеціальні форми успадкування домішок.

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

[ред. | ред. код]

Крім 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!")
	}
}

Примітки

[ред. | ред. код]
  1. а б Using Mix-ins with Python
  2. Implementing Mix-ins with C# Extension Methods
  3. I know the answer (it's 42): Mix-ins and C#
  4. Boyland, John; Giuseppe Castagna (26 червня 1996). Type-Safe Compilation of Covariant Specialization: A Practical Case. У Pierre Cointe (ред.). ECOOP '96, Object-oriented Programming: 10th European Conference. Springer. с. 16—17. ISBN 9783540614395. {{cite book}}: |access-date= вимагає |url= (довідка)
  5. http://c2.com/cgi/wiki?MixIn [голе посилання]
  6. Working with Mixins in Ruby. 8 липня 2015.
  7. Re-use in OO: Inheritance, Composition and Mixins.
  8. Moving beyond mixins » Justin Leitgeb. Архів оригіналу за 25 вересня 2015. Процитовано 16 вересня 2015.
  9. OOPSLA '90, Mixin based inheritance (pdf)
  10. Bill Wagner. Create mixin types using default interface methods. docs.microsoft.com (амер.). Процитовано 18 квітня 2022.
  11. slava (25 січня 2010). Factor/Features/The language. concatenative.org. Процитовано 15 травня 2012. Factor's main language features: … Object system with Inheritance, Generic functions, Predicate dispatch and Mixins
  12. Alain Frisch (14 червня 2013). Mixin objects. LexiFi. Процитовано 29 березня 2022.
  13. Classes - MATLAB & Simulink - MathWorks India. Архів оригіналу за 18 червня 2021. Процитовано 7 березня 2023.
  14. Mixin Class Composition. École polytechnique fédérale de Lausanne. Процитовано 16 травня 2014.
  15. Mixin classes in XOTcl

Див. також

[ред. | ред. код]

Посилання

[ред. | ред. код]