Похожа ли концепция категорий Objective-C в чем-либо на концепцию миксинов? Если да: в чем сходство? В нет: в чем различия?

16
teabot 7 Авг 2009 в 17:39

4 ответа

Лучший ответ

Насколько я понимаю:

Миксины

  • Синтаксический сахар для композиции
  • Добавлен разработчиком класса, а не пользователем
  • Может быть повторно использован несколькими классами
  • Может добавлять переменные экземпляра
  • Может быть реализовано с использованием пересылки в Objective-C

Категории

  • Подобно методам расширения на других языках
  • Обычно добавляется пользователем класса, а не разработчиком
  • Используется ровно одним классом и его подклассами
  • Невозможно добавить переменные экземпляра
17
John Calsbeek 7 Авг 2009 в 15:59

С помощью миксина вы можете получить новый класс из своей базы и миксина, а затем создать экземпляр этого нового класса, чтобы воспользоваться им.

С категорией вы эффективно добавляете непосредственно базовый класс, так что все экземпляры этой базы имеют доступ к функциям, предоставляемым категорией.

2
Paul Dixon 7 Авг 2009 в 13:50

Категории определены для конкретного класса, насколько я знаю, вы не можете создать категорию и добавить методы, которые она реализует, к нескольким классам.

4
pgb 7 Авг 2009 в 13:44

Чтобы быть ясным, ответ НЕТ - это не одно и то же.

Различия изложены Джоном Калсбиком в принятом ответе, но я бы сказал, что ключевое отличие состоит в том, что миксины могут использоваться в разных классах, тогда как категории всегда расширяют только один класс, который они объявляют в своем определении.

Это ключевое различие, потому что это означает, что варианты использования этих двух функций совершенно разные. С другой стороны, если вы переходите с Ruby на Objective-C и упускаете свои миксины, вам не будет радости с категориями.

Вариант использования миксинов заключается в том, что у вас есть некоторый код - методы и переменные экземпляра - которые вы хотите повторно использовать в нескольких классах, у которых нет общего суперкласса. Вы не можете этого сделать с категориями.

Примеси фактически представляют собой «множественное наследование» типа, которого вы не найдете в Objective-C. Самая близкая вещь в objective-c - это протоколы, точно так же, как Java - это интерфейсы, но у них нет ни переменных экземпляра, ни тел методов (в objective-C или java). Таким образом, вам обычно остается создавать вспомогательные классы или помещать код в суперклассы.

Вариант использования категорий objective-c заключается в том, что вы хотите добавить методы к существующему классу - даже к системному или библиотечному классу.

Я бы сказал, что миксины более мощные, но поскольку это сравнение яблок с апельсинами, это было бы бессмысленно.

Чтобы быть точным:

  • Рубиновый эквивалент категорий - просто повторно открыть класс, который вы хотите расширить и расширить. (Вы можете сделать это где угодно в Ruby, и это фактически идентично категориям)

  • Я не уверен, что такое объективный эквивалент Mixins - кто-нибудь?

[Обновление] Еще немного поиска, и нет эквивалента миксинов в Objective-C, но предприимчивый Владимир Митрович создал библиотеку, которая эффективно это делает. https://github.com/vl4dimir/ObjectiveMixin

Я не понимаю, использовать это или нет: иногда, если язык, который вы используете, что-то не поддерживает, легче работать с ним, чем бороться с ним или пытаться импортировать свои любимые функции с других языков. («Если вы не можете использовать язык программирования, который вам нравится, любите тот, на котором вы работаете»).

Опять же, возможно, это просто немного меня заносчиво. Все движение по аспектно-ориентированному программированию на протяжении многих лет наполняло Java функциями (но, я бы добавил, не получило особой поддержки за пределами JBoss). В любом случае, Владимир получает дополнительные похвалы за использование Черепашек-ниндзя в своем примере.

С другой стороны, узел: как относительный объектный нуб, мне кажется, что категории слишком часто используются в примерах кода, которые я нахожу по всей сети. Кажется обычной практикой добавлять статические вспомогательные методы к системным классам с категориями, когда было бы так же легко создать вспомогательный класс для размещения этих методов в вашем проекте, с меньшим риском их поломки при обновлении системного класса или при импорте чужая библиотека со своими такими категориями. Типичный пример - добавление новых статических методов цвета в UIColor. Почему бы просто не добавить их в локальный класс?

Я видел одно действительно хорошее применение категорий - это добавление методов не к системным классам, а к сгенерированным классам. Поэтому, когда вы генерируете классы из своей объектной модели основных данных и хотите добавить новые конструкторы или другие методы, которые действительно принадлежат к классу модели, вы можете сделать это с помощью категорий, что позволит вам безопасно регенерируйте класс модели, если вы измените свою модель, без потери вашей работы.

В итоге: - забудьте о категориях как о решении для миксинов - категории хороши для основных данных, но в противном случае используются чрезмерно и переоцениваются

7
Rhubarb 19 Окт 2012 в 09:46