Как стать автором
Обновить

Комментарии 29

Всегда используем // MARK: -

Вот это мне совершенно не понятно. Ну ладно, фиксированный порядок, хорошо. Но зачем еще дополнительно маркера-то вводить?


Перечитал еще раз: "данная метка не только хорошо выделяется из всего кода, но и автоматически создает оглавление". Видимо, эта такая милая специфика языка/IDE. Моежт стоит тогда все-таки явно указывать, что эта рекомендация специфична?


Хотя, впрочем, фиксированный порядок — тоже вопрос. Вот написано: сначала публичные методы, затем приватные методы. Почему так, а не "публичный метод и используемые им приватные методы"?

На последний вопрос ответить легко. Публичные методы — интерфейс класса: то, как с ним взаимодействуют извне. Это то, как он выглядит «снаружи». Приватные методы/данные — детали реализации, знать которые надо только для написания самого класса, но не для его использования.
Публичные методы — интерфейс класса: то, как с ним взаимодействуют извне. Это то, как он выглядит «снаружи».

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

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

Не должны. Лучше иметь отдельный участок-секцию кода, где идут только свойства, упорядоченные по порядку паблик-readonly-приват. А потом уже идет конструктор, и лишь потом — публичные методы. Смешивать код по принципу модификатора доступа — не самая удачная идея, потому что их мало (часто используемых — всего два). Так ваш код разобьется всего на две огромных секции внутри файла. А разделение по смысловым элементам (typealias'ы, свойства, приватные свойства, конструктор/деструктор, методы, приватные методы, реализация протоколов) дает куда больше секций в коде, а значит, и повышает простоту восприятия его структуры. Аналогия: что проще, книга на тему «Программирование» из двух огромных общих глав, или из двадцати, но более конкретных?

а почему, собственно, то, как класс выглядит «снаружи», должно влиять на то, как он расположен в файле?

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

И да, есть вариант «отсматривать автоматически создаваемое подобие хедера файла» через спец. кнопку в Xcode, но это довольно тормозная штука, и поэтому, лично на мой взгляд, неудобная.
Не должны. Лучше иметь отдельный участок-секцию кода, где идут только свойства, упорядоченные по порядку паблик-readonly-приват.

Но почему? Это же противоречит идее "сначала интерфейс класса, потом внутренности".


Смешивать код по принципу модификатора доступа — не самая удачная идея

Не "смешивать", а "объединять". И если "плохая идея" объединять публичные свойства и методы (особенно учитывая, что свойства — это, по большому счету, тоже методы), то непонятно, почему хорошая идея — объединять два публичных метода.


Аналогия: что проще, книга на тему «Программирование» из двух огромных общих глав, или из двадцати, но более конкретных?

Это зависит от того, что в этих главах содержится.


Потому что часто бывает задача изучить неизвестный класс, его функционал, и сделать это побыстрее, не отсматривая все тело файла. [...] Нужно лишь понять, какие возможности он предоставляет для пользования

Я для этого пользуюсь автодополнением, потому что тогда вообще не надо ходить в файл (и не надо пролистывать тела публичных методов).

Ctrl+Cmd+️
Почему так, а не «публичный метод и используемые им приватные методы»?

Отвечу со своей колокольни. В варианте «сначала паблик, потом приват» при отсмотре файла вы точно знаете, что если видите приватный метод, то все, публичные — закончились. А если делать вперемешку, как вы предложили, то вы никогда не узнаете, где и когда в файле заканчиваются публичные методы. А учитывая, что свифтовый код пишется в одном файле (без хедеров, отделяющих публичную часть), то при изучении чужого кода на предмет «что там где находится, что умеет класс, какие свойства и методы отдает наружу и т.д.» вам будет на порядок сложнее разобрать каждый незнакомый вам класс. Ваш подход удобен лишь «для себя самого», пока на проекте все известно, и нет людей, не знакомых с кодом. А еще нет авралов.
Значит должно быть правило для swiftlint/swiftformat иначе уверенность в том что закончились может сыграть злую шутку.
Перечитал еще раз: «данная метка не только хорошо выделяется из всего кода, но и автоматически создает оглавление». Видимо, эта такая милая специфика языка/IDE. Моежт стоит тогда все-таки явно указывать, что эта рекомендация специфична?

Это же про ай-ос разработку, а там IDE — X code. Поэтому, как раз отклонение от нее — специфично.
Это же про ай-ос разработку, а там IDE — X code.

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


(ну и еще, я слышал, под iOS можно разрабатывать не только на в X code, говорят, даже кроссплатформенные инструменты есть)

AppCode ещё есть. Очень удобно работать в ней.
Отличная статья.

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

Спасибо.
Поддерживаю. Сам стараюсь в проектах, где работаю, добровольно-принудительно вводить такой же порядок. Очень помогает преобразить код из состояния «свалка» в состояние «книга».
НЛО прилетело и опубликовало эту надпись здесь
Не хочу показаться грубым, но видеть методы вроде setupNavigationBar во вьюконтроллере в примерах хорошего кода?
Можно сделать статический класс-гайдлайн с методами setupNavigationBar, setupSomeButton — так не придется в каждом вьюконтроллере дублировать одно и тоже. Как в одном из примеров showActivityIndicator(on viewController: UIViewController).
НЛО прилетело и опубликовало эту надпись здесь
Я привык называть функции didTouchButton(_ sender: UIButton), а коллеги просто touchButton(_ sender: UIButton) называют.
Плиз можете указать место где это яблочниками рекомендуется?

Половина — просто вкусовщина.


1,2 — писать марки и давать им имена без смысловой нагрузки, которые просто констатируют капитанские факты (публичные, приватные) — странно, читаемость это точно не улучшит, стоит применять марки для разделения разных наборов методов внутри класса, например, работа с таблицей, работа с поиском и т.п.
3 — создавать множество одноразовых одно-двух-строчников также может ухудшить понимание происходящего в коде, часто придется скакать между использованием и реализацией.
4 — также ухудшает понимаемость класса, логичнее сразу в объявлении класса видеть все его наследования и интерфейсы, но с экстеншенами все интерфейсы будут разбросаны где-то далеко ниже по коду класса, придется весь класс просмотреть, чтобы понять его суть.


Также в статье про читаемость стоит привести в порядок примеры кода, в них нет единого консистентного кодстайла, выглядит как надерганные куски из гугла.


P.S. Интересно, когда таки айосники перестанут писать weak для аутлетов.

Т.е. вы утверждаете, что писать weak не нужно? Объяснитесь!

Если вы понимаете управление памятью в айос и иерархию вьюх во вьюконтроллере, то все должно быть очевидно.

Интересно, когда таки айосники перестанут писать weak для аутлетов.
Хсоde weak вставляет сам если мышкой из Interface Builder тянуть.

В Xcode в появившемся окне при создании аутлета это выбирается.

Выносите реализацию протоколов в extension

Что делать, если в протоколе объявлено свойство? Где его располагать?
Вычисляемое или переносить реализацию чисто в класс. А так этот совет касается в большей степени протоколов с методами (делегаты)
Любопытная статья, делаю все также, только вот вместе с Lifecycle я еще все override-ы сую.
Нормальная ли практика, если перекрывать все оконченые классы final?
Да, это хорошая практика отмечать класс как final если данный класс не будет иметь наследников.
Очень хорошо, хотя есть несколько мыслей на тему:

Чтобы ещё круче автоматизировать рутину — можно использовать готовый шаблон — тогда всем будет сразу видно куда вставлять IBOutlet а куда override

Имхо код в п.3 легче читается тот что Вами не рекомендован. И ещё я бы предпочёл
navigationController<b>!</b>.navigationBar.backgroundColor = .red
чтобы сразу упасть если кто-то решит использовать класс неожиданным образом. А читающему будет очевидно что раз не падает код то неожиданность в том что там был nil искать не следует.
Если ли же класс подразумевается для использования и под navigationController и без оного — то лучше как минимум вставить коммент об этом явным образом.

Ещё я предпочитаю вставлять internal чтобы было видно где свойство явно внешнее а где забыли прописать private.
А вообще рекомендую все var делать private + иметь
func configure(with delegate: SomeDelegate, userId: String)
Или вообще
static func start(from navCtrl: UINavigationController, with delegate: SomeDelegate, ...)

Кстати. Чтобы получить проверку на этапе компиляции лучше сделать класс UserId — тогда никто случайно FamilyId не отправит туда где должен быть UserId. Что легко возможно если используется String.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории