Какие хорошие примеры миксинов и черт?
Я читал на Ruby и узнал о его шаблоне mixins, но не мог придумать много полезных функций mixin (потому что я не привык думать об этом, скорее всего). Поэтому мне было интересно, что будет хорошими примерами полезных функций Mixin?
Спасибо
Изменить: немного фона. Я исхожу из С++ и других языков Object, но я сомневаюсь, что Ruby говорит, что он не наследует mixins, но я все время вижу mixins как множественное наследование, поэтому я боюсь, что я слишком рано их классифицирую в свою зону комфорта, и на самом деле не пытайтесь понять, что такое mixin.
Ответы
Ответ 1
Ну, обычный пример, я думаю, это Persistence
module Persistence
def load sFileName
puts "load code to read #{sFileName} contents into my_data"
end
def save sFileName
puts "Uber code to persist #{@my_data} to #{sFileName}"
end
end
class BrandNewClass
include Persistence
attr :my_data
def data=(someData)
@my_data = someData
end
end
b = BrandNewClass.new
b.data = "My pwd"
b.save "MyFile.secret"
b.load "MyFile.secret"
Представьте, что модуль написан ниндзя Ruby, который сохраняет состояние вашего класса в файле.
Теперь предположим, что я пишу совершенно новый класс, я могу повторно использовать функциональность настойчивости, смешав его, сказав include ModuleILike
. Вы можете даже включать модули во время выполнения. Я бесплатно загружаю и сохраняю методы, просто вставляя их. Эти методы аналогичны тем, которые вы написали для своего класса. Код/Поведение/Функциональность - повторное использование без наследования!
Итак, что вы делаете, это включает методы в таблицу методов для вашего класса (не буквально правильные, но близкие).
Ответ 2
Обычно они используются для добавления в класс некоторых стандартных функций, без необходимости переопределять их. Вероятно, вы можете думать о них как о интерфейсах в Java, но вместо того, чтобы просто определять список методов, которые необходимо реализовать, многие из них будут фактически реализованы путем включения модуля.
В стандартной библиотеке есть несколько примеров:
Синглтон - модуль, который можно смешать в любом классе, чтобы сделать его одиночным. Метод initialize делается частным, и добавлен метод экземпляра, который гарантирует, что в вашем приложении есть только один экземпляр этого класса.
Сравнительно. Если вы включите этот модуль в класс, определение метода <= > , который сравнивает текущий экземпляр с другим объектом и говорит, что больше, достаточно, чтобы предоставить <, < =, ==, > =, > и между? Методы.
Перечислить - путем смешивания в этом модуле и определения метода каждый вы получите поддержку всех других связанных методов, таких как сбор, ввод, выбор и отклонение. Если он также получил метод <= > , он также будет поддерживать сортировку, min и max.
DataMapper - также интересный пример того, что можно сделать с помощью простого оператора include, взятия стандартного класса и добавления возможности сохранять его в хранилище данных.
Ответ 3
В рубине причина, по которой Mixins не является множественным наследованием, заключается в том, что объединение методов mixin - это одноразовая вещь. Это не будет такой большой проблемой, за исключением того, что модули и классы Ruby открыты для модификации. Это означает, что если вы смешиваете модуль с вашим классом, добавьте метод в модуль, этот метод не будет доступен для вашего класса; где, если бы вы сделали это в обратном порядке, это было бы.
Это нравится заказывать конус мороженого. Если вы получаете шоколадные брызги и ириски в качестве ваших миксинов и уходите с конусом, то какой у вас конус мороженого не изменится, если кто-то добавит многоцветные брызги, чтобы шоколад разбрызгивал бункер обратно в магазин мороженого. Ваш класс, конус мороженого, не модифицируется, когда микширующий модуль, бункер спринклеров. Следующий пользователь, который будет использовать этот модуль mixin, увидит изменения.
Когда вы include
модуль в рубине, он вызывает Module#append_features
в этом модуле, который один раз добавляет копию этих методов модуля в один из них.
Множественное наследование, как я понимаю, больше похоже на делегирование. Если ваш класс не знает, как что-то сделать, он спрашивает своих родителей. В среде открытого класса родители классов могут быть изменены после создания класса.
Он похож на отношения родитель-ребенок RL. Ваша мать, возможно, научилась жонглировать после того, как вы родились, но если кто-то попросит вас сделать жонглирование, и вы попросите ее: показать вам, как (скопируйте его, когда вам это нужно) или сделайте это для вас (чистая делегация), затем она я буду в состоянии в тот момент, даже несмотря на то, что вы были созданы до того, как ее способность жонглировать была.
Возможно, вы можете изменить модуль ruby 'include', чтобы действовать скорее как множественное наследование, изменяя Module#append_features
, чтобы сохранить список включений, а затем обновить их с помощью обратного вызова method_added
, но это будет большой сдвиг от стандартного Ruby и может вызвать серьезные проблемы при работе с другим кодом. Возможно, вам лучше создать метод Module#inherit
, который называется include
и обработать делегирование.
Что касается примера реального мира, Enumerable
является удивительным. Если вы определяете #each
и включаете Enumerable
в свой класс, то это дает вам доступ ко всему хосту итераторов без необходимости кодирования каждого из них.
Ответ 4
В основном он используется, поскольку можно использовать множественное наследование в С++ или реализовать интерфейсы в Java/С#. Я не уверен, где лежит ваш опыт, но если вы делали это раньше, mixins - это то, как вы будете делать это в Ruby. Это системный способ ввода функциональности в классы.