Pull to refresh

Вещи, которые мы хотим сделать «потом»

Reading time 6 min
Views 21K
Известно, что ошибки проще не допускать, чем исправлять и чем позже найдена ошибка, тем сложнее ее исправить. Не смотря на это у всех нас есть менеджеры дедлайны и тот кусок кода, который надо бы исправить после релиза.



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

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

База данных

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

Индексы и констрейнты

Традиционно проставить индексы и констрейнты как-то забывается. Особо забывчивые пренебрегают даже форен-ключами. Так и получаются странные ошибки из области db inconsistency. Отсутствие констрейнтов позволяет перевести БД в несогласованное состояние, то есть в такое, которое разработчик не предполагал. Вылавливать и исправлять такие ошибки долго и муторно.

Эпизодически возникает желание засунуть в БД JSON или XML, чтобы быстрее передать в слой представления. Идея по своему хорошая, но таким образом теряется основная сильная сторона классических SQL-решений. Рано или поздно вас попросят отсортировать выдачу и это будет неприятно. Хочется JSON — запросто. Возьмите монгу или что-то другое no-sql'ное и выбирайте, что вам дороже целостность данных или скорость доступа.

Кроме этого, БД-традиционно самое узкое место с точки зрения производительности. Как вы будете это разруливать? Может быть хватит слегка денормализовать БД или воткнуть CQRS или можно все удачно закешировать? Серебряных пуль, как обычно нет. Все зависит от специфики приложения. Все эти вопросы лучше задать себе заранее. Я не призываю стрелять из пушки по воробьям. На начальном этапе все это может казать жутким оверхедом и реализовывать супер-архитектуру сразу не нужно. Гораздо разумнее писать достаточно хороший на этом этапе код, но держать в голове план развития приложения на пару шагов вперед все-таки следует, чтобы не было мучительно больно потом.

Слои приложения и юнит-тесты

Вот это место я уж никогда не буду менять… Так думал я когда-то, пока как-то раз мне не пришлось сменить фундаментальную логику приложения. Софт продает билеты и, в общем, однажды пришлось поменять логику заведения тех самых билетов. Это стоило мне двухнедельного рефакторинга, в ходе которого, я выстроил в приложении новый слой бизнес-логики, потому что предыдущий мы тестировали только на уровне интеграционных тестов и замокать БД было просто невозможно. Слои DTO и Entity были перемешаны. Невозможность тестирования при этом не самая большая головная боль сильной связанности.

Отсутствие порядка в слоях приложения говорит об отсутствии порядка в голове разработчика. Каждый новый фича-реквест начинает представлять собой очередной хак в самом неожиданном месте и вот уже бизнес-логика приложения равномерно размазана по всему коду. Такой код просто невозможно поменять, не создав при этом какой-нибудь побочный эффект, как всегда неожиданный, и в самый неподходящий момент. Так что ни одного серьезного приложения без тестов я уже давно не пишу. С юнитами просто невозможно перемешать слои приложения. У вас просто не получится написать тест, а это заставит критически переосмыслить текущую архитектуру.

Null Reference или защитное программирование

Долгое время я считал «пусть падает», ведь я никогда не передаю null-ссылок. И это работало для меня. Со временм я заметил, что таким образом код проверок на NULL начинает как плавленный сыр растекаться по всему приложению. В добавок, не все разработчики, с которыми я работал проверяли свои значения на NULL. И вот что я заметил: писать защитные конструкции — утомительное занятие, поэтому я автоматически стал писать код так, чтобы свести количество этих проверок к минимуму. Это положительно сказалось на дизайне системы в целом. Кода стало меньше, код стал лучше структурирован. Я посматриваю на возможности AOP, чтобы сделать проверки на NULL декларативными, но пока мне хорошо и так.

Швы приложения и SRP

Как и в случае с БД слои приложения служат лишь одной цели — дать возможность в будущем быстро и безболезненно заменить часть вашей системы. Создать IFileStorage с единственной реализаций SimpleFileStorage гораздо проще, чем прочесывать все приложение в поисках записи в файловую систему, потому что вы решили переехать в облако. С опытом начинаешь уже кишками (или иными частями тела) чувствовать места, которые вероятнее всего изменятся. Каждый раз, нарушая SRP вы экономите минуты или часы своего времени сейчас, которые выльются в дни и недели потом. Быстро да, менеджер рад… сейчас. Потом возникнут вопросы, почему внести это мааааа-ленькое изменение так долго.

Масштабирование web-сервера

Невозможно постоянно наращивать мощности сервера. Рано или поздно вы упретесь в возможности канала. И вот тут ВНЕЗАПНО всплывут все статические переменные, которые вы использовали напрямую. Вообще горизонтальное масштабирование системы на всех уровнях это то, о чем нужно подумать заранее. И здесь снова, можно все-также не париться и писать в статические переменные ровно до того момента, пока вы не вставите еще один сервер. С учетом одного но. Делайте все эти грязные вещи внутри своего IDataProvier или IProblemResolver. Тогда придется менять только один класс, а не собирать изменения по всему коду.

ДевОпс

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

Как-то раз мы разворачивали систему заказчика два дня на наших серверах. В ход пошло все: бубуен, тувинское народное горловое пение и самое главное Config Tool. Без того самого конфиг тула вообще никто не мог заставить приложение работать. И я был бы счастлив, если бы этот тул был инсталлятором. К сожалению, Config Tool представлял собой консольное приложение, которое надо было запускать в строго определенных условиях, после чего выкладывать архивы и разворачивать все руками на серверах. Однако, без Config Tool сконфигурировать всю пачку приложений вообще никто не мог. Софтина многозначительно валилось с ошибками, совершенно не отражающими суть проблемы: например ругалось на сертификат, хотя проблема была в авторизации.

Ruby on Rails и ASP.NET давно уже предлагают и даже навязывают (и это правильно) простые и крутые способы разворачивания приложений. Пользуйтесь теми фишками, которые предлагает ваша среда. А если не предлагает, всегда можно сделать процесс разворачивания чуточку проще. Это касается не только уровня приложения. Полезно держать это в голове еще до того, как будет написана первая строчка кода. Если вы хотите поместить конфиг в базу данных, добавьте миграцию, чтобы в 2:00 AM не редактировать базу данных на продакшне, потому что там (упс!) старый конфиг. Другие разработчики в вашей команде тоже будут благодарны, если после очередного апдейта из VCS у них ничего не свалится от того, что теперь наше приложение работает с мега-супер новой штукой, которую нужно предварительно настроить с помощью бубна, тувинского народного горлового пения и духов.

Многопоточное программирование

Вы точно уверены, что вы умеете писать многопоточный код? Вы точно уверены, что оно вам надо вообще? Везде, где можно не писать многопоточного кода, пожалуйста, не пишите его. Интересно, клево да. И даже, возможно, на некоторых наборах данных на вашей машине он работает правильно. Многопоточное программирование — совершенно отдельная область знаний, а писать многопоточные приложения в разы сложнее однопоточных. Ровно как и отлаживать. Поберегите нервы себе и вашим коллегами.

Казалось бы, вещи простые. Про все это говорили. Однако это то, что доставляет мне больше всего проблем в повседневной работе.
Tags:
Hubs:
+9
Comments 10
Comments Comments 10

Articles