Какие хорошие примеры миксинов и черт?

Я читал на 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. Это системный способ ввода функциональности в классы.