Подтвердить что ты не робот

Создание Objective-C Классы выглядят Красиво

Я хотел спросить вас всех о ваших мнениях о запахах кода в Objective C, в частности Cocoa Touch. Я работаю над довольно сложной игрой и собираюсь начать Великий декабрьский рефакторинг.

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

Чем больше я рефакторинг (хорошая вещь!), тем больше я должен поддерживать все это дублирование (не очень хорошее). Это просто неправильно.

На языке, подобном Ruby, сообщество уделяет много внимания очень коротким, ясным, красивым методам. Мой вопрос в том, что для Objective C (Cocoa Touch конкретно), как долго ваши методы, насколько велики ваши контроллеры и сколько методов в классе вы все нахождете, становится типичным в ваших проектах? Существуют ли какие-либо особенно красивые, красивые примеры классов, составленные из коротких методов в Objective C, или это просто не важная часть языковой культуры?

РАСКРЫТИЕ: Я сейчас читаю "Маленький Schemer", который должен объяснить мою грусть, re: Objective C.

4b9b3361

Ответ 1

Красота субъективна. Для меня класс Objective-C красив, если он доступен для чтения (я знаю, что он должен делать) и поддерживаемый (я могу видеть, какие части несут ответственность за выполнение чего). Мне также не нравится, что меня выкидывают из кода чтения незнакомой идиомой. Похоже, когда вы читаете книгу, и вы читаете что-то, что выводит вас из погружения и напоминает вам, что вы читаете.

Вероятно, вы получите много разных, взаимоисключающих советов, но вот мои мысли.

  • Ничего плохого в том, что частные методы находятся в частной категории. Это то, для чего оно есть. Если вам не нравятся объявления, которые засоряют файл, либо используют сворачивание кода в среде IDE, либо имеют расширения в качестве категории в другом файле.
  • Связать связанные группы методы и пометить их операторами #pragma mark
  • Независимо от того, какой формат кода вы используете, важна последовательность. Возьмите несколько минут и напишите свои собственные рекомендации (здесь mine), поэтому, если вы забудете, что вы должны делать, у вас есть ссылка.
  • Контроллер не обязательно должен быть делегатом и источником данных, для которых у вас всегда могут быть другие классы.
  • Используйте описательные имена для методов и свойств. Да, вы можете документировать их, но вы не можете видеть документацию, когда Xcode применяет завершение кода, где хорошо названные методы и свойства окупаются. Кроме того, комментарии кодов становятся устаревшими, если они не обновляются, а сам код изменяется.
  • Не пытайтесь писать хитрый код. Вы можете подумать, что лучше цепочки последовательности вызовов методов в одной строке, но компилятор лучше оптимизирует, чем вы могли бы подумать. Хорошо использовать временные переменные для хранения значений (в основном это просто указатели, так что относительно небольшие), если это улучшает читаемость. Введите код для чтения людьми.
  • DRY применяется к Objective-C столько же, сколько к другим языкам. Не беспокойтесь о том, как реорганизовать код в другие методы. Нет ничего плохого в том, что у вас много методов, если они полезны.

Ответ 2

Самое первое, что я делаю до внедрения класса или метода, - спросить: "Как бы я хотел использовать это извне?"

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

Есть много шаблонов дизайна, два десятилетия программирования научили меня, что единственный образец, который выдерживает испытание временем: KISS. Держите его просто глупым.

Некоторые общие правила для любого языка или среды:

  • Следите за своим чувством кишки за любой совет, который вы прочитали или услышали!
  • Выйдите рано!
    • При необходимости проверьте исходные данные и быстро запустите их! Меньше очистки.
  • Никогда не добавляйте что-то в свой код, который вы не используете.
    • Вариант для "обратного" может показаться приятным, чтобы иметь дорогу.
    • В таком случае добавьте его в дорогу! Не тратьте время, добавляя сложность, в которой вы не нуждаетесь.
  • Имена методов должны описывать, что делается, никогда, как это делается.
    • Методам должно быть разрешено изменять их реализацию, не изменяя их имя, пока результат не будет таким же.
    • Если вы не можете понять, что метод делает из него, тогда измените имя!
    • Если часть детали достаточно сложна, используйте комментарии для описания своей реализации.
  • Не бойтесь одиночек!
    • Если ваше приложение имеет только одну модель данных, то это singleton!
    • Прохождение единой переменной по всему месту просто притворяется, что это что-то другое, кроме сингла и добавление сложности в качестве бонуса.
  • Планирование сбоев с самого начала.
    • Всегда используйте для doFoo:error вместо doFoo: с самого начала.
    • Создайте красивые экземпляры NSError с конечным пользователем, читаемыми локализованными описаниями с самого начала.
    • Это большая боль, чтобы модифицировать обработку ошибок/сообщений в большое существующее приложение.
    • И всегда будут ошибки, если у вас есть пользователи и IO!
  • Cocoa/Objective-C Объект * Ориентирован, а не ** Класс Ориентирован на большинство популярных детей, претендующих на ООП.
    • Не вводите класс немого значения с только свойствами, класс без методов, выполняющих фактическую работу, также может быть структурой.
    • Пусть ваши объекты будут умными! Зачем добавлять целый новый класс FooParser, если метод fooFromString: на Foo - это все, что вам нужно?
  • В Cocoa то, что вы можете сделать, всегда более важно, чем вы.
    • Не вводите протокол, если это может сделать действие target/action.
    • Не проверяйте, соответствуют ли экземпляры протоколам, это класс, который зависит от компилятора.

Ответ 3

Мои 2 цента:

  • Свойства обычно лучше, чем старомодный getter + setter. Даже если вы используете @dynamic properties - объявляете их с помощью @property, это более информативно и короче.
  • Я лично не моделирую "private" методы для классов. Да, я могу написать категорию где-то в файле .m(m), но поскольку Obj-C не имеет чистого способа объявить частный метод - зачем его изобретать? В любом случае, даже если вам действительно нужно что-то подобное - объявите отдельный "MyClassPrivate.h" с категорией и включите его в файлы .m(m), чтобы избежать дублирования объявлений.
  • Привязка. Связывание для большинства отношений с Controller ↔ UI, использование трансформаторов, форматировщиков, просто не записывайте методы для чтения/записи значений элементов управления вручную. Это делает код похожим на что-то из эпохи MFC.
  • С++, много кода выглядит намного лучше и короче при написании на С++. Поскольку компилятор понимает классы С++, это хороший момент для рефакторинга, особенно при работе с низкоуровневым кодом.
  • Я обычно разделяю большие контроллеры. Что-то более 500 строк кода является хорошим кандидатом для рефакторинга для меня. Например, у меня есть контроллер окна документа, поскольку некоторые версии приложения расширяются с параметрами импорта/экспорта изображений. Контроллер растет до 1.000 строк, где 1/2 является "образным материалом". Это "триггер" для меня, чтобы создать ImageStuffController, создать экземпляр в NIB и поместить туда весь относительный код изображения.

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