что значит миксины в манге
Миксины для “классов” в JavaScript
Одинаковый код в нескольких местах — это боль. Сегодня я напишу пару слов про повторяющиеся куски классов. Люди давно придумали решение — можно вынести одинаковые методы и свойства в общий базовый класс, а если такового нет — использовать примеси. Существует миллион реализаций данного паттерна для JavaScript, я хочу детально остановиться на подходе, когда миксин попадает в цепочку наследования.
Проблема в картинках
Начнем с визуализации нашей проблемы. Допустим у нас есть два базовых класса и от них наследуются два дочерних класса.
В какой-то момент в дочерних классах появляется необходимость в одинаковом функционале. Обычная копипаста будет выглядеть на нашей схеме вот так:
Очень часто бывает, что данный функционал не имеет ничего общего с родительскими классами, поэтому выносить его в какой-то базовый класс нелогично и неправильно. Вынесем его в отдельное место — миксин. С точки зрения языка миксин может быть обычным объектом.
А теперь обсудим момент, ради которого написана вся статья — как правильно замешивать наш миксин в классы.
Исходя из собственного опыта, могу заявить, что самый удобный способ — это создание временного класса на основе миксина и подстановка его в очередь наследования.
Плюсы данного подхода
Пишем код
Во всех последующих примерах будет использоваться конкретная реализация — библиотека Backbone.Mix. Посмотрев код, вы обнаружите, что он чрезвычайно прост, поэтому вы можете легко адаптировать его для своего любимого фреймворка.
Давайте посмотрим, как применять миксины, встраивающиеся в цепочку наследования, в реальной жизни и прочувствуем плюсы данного подхода на практике. Представьте, что вы пишете сайт )) и на вашем сайте есть разные штуки, которые можно закрывать — попапы, хинты и т.п. Все они должны слушать клик по элементу с CSS классом close и скрывать элемент. Миксин для этого может выглядеть так:
Вмешиваемся.
Довольно просто, не правда ли? Теперь наша цепочка наследования выглядит так:
Здесь и далее в примерах используется библиотека backbone-super
Примеси, которые не мешают..
… а помогают. Бывает замес выходит не хилый, и одним миксином не обойтись. Например, представьте что мы — крутые пацаны, и пишем лог в IndexedDB, а еще у нас для этого свой миксин — Loggable 🙂
Тогда к попапу мы будем мешать уже два миксина:
Синтаксис вроде не сложный. На схеме это будет выглядеть так:
Как видите, цепочка наследования выстроится в зависимости от порядка подключения миксинов.
Зависимые миксины
А теперь представьте ситуацию, что к нам подходит наш аналитик и сообщает, что хочет собирать статистику по всем закрытиям попапов, хинтов — всего, что может закрываться. Конечно же, у нас давно есть миксин Trackable для таких случаев, с того времени, как мы делали регистрацию на сайте.
И в цепочке наследования Trackable должен оказаться раньше, чем Closable :
Код для миксинов с зависимостями немного усложнится:
Документируй миксины правильно
На этом, пожалуй всё, счастливого вмешивания!
Звуковые эффекты в манге
Устройство японских звуковых слов
Обратимся теперь к основным принципам японской ономатопеи. Все слова-звуки делятся на 3 семейства и 5 классов. Семейства группируют слова по звукам, которым они подражают, а классы – по морфемной структуре, то есть тому, как слова выглядят с точки зрения словообразования. Кстати, такие классы и семейства можно выделить почти в любом языке, в том числе и в русском. Давайте вначале рассмотрим семейства, прежде чем углубиться в технические подробности классов.
Перейдем к классам. Существует пять классов, разделяющих слова по их структуре.
Корневые слова – образованные отбрасыванием всех морфем и оставлением одного корня. На примере слова учится – настоящее время, учить – неопределенная невозвратная форма, уч – корень. Мы выбрасываем суффиксы и окончание и остается лишь минимальная смысловая единица – корень.
В японском: hanashimasu, ханасимасу (говорю) –> hanasu, ханасу (говорить) –> hana, хана (корень)
Японские звукоподражания из этого класса используют корни, такие как hana.
Вариативный повтор – слова, образованные повторением первой своей части с небольшими изменениями. Например, тик-так в русском языке. ガサゴソ gasa-goso, гаса-госо (дребезжание).
Повтор основания – повторяется основная часть звука, а начало слова может немного отличаться. К примеру, тра-та-та.
Простой повтор – повторение безо всяких изменений. В русском тук-тук. コロコロ korokoro, корокоро (звук чего-то катящегося). Это самый распространенный класс слов.
Прочее – все то, что не подошло ни под одну из остальных категорий.
Вы можете задать вопрос: а зачем мне это знать? Знание классов поможет вам во время чтения определить, является ли слово звукоподражанием или нет. Слова-звуки могут иметь «степени сравнения», и классы покажут вам связь между родственными словами:
ハタハタ hatahata, хатахата – звук треплющейся на ветру ткани или другой материи.
パタパタ patapata, патапата – ветер подул сильнее, чем в hatahata.
バタバタ batabata, батабата – ветер дует еще сильнее, чем в patapata.
Все три слова образованы простым повтором и имеют одно и то же повторяющееся основание (ata). Это, наверное, излишние технические детали, но они могут вам пригодиться.
ギュアアッ – gyuaa, гюа
Слова, обозначающие состояния и чувства
Явление gitaigo не уникально для японского, оно существует и в других языках. В английском grin, gaze, wink, примерные аналоги в русском языке ухмыляться, глазеть. Усиление эффекта, который производит слово, возникает из-за литературного консонанса, повторения согласных или гласных звуков, акцентирующих внимание на слове. Один из самых известных примеров gitaigo じーっ jii, дзи, что означает «уставиться, глазеть» и часто используется вместе с персонажем, который пристально смотрит на другого персонажа или читателя. Gitaigo стали неотемлимой частью художественного языка аниме. Эти слова не стоит читать, их нужно просто «видеть». В японском языке они широко распространены и используются в повседневном общении, поэтому неудивительно, что они встречаются в аниме и манге.
Слова, описывающие внутренние переживания или физическое состояние, помогают нам судить о том, что испытывает персонаж в данный момент. В манге невозможно описать чувства так, как это можно сделать в книге, ведь в книгах мы часто поставлены на место персонажа и видим мир его глазами. В манге все наоборот: мы являемся сторонним наблюдателем. Gitaigo позволяет авторам избавиться от неясностей в душевном состоянии героев.
Вот несколько примеров применения gitaigo в разговорном японском.
イライラ ira ira, ира-ира
Образовано от слова ira, что переводится как «колючка». Используется для выражения чувства недовольства и раздражения.
Пример:
試験勉強が思うように進まずイライラする。
Shiken benkyō ga omou yō ni susumazu ira ira suru.
Сикэн бэнкё га омоу ё ни сусумадзу ира ира суру.
Я беспокоюсь, потому что моя подготовка к экзаменам идет не так хорошо, как я думал.
ピカピカ pika pika, пика-пика
Блестящий, сверкающий.
Пример:
靴をピカピカに磨いて会社に行く。
Kutsu wo pika pika ni migaite kaisha ni iku.
Куцу о пика пика ни мигаитэ каися ни ику.
Я полирую свои ботинки до блеска перед тем как пойти на работу.
ワクワク waku waku, ваку-ваку
Происходит от глагола waku, который используется для того чтобы описать извержение воды из гейзера, значение сходно с таковым у глагола фонтанировать. Выражение используется для обозначения чувства радости и нетерпения в связи с ожиданием какого-либо события.
Пример:
彼女が留学を終え、帰ってくる。ワクワクしながら空港に迎えに行った。
Kanojo ga ryūgaku wo oe, kaette kuru. Waku waku shinagara kūkō ni mukae ni itta.
Канодзё га рюгаку о оэ, каэттэ куру. Ваку ваку синагара куко ни мукаэ ни итта.
Моя девушка училась по обмену за границей, и сейчас летит домой. Когда я поехал в аэропорт, меня охватило радостное возбуждение в предвкушении встречи с ней.
Waku waku
ふわふわ fuwa fuwa, фува-фува (произносится скорее как фуа-фуа)
Мягкий, пушистый и легкий. Также используется для описания предмета, который легко парит в воздухе, как перышко или тополиный пух.
Пример:
青空に白い雲がふわふわ浮いている。
Aozora ni shiroi kumo ga fuwa fuwa uiteiru.
Аодзора ни сирои кумо га фува фува уитеиру.
Белые невесомые облака плывут по голубому небу.
Fuwa fuwa
ニコニコ niko niko, нико-нико
Радостно улыбаться.
Пример:
何かいいことがあったのか、きょうの上司は終始ニコニコ顔だ。
Nani ka ii koto ga atta no ka, kyō no jōshi wa shūshi niko niko gao da.
Нани ка и кото га атта но ка, кё но дзёси ва сюси нико нико гао да.
Что с моей начальницей? Она весь день просто сияет от счастья!
Niko niko
ぺこぺこ peko peko, пэко-пэко
Чувствовать голод или быть подобострастным. Считается измененной формой глагола hekomu, хэкому, что означает «опустеть».
Примеры:
お腹がぺこぺこで集中できない。
Onaka ga peko peko de shūchū dekinai.
Онака га пэко пэко дэ сютю дэкинаи.
Я голоден, поэтому не могу сосредоточиться.
社長にペコペコする。
Shachō ni peko peko suru.
Сятё ни пэко пэко суру.
Стелиться подстилкой перед президентом компании.
ドキドキ doki doki, доки-доки
Учащенное сердцебиение, вызванное радостью, волнением, страхом или удивлением.
Пример:
試験結果発表の日、不安で心臓がドキドキした。
Shiken kekka happyō no hi, fuan de shinzō ga doki doki shita.
Сикэн кэкка хаппё но хи, фуан дэ синзо га доки доки сита.
В день объявления результатов экзаменов я так разволоновался, что сердце стучало в ушах.
ペラペラ pera pera, пэра-пэра
Бегло говорить (на иностранном языке).
Пример:
彼は英語がペラペラだ。
Kare wa eigo ga pera pera da.
Карэ ва эиго га пэра пэра да.
Он хорошо говорит по английски.
Pera pera
Сбивающая с толку многозначность
Серьезным препятствием на пути к пониманию ономатопических выражений может стать их гибкость и наличие большого количества разноообразных толкований. Например, знаменитое goro goro может означать все что угодно, начиная от урчания или грома и заканчивая ленивым покатыванием по полу.
Эта табличка ни в коем случае не содержит полный список ономатопеи, но она позволит вам ознакомиться со значениями наиболее часто использующихся в манге слов3. В таблице используются как катакана, так и хирагана, и дается транскрипция по Хэпбёрну и Поливанову, а также примерный перевод на русский.
Gitaigo выделены жирным шрифтом. Список отсортирован по знакам каны, поэтому вам не составит труда найти фразу по ее первой букве[4].
Миксины
Царство: | Животные |
Тип: | Хордовые |
Класс: | Круглоротые |
Отряд: | Миксинообразные |
Семейство: | Миксиновые |
Микси́новые (лат. Myxinidae ) — семейство позвоночных класса круглоротых. Длина тела — 45—70 см. Непарная ноздря расположена на конце головы и сообщается с глоткой. Рот и ноздря обрамлены 6—8 мясистыми усиками. Жаберных мешков — 5—15 пар; у одних видов каждый мешок сообщается с глоткой и наружной средой, у других — они открываются с каждой стороны общим отверстием. Жаберный скелет состоит из небольшого числа хрящевых пластинок. Кровеносная система незамкнутая, имеется основное сердце и 3 дополнительных. Глаза затянуты кожей; светочувствительные клетки располагаются также вокруг клоаки. Один отряд с 1 семейством (около 15 видов); распространены в умеренных и субтропических водах Мирового океана. Откладывают 20—30 крупных овальных яиц (размером 18—20 мм). В России европейская миксина (или миксина обыкновенная, Myxine glutinosa) изредка встречается в Баренцевом море. Миксины — хищники, выедают внутренности и мышцы у ослабевших рыб, вгрызаясь в жертву с помощью мощного языка с роговыми зубцами; реже питаются червями. Производят огромное количество слизи на поверхности тела. Будучи схваченными, например за хвост, миксины способны завязываться в узел, которым они упираются в нападающего и перемещая узел вдоль тела к хвосту, а также благодаря выделяемой слизи, высвобождаются из захвата. Очень живучи, хорошо переносят длительное пребывание без воды, могут подолгу голодать и долго остаются живыми, получив даже чрезвычайно тяжелые ранения. Описан случай, когда она продолжала плавать через пять часов после того, как была обезглавлена. Использование примесей (mixins) в DartНесколько раз от коллег звучал вопрос о том, что не понятно, зачем вообще нужны mixin’ы (примеси) в языке Dart. Я решил посмотреть, что есть на просторах Интернета по этому вопросу. К великому огорчению в статьях, которые удалось найти в основном говорится о том, как использовать примеси, но не дается разъяснений зачем они нужны, в каких случаях их использование более предпочтительно, чем обычное наследование или реализация интерфейсов. Эта статья является попыткой восполнить этот пробел. Несмотря на то, что в Интернете есть достаточно статей по теме примесей в Dart и Flutter, ясности они не вносят на мой взгляд потому, что приводимые примеры показывают чистую механику конструирования классов с примесями, которая далека от разумности и поэтому не демонстрирует реальную область их применения. В частности я встретил такой пример. Имеем: И почему-то нам захотелось получить животное, которое имеет свойства кошек и собак одновременно. В этом случае мы можем сделать так: К данному примеру есть по крайней мере два вопроса: При этом, зачем же все-таки нужны примеси, остается загадкой. Множественное наследование критикуется за ряд недостатков (см. Википедию), поэтому многие языки программирования не используют множественное наследование совсем, а используют механизм реализации интерфейсов и/или примеси. Да и, с точки зрения логики, конструкции, получающиеся в результате множественного наследования, не просто осмыслить. Для понимания следующего материала необходимо вспомнить некоторые понятия из элементарной логики. В частности понятия существенных и несущественных свойств. Существенными свойствами объектов являются те, благодаря наличию которых он отностится к тому или иному классу объектов. Несущественными свойствами объекта являются те, наличие, отсутствие или конкретные значения которых не влияет на принадлежность обекта некоторому классу объектов. Например, форма прямоугольника является существенным свойством этой фигуры, так как если мы изменим эту форму (уберем или добавим сторону или изменим углы), то прямоугольник перестанет быть прямоугольником. Но если изменить размеры прямоугольника, то он все равно останется прямоугольником. Поэтому размеры — это несущественное свойство. Выстраивание иерархии классов обычно основывается на добавлении к классу родителя каких-либо существенных свойств. Например, В основе этой иерархии лежит существенное свойство форма фигуры. Здесь существенным свойством является назначение виджета. А теперь предположим нам понадобилось добавить некоторое несущественное свойство к нашим сущностям. Таким свойством, например, является цвет. Пусть мы хотим теперь раскрашивать некоторые фигуры и виджеты. Можно воспользоваться механизмом реализации интерфейсов. Тогда мы получим что-то типа такого: Как видно это тоже не самое лучшее решение, так как нам приходится дублировать один и тот же код для каждой раскаршиваемой сущности. Но все эти проблемы решаются, если фукционал, связанный с несущественным свойством, мы вынесем в отдельную примесь (mixin): Теперь можно этим пользоваться: Подводя итог вышесказанному, можно следующим образом определить, когда удобно использовать примеси: если имеется несколько различных иерархий, которым нужно добавить один и тот же функционал, определяющий некоторое несущественное свойство для сущностей этих иерархий. Либо это может быть одна иерархия, но мы имеем дело с разными ее ветками. В качестве примера рассмотрим виджеты фреймворка Flutter. Предположим нам понадобилось добавлять к некоторым виджетам функционал, связанный с одним и тем же свойством. Виджеты во Flutter конструируются следующим образом: Для добавления некоторого свойства через наследование придется реализовывать по крайней мере два класса: при этом, как видно снова приходится дублировать функционал, связанный с добавляемым свойством. При использовании примесей проблема решается: Для тех, кто знаком с паттеранами проектирования, использование примесей в некоторых случаях может заменить применение паттерна Мост. В заключение следует заметить, что подобным образом можно подмешивать функционал сразу нескольких различных свойств в произвольных сочетаниях. Данная статья не претендует на исчерпывающее определение вариантов использования примесей. Вероятно пытливый ум разработчика сможет найти еще много красивых применений для них. Буду рад, если эти варианты использования примесей появятся в комментариях к этой статье. Миксины как функции — SASS: ПрограммированиеВозможно главной особенностью миксинов является то, что они могут принимать аргументы, которые могут быть использованы внутри. В программировании такие участки кода называются функциями. Они призваны облегчить переиспользование кода. Как же нам использовать это в SASS? Возьмём простой класс mx-10, который делает отступы слева и справа на 10 пикселей. Что делать, если мы захотим добавить больше таких классов? Например .mx-5, mx-10, mx-15, mx-20 и так далее. Конечно можно руками прописать все нужные нам классы и задать им свойства. Но это достаточно монотонный и долгий процесс. Попробуем для начала вынести свойства margin-left и margin-right в миксин, чтобы не было необходимости каждый раз их указывать. Кажется, что мало того, что ничего особо не поменялось, так мы ещё и добавили лишний код. Как нам это поможет в выносе дублирующего кода? Тут на сцену и выходит особенность миксинов принимать аргументы. Аргумент — некая переменная, от которой зависит результат выполнения функции. Аргументы указываются в круглых скобках и могут иметь любое имя. Каждый аргумент указывается с ключевым символом $. Если аргументов несколько, то они перечисляются через запятую. Добавим два аргумента в наш миксин. Первый аргумент будет указывать на значение свойства margin-right, а второй аргумент на значение свойства margin-left. Вторым шагом по превращению простого миксина в функцию является подстановка аргументов в свойства внутри миксина. Для этого вместо значений свойств подставим нужные нам аргументы. Если попробовать сейчас скомпилировать этот код, то получим следующую ошибку: Препроцессор сообщает нам, что отсутствует аргумент $mr. Это значит, что как только мы в миксин добавляем аргументы, то вызов без них невозможен. Даже если сами аргументы не будут использованы в миксине. Поправим ошибку и добавим 2 аргумента при вызове миксина. Аргументы также указываются в круглых скобках и туда мы помещаем то значение, которое ожидаем. В данном случае 10px. После компиляции мы получим именно тот код, который и хотели получить с самого начала: Разница теперь в том, что мы можем удобно писать новые классы без постоянного дублирования свойств. А в данном случае, так как значения свойств у нас повторяются, то мы можем передавать всего один аргумент и использовать его в двух свойствах сразу. Это хорошая практика, если свойства «родственны» друг другу. Использовать один аргумент для передачи, например, свойства height и margin-top не очень хорошая идея, даже если они и имеют одно значение. Так вы внесёте путаницу в код и уменьшите собственные возможности по кастомизации селекторов. В прошлом примере было показано, что случится, если не указать аргумент при вызове миксина. На самом деле это не всегда вызовет ошибку, так как миксины могут принимать аргументы по умолчанию. Если при вызове миксина не было указано никаких аргументов, то препроцессор будет пользоваться именно ими. Эти аргументы указываются непосредственно при создании миксина и перечислении аргументов. Всё, что нам нужно — указать значения, как у простой переменной. Это схоже с тем, как у переменной устанавливался флаг !default. Так как мы не указали аргументы при вызове миксина, то компилятор заберёт значение по умолчанию, которое было указано при создании миксина. После компиляции получится следующий CSS-код: Использование возможности миксинов принимать аргументы сильно помогает при создании шаблонов свойств с вендорными префиксами. В прошлом уроке мы посмотрели, как сделать миксин со свойством box-shadow и его вендорными префиксами. Использовав возможность указывать аргументы, мы можем сильно сократить наш код при повторном использовании с другими значениями. После компиляции мы получим следующий CSS: Передача свойств в миксинПомимо аргументов, в миксин мы можем передавать целый CSS код. Это очень удобно, если помимо каких-то значений нам нужно работать с кастомным CSS, который изначально отстутствует в миксине. Передать контент в миксин можно следующим образом: После компиляции мы получим следующий CSS код:
|
---|