Еще раз про синглтоны, датасторы и прочие вещи для хранения
Всем привет! Ни разу не получал какого-либо четкого ответа на тему хранения данных в мобильном приложении (в моем случае - iOS). Допустим, у меня есть модель данных - массив городов. Этот массив я получаю из сети и использую его почти в каждом модуле приложения(модулей примерно 10). Под словом модуль, я представляю некую часть приложения, которая состоит из нескольких экранов. К примеру модуль Profile - включает в себя главную страницу, экран редактирования профиля и тд (ну это что бы было понятнее :) )
И вот я в этих модулях всегда юзаю массив городов. А еще у меня есть выбранный город. И в зависимости от выбранного города, в каждом get/post запросе этот выбранный город будет лежать.
Как сейчас реализовано? Сейчас это просто синглтон с названием AppState, в котором лежит текущий выбранный город. Дальше есть синглтон AppArrays, в котором лежит как раз этот массив с городами. Объясните тупому - если синглтон это антипаттерн и он нарушает солид и вообще это глобальное состояние непокрываемое нормально тестами, то что тогда вместо этого использовать? UserDefaults? Это же тот же синглтон.
Может, какую-либо базу данных, а-ля CoreData или Realm? Или нужно создать какой-то НЕ синглтон класс и проставлять зависимость для каждого модуля в каком-нибудь Assembly классе (но это же муторно, особенно если приложение покрыто координаторами)? А как хранить состаяние пользователь авторизован или нет(авторизация по токену)? Вот на этот вопрос я не знаю ответа.
Второй вопрос - как вы храните данные в контроллерах? И вообще на сколько это правильно держать массив данных, который читает UITableView? Может это выносить в какой-то датастор? Куда вот допустим мне класть данные, которые пришли из сервера и я хочу их отобразить на UITableView? Из всех presеentation Layer архитектур эту проблему решает странный CleanSwift, в котором в интеракторе закрывается протоколом DataStore и проставляется зависимость в роутере. В вайпере, мвп такие проблемы почему-то не поднимаются.
Ответы (1 шт):
По поводу паттернов/антипаттернов/как лучше/как правильно постоянно ведутся споры и пишутся объемные труды. Если глянуть в общем, то наибольшее влияние на "бест практис" оказывают ограничения "железа", "так исторически сложилось" и лень.
К примеру, те же нейронные сети были описаны лет 80 назад, но "выстрелили" они только сейчас, так как только начало появляться достаточно мощное железо.
Так исторически сложилось – тут и так понятно.
Лень – один из главных двигателей прогресса. И улучшения кода :) Если раньше ЭВМ были огромными, слабыми, и нереально дорогими, на их фоне стоимость труда была относительно очень низкой, поэтому специалисты должны были бороться за каждый такт, оптимизировать и писать максимально понятно "для машины". Сейчас же стоимость "железа" относительно стоимости труда копеечная и поэтому нужно писать максимально понятно для себя и других, а для машины пусть уже компилятор поясняет.
Поэтому один из моих критериев хорошего кода примерно такой: если я написал что-то и через несколько месяцев, когда уже это забылось, чтобы повторно вникнуть в это "что-то" потребуется мало времени – код хороший. Если много времени и возникнут вопросы вида: "А это что за? Почему здесь так?" – код ужасный. Если кто-то другой будет работать с этим кодом и сможет быстро вникнуть – код хороший. Если будет вникать долго и возникнут ко мне вопросы "А это что за? Почему здесь так?" – ужасный.
VIPER, MVP, MVC - это, по сути, одно и то же. Просто с разной детализацией, структуризацией и ограничениями по организации. Все стремятся к стандартизации в типовых задачах.
Вы правильно заметили, что UserDefaults - это сиглтон в сухом остатке, как и любая база данных, UIApplication, да они повсюду.
И да, лучше закрывать протоколом, а Dependency Injection – наше всё. Но снова же, насколько оно нужно в каждом из конкретных случаев? Если это одноразовый прототип на коленке, чтобы показать и выбросить – зачем терять время? Если проект с перспективой поддержки и развития – тогда да, нужно задуматься о тестировании, организации и читаемости.