Pull to refresh

Comments 41

Используйте паттерны, когда понимаете что это нужно.

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


Скажем если мы хотим чтобы код легко находился в проекте, повышаем coheasion. Что бы было проще определить насколько модуль кохизив, смотрим на него с точки зрения SRP. Хотим увеличить гибкость и избежать лавинообразных изменений между модулями — нужно снижать coupling, применять dependency inversion и т.д.


Нужно изолировать презентационную логику от логики обработки данных — не вопрос, формируем отдельно слой обработки данных и сверху лепим контроллеры и вьюхи которые будут заниматься отображением готовых данных. Если у нас есть необходимость как-то изолировать обработку данных в отдельном треде, можно попробовать реализовать все таким образом, чтобы один слой лежал в одном треде и только выставлял бы нужное состояние некому view model а в другом слое мы бы отслеживали изменение состояния и перерисовывали вьюху.


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

Вам нужно было писать эту статью) Но насколько я понял — вы со мной солидарны

Я не iOS разработчик, я мельком знаком с проблемами в вашем комьюнити. Скажем мои мобильщики частенько жалуются что мол подавляющее большинство не замарачиваются и размазывают логику по контроллеру. То есть до смешного доходит когда на одном проекте из 10 скринов можно найти 6 реализаций обработки пагинации.


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


  • Паттерны офигенны! Как я раньше без них жил! Куда бы еще запихнуть...
  • От этих паттернов только одни проблемы… Как мне теперь код мэйнтейнить...

Как по мне тратить на подобное целый год слишком долго. И грустно от того что я сам проходил через подобные этапы. Грустно от того что про концепции вроде связанности или принципы/паттерны GRASP я узнал через года 3 после того как начал путь в коммерческой разработке. А многие и через 5 лет не знают об этом. Люди через какое-то время просто находят свою зону комфорта. Кто-то просто не парится и не повышает сложность проекта. Кто-то раз в год меняет работу чтобы сбежать от ужаса поддержки своих решений...


Что до проектов с кривой архитектурой и кучей звезд — увы и ах… так везде. Многие хорошие разработчики которые выкладывают неплохие решения просто не парятся о продвижении своих библиотек.

Свою не продвигал, считаю что визуалка вытащила. Хотя для громкого заглавия использовал «плохую архитектуру». Проблемы она решает, я ей доволен — считаю что хороший выбор сделал.

История скорее о том, «сидя в зонах комфорта» юзают один паттерн под все случаи жизни.

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

тут скорее культ карго нежели зона комфорта. Ну мол кто-то рассказал что если будете применять viper то железные птицы вернутся все будет всегда хорошо. И скорее всего либо было лень разбираться что это такое либо авторитет шамана главного разработчика на проекте высок и ему лучше знать.


вижу VIPER где только можно и нельзя.

Я могу сказать так, из моего опыта общения с нашими мобильщиками которые практиковали viper на нескольких проектах, чаще проблема кроется еще и в неверной интерпретации этого паттерна. Поскольку паттерн этот основан на идеях Дяди Боба, нужно хорошо понимать такие принципы как SRP (который кажется обманчиво простым но на деле его весьма сложно соблюдать).


Так же у нас там есть ограничение в духе "сущности никогда не должны покидать интерактор и попадать в presenter" что есть просто соблюдение закона деметры и инкапсуляции. Опять же за последние 6 лет мне попадались только 2-3 проекта где на клиенте было достаточно логики что бы можно было выстраивать интеракторы. И да, те самые интеракторы подразумевается использовать только для операций записи, операции чтения можно делать проще. Более того, использование одних и тех же сущностей как для записи так и для чтения может приводить к нарушению SRP ради которого весь viper и задуман.


Ну то есть как по мне опять же проблема не в viper а в том что во всех описаниях этого паттерна которые мне удалось нагуглить вообще не говорится о том какие проблемы он решает. Как правило в качестве аргумента используют "юзают на больших проектах" и людям этого хватает.

Именно! Проблем с Viper нет никаких, есть вопросы «зачем», на которые часто ответ «ну так делают»

А то что поддержка сложным паттернов обходится в 2x-5x времени, или что есть другие, лучшие варианты (или вообще плюнуть и написать это одностраничное приложение все в контроллере) — боятся будто нечесть серебряных пуль)

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

Еще раз, и VIPER — прекрасный паттерн. Но стоит перед вами задача реализовать экран, который выводит «Хабрахбр, дай мне кармы»

Вы будете подтягивать VIPER? Я — нет.

И вся статья о том, что нужно использовать VIPER не потому что «на больших проектах используют, значит надо», а понять что паттерн решит вашу проблему. И, возможно, кастомизировать / комбинировать уже существующие паттерны для этой цели. А может и свой сделать.

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

тут нет цели


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

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


Другое дело что вайпер налагает сэт весьма простых ограничений вида "такой-то код ложи сюда", что немного позволят дисциплинировать команду. Но все же что мне не нравится в этом паттерне что он как бы и прославляет SRP и как бы сам по себе отвечает за слишком многое. Скажем почему бы не воспринимать интеракторы как модель в контексте привычных многим MV* а все эти вайрфреймы/сущности сделать лишь деталью их реализации. Как бы при таком варианте вся та же идея сохраняется, но проще маневрировать.


Но имхо, все высказавшиеся правы в том, что времени на написание кода с этим паттернов уходит не мало.

по сути мы тут имеем дополнительный уровень взаимодействия и больше мелких объектов. То есть на скорость непосредственно написания кода это не сильно влияет на самом деле. Тут больше вопрос в необходимом на проекте уровне изоляции и в том насколько выбранные подходы позволяют устранять дублирование логики.

Вайпер в его «разбитости» упрощает тестирование кода. Так же, ваше желание маневрировать мне не сильно понятно, не могли бы вы описать подробнее, где вайпер мешает маневрировать?
Вайпер в его «разбитости» упрощает тестирование кода.

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


где вайпер мешает маневрировать?

он жестко декларирует что куда и как. И это не плохо. Просто опять же для этого люди должны хорошо понимать почему там что куда и как. А если разработчики и так это понимают, то они и сами вполне себе могут делать свои вариации разделения ответственности и декомпозиции проекта.


p.s. лично мне было бы интересно послушать от кого-нибудь про опыт дробления UI на отдельные компоненты. Это как по мне ценности разработчикам добавит больше чем вайпер который орудует цельными скринами.

да, спасибо что поправили

Для чего используется вот эта конструкция?

let permissionAssistant = SPRequestPermissionAssistant.modules.dialog.interactive.create(with: [.Camera, .PhotoLibrary, .Notification]


Никому не нужны подробности реализации, должно быть просто:

let permissionAssistant = SPRequestPermissionAssistant.create(with: [.Camera, .PhotoLibrary, .Notification]


То что вы выставляете наружу кишки — это феил.
Для чего используется вот эта конструкция?

Это сборка модуля. Если не ошибаюсь, прием называется Dependency Injection и очень близко идет с протокольным подходом.

Никому не нужны подробности реализации, должно быть просто:

Никаких подробностей реализации. Это просто выбор одного из модулей. Хотите банер сверху? Будет:

SPRequestPermissionAssistant.modules.banner


Хотите диалоговое окно, но не интерактивное, а с блюром:

SPRequestPermissionAssistant.modules.dialog.blur
Какая связь между звёздами и качеством кода? Компонент нравится — потому и звездят, качество кода тут вообще побоку. Гитхаб это не кодревью.
В этом и смысл — нужно оправдано применять паттерны и не забывать о цели, которая ставится. Паттерны — не панацея.

На примере проекта я показал как забить на традиционные паттерны и сделать такую архитектуру, которая будет решать необходимую мне проблему (я не говорю что изобрел ее, просто скомбинировал разные подходы).

Я не говорю что есть связь между звёздами и качеством кода, скорее говорю что некачественный код может быть объективно лучше, нежели 5x сил, затраченных на реализацию паттерна (или "используем VIPER потому что промышленный стек")
Как мне кажется, похожие взгляды высказывались на хабре в статье про "выпекание хлеба".

Ну и Оккам со своей бритвой плохого не посоветует.
Ну и Оккам со своей бритвой плохого не посоветует.

бритва Хэнлона тож ничаго.

Суперская статья!
Да, взгляды и призывы очень похожее
Я не говорю что есть связь между звёздами и качеством кода, скорее говорю что некачественный код может быть объективно лучше, нежели 5x сил на реализацию паттерна
Это уж конечно, программирование ради программирование вообще в последнее время как-то начинает напрягать.
По-моему эта либо нарушает гайдлайны эппла, разрешения должны запрашиваться в момент, когда они нужны, надо объяснить, зачем они нужны и приложение должно уметь работать при отсутствии разрешений.

Рано или поздно заблочат в аппсторе
Вы правы. Но гидлайнов либа не нарушает и вопросов не возникало (лично у меня 20+ ревью уже было).

Если капнуть глубже — завязано вообще приложение на выборе фотографии. Как вы без разрешения камеры и фото? Или те же пуши… они не влияют на функционал, но хотелось бы чтобы пользователи давали добро. По гидлайнам их нужно запрашивать… при первом запуске? Это ужасный подход, и конверсия будет на нуле.

Из общения с саппортом было принято пожелание не требовать нотификации. Так в либа для их запроса кастомная логика: если были запрещены, не смотря на то что разрешение не получено — диалоговое окно закроется.

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

Ну серьезно?)

Давайте еще раз, к примеру проект — перископ. Для корректной работы нужна камера, микрофон и локация. Выкиньте все 3 окна на пользователя? Мне кажется именно это и будет «низкой квалификацией». А так покажете диалоговое окно с тремя разрешениями (можно и пуши еще предложить, заодно, у пушей нет конкретной «правильной» точки запроса)

Вы можете сказать что ситуация единственная, и скорее исключение. Но возьмем популярный вариант — вам нужно выбрать фотографию, или сделать ее. Два разрешения, так? Тоже выкиньте пачкой разрешения? Мне лично понравится диалоговое окно с приятной UI, а не N-ое количество алертов поверх

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

А вообще грустно что вы аудиторию заочно назвали «низкоквалифицированной»
Перископ… вы же именно оттуда взяли идею, правильно я понимаю? Чтобы сделать фотографию мы запрашиваем доступ к камере, совсем не обязательно её нужно будет сохранять. Если только после фотографирования пользователь запросил сохранение, уже тогда запрашиваем доступ к галерее. Сравните сценарии:
А) Пользователь запускает приложение, знакомится и интерфейсом, нажимает кнопку «сфотографировать», разрешает доступ к камере, играется с фильтрами, пересылает фотографию, отказывает в доступе к галерее.
Б) Пользователь запускает приложение, получает окно с запросом кучи прав, нажимает «разрешить доступ к камере», получает уже системный запрос на разрешение доступа к камере, повторно разрешает доступ к камере, видит «вы не можете продолжить, пока не дадите все разрешения». Дальше лично я бы ругаясь прошел только при условии, что приложение уровня перископа. Давайте оставим такой ущербный подход к управлению правами доступа андроиду, ок?

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

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

Более того, я против если приложение где-то глубоко использует галерею, запрашивать ее при запуске. Еще раз вернемся к перископу (это прекрасный пример) — как иначе организовать, чтобы не убить лояльность? Да никак.

А теперь, представим, вы запрашиваете пуши. Только пуши. Вместо того, чтобы выбросить на пользователя системный запрос, вы показываете ему окно, пытаясь убедить в том, что пуши ему будут полезны. Если что, конверсия реально оказалась выше.

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

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

Сразу дьявол на левом? плече шепчет: “Singltone…”. И первые дни мне казалось это прекрасным решением, в AppDelegate сконфигурировал, а показывай контролер где захочется.

Presenter держит контроллер, он будет разбираться с жестами, экраном и прочим, чем занимаются контроллеры. Конечно, возникает вопрос как контроллер будет сообщать о действиях. У особо пытливых возникнет вопрос «а ARC часом не уничтожит все к чертям?».


Я думаю вы ставили перед собой цель: Написать легко используемый, закрытый функционал. Но почему вы так далеко пошли? Вы ведь не храните ссылку на UIAlertController? Вроде как красивое решение, где легко добавляется и хендлится выбор элемента. Почему не покапали в эту сторону?
Да и проблема с ARC решается retain циклом с последующим его освобождением, вы ведь знаете жизненней цикл вашей реализации.

По поводу звезд — тут скорее заслуга не решения, а вашего маркетингового хода, я думаю вы потратили достаточно времени, чтобы написать во все возможные комьюнити.
Функционал не закрытый, скорее скрытый протоколом. Мне кажется (и не просто так) в таком проекте это отличная практика.

По поводу маркетинга — я самый ужасный маркетолог. Ни одной статьи не найдете, потому что никто их не писал) Но погуглив найдете кучу рекомендаций на профильных ресурсах. Вообще все было просто, я попал в дно топа, после попал в выбору awesome-ios. А дальше понеслось…

P.S. Даже грустно что сразу видите маркетинг, а не «лояльно воспринятый проект», тем более что предпосылок так думать вроде как и нет.
Функционал не закрытый, скорее скрытый протоколом. Мне кажется (и не просто так) в таком проекте это отличная практика.

Речь шла про понятный и простой interface (как в UIAlertController, как я писал выше), а не property + SPRequestPermissionAssistant.modules.dialog.interactive.create.
Жаль, что игнорите советы или у вас мнение о UIAlertController?
P.S. Даже грустно что сразу видите маркетинг, а не «лояльно воспринятый проект», тем более что предпосылок так думать вроде как и нет.

Серьезно? Я состою во множестве чатиках, группах, да и на всяких cocoacontrols, и во всех сиял ваш профиль с ссылкой на это чудо.
Жаль, что игнорите советы или у вас мнение о UIAlertController?

Простите, перечитал раз 5 и не понял, торможу) Если у вас есть предложение — отпишитесь мне чуть подробнее. Всегда рад взгляду со стороны

Серьезно?

А да, на cocoacontrols действительно кидал, общаемся с автором проекта — он немного подержал в топе(очень понравился ему проект). Но максимум оттуда выжать ну 100 звезд) Было еще два момента, в группе iOS dev (проект уже имел больше 1к звезд), и в чате iOsNinja — тоже самое.

Больше нет, я не вижу тут маркетинга. В iOS dev поделился успехом (мне много помогали резиденты, и даже Скутаренко), а в iOsNinja — 100 человек в чате)

А где еще? Честн слово, органика) Так что я серьезно — маркетинга небыло
Исправьте в начале текста в слове «Singltone» две ошибки.
Ну как бы в тему — http://local.joelonsoftware.com/wiki/Не_дайте_Астронавтам_Архитектуры_вас_запугать
Сколько раз себя ловил на этом

Когда вы поднимаетесь слишком высоко, наполненный абстракциями, вы задыхаетесь из-за отсутствия кислорода. Иногда мыслители просто не знают, когда остановиться, и они создают абсурдные, всеобъемлющие, высокоуровневые картины устройства вселенной, которые являются хорошими и изящными, но фактически не означают вообще ничего.


Отличная, ироничная статья
Использовал это расширение в своем приложении, очень понравилась тонкая настройка окошка уведомлений. Могу сказать, что количество пользователей, включающих-таки уведомления, увеличилось очень сильно, это следует из статистики «возвращений» пользователей в приложение на следующий день. Респект автору :)
Мимо проходил и со свифтом не дружу, но у вас там конструкции наподобие
SPRequestPermissionAssistant.modules.dialog.interactive.create(with: [.Camera, .PhotoLibrary, .Notification])

это норма? Нельзя чтоли напрямую импортировать конкретные модули/методы и использовать их по-человечески? Аля
import { interactive } from '%пути к модулю либы%';
interactive.create(%stuff%);


А то прям жуть какая-та.
Sign up to leave a comment.

Articles