По-перше, слід зауважити, що міксини існують лише на мовах із багатонаступним успадкуванням. Ви не можете робити mixin на Java або C #.
В основному, міксин - це окремий базовий тип, який забезпечує обмежену функціональність та поліморфний резонанс для дитячого класу. Якщо ви думаєте на C #, подумайте про інтерфейс, який вам не потрібно реально реалізовувати, оскільки він уже реалізований; ви просто успадковуєте його і отримуєте користь від його функціональності.
Міксини, як правило, вузькі за обсягом і не повинні розширюватися.
[редагувати - щодо того, чому:]
Думаю, я повинен звернутися до цього питання, оскільки ви попросили. Велика перевага полягає в тому, що вам не доведеться робити це знову і знову. У C #, найбільше місце, де міксин може отримати користь, може бути від схеми утилізації . Щоразу, коли ви реалізуєте IDisposable, ви завжди завжди хочете дотримуватися тієї ж схеми, але ви закінчуєте писати та переписувати той самий базовий код з незначними варіаціями. Якщо був міксин для вивезення, який можна розширити, ви могли б заощадити багато додаткових текстів.
[редагувати 2 - відповісти на ваші інші запитання]
Що відокремлює міксин від багаторазового успадкування? Це просто питання семантики?
Так. Різниця між міксином та стандартним множинним успадкуванням - лише питання семантики; клас, який має багатократне успадкування, може використовувати міксин як частину цього багаторазового успадкування.
Суть міксину полягає в створенні типу, який можна "змішати" з будь-яким іншим типом шляхом успадкування, не впливаючи на тип успадкування, при цьому все ще пропонуючи певну корисну функціональність для цього типу.
Знову ж таки, подумайте про вже реалізований інтерфейс.
Я особисто не використовую комбінації, оскільки я розвиваюсь головним чином мовою, яка їх не підтримує, тому мені дуже важко придумати гідний приклад, який просто подасть це "аха!" момент для вас. Але я спробую ще раз. Я буду використовувати надуманий приклад - більшість мов уже так чи інакше надають цю функцію - але це, сподіваємось, пояснить, як міксини повинні створюватися та використовуватися. Ось:
Припустимо, у вас є тип, який ви хочете мати можливість серіалізувати до та з XML. Ви хочете, щоб тип надав метод "ToXML", який повертає рядок, що містить фрагмент XML зі значеннями даних типу, і "FromXML", що дозволяє типу реконструювати свої дані з фрагмента XML в рядку. Знову ж таки, це надуманий приклад, тому, можливо, ви використовуєте файловий потік або клас XML Writer з бібліотеки часу виконання вашої мови ... що завгодно. Справа в тому, що ви хочете серіалізувати свій об’єкт у XML та отримати новий об’єкт із XML.
Іншим важливим моментом у цьому прикладі є те, що ви хочете зробити це загальним способом. Вам не потрібно впроваджувати метод "ToXML" і "FromXML" для кожного типу, який ви хочете серіалізувати, ви хочете отримати деякі загальні засоби для того, щоб ваш тип зробив це, і він просто працює. Ви хочете повторно використовувати код.
Якщо ваша мова це підтримує, ви можете створити XmlSerializable mixin, щоб зробити вашу роботу за вас. Цей тип реалізує методи ToXML та FromXML. Використовуючи якийсь не важливий для прикладу механізм, він міг би зібрати всі необхідні дані з будь-якого типу, з яким він змішується, щоб створити фрагмент XML, повернутий ToXML, і він був би однаково здатний відновити ці дані, коли FromXML є називається.
І це все. Щоб використовувати його, у вас буде будь-який тип, який потрібно серіалізувати до спадщини XML від XmlSerializable. Щоразу, коли вам потрібно було серіалізувати або десеріалізувати цей тип, ви просто викликали б ToXML або FromXML. Насправді, оскільки XmlSerializable є повноцінним типом та поліморфним, ви могли б створити серіалізатор документів, який нічого не знає про ваш початковий тип, приймаючи, скажімо, масив типів XmlSerializable.
Тепер уявіть, як використовувати цей сценарій для інших речей, наприклад, для створення міксину, який гарантує, що кожен клас, який змішує його в журналах, кожен виклик методу, або міксин, який надає транзакційність типу, в який він змішується. Список можна продовжувати і продовжувати.
Якщо ви просто думаєте про міксин як про невеликий базовий тип, призначений для додавання невеликої кількості функціональності типу, не впливаючи інакше на цей тип, то ви золотий.
Сподіваємось. :)