Pull to refresh

Проверяем Архитектурные стили на движке Factorio (часть 1)

Reading time 28 min
Views 42K

Вводная

Добрый день всем, дорогие читатели!

Если вы хотя бы чуть-чуть имели неудачу пообщаться с Архитекторами, то знаете, что в их понимании не существует идеальной архитектуры ПО и вся их работа состоит во взвешивании плюсов и минусов того или иного Архитектурного стиля. И поскольку Архитектурных стилей много и каждый имеет свои преимущества (даже Монолит) и недостатки (даже Микросервисы) - работа архитектора состоит в попытках применения данных стилей на конкретный продукт и попыток предугадать, что из этого получит в итоге для бизнес-части.

Архитектурный стиль, иногда называемый архитектурным шаблоном – это набор принципов (высокоуровневая схема), обеспечивающая абстрактную инфраструктуру для семейства систем (StudFiles)

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

Factorio - компьютерная игра в жанре симулятора строительства и управления (Wikipedia)

Как сказал мой добрый друг-программист про Factorio: "Эту игру создали программисты для программистов" и эти слова плотно въелись в мою память. И реально игра в эту игру очень сильно напоминает процесс разработки ПО: можно просто строить как попало и прийти к полностью запутанной и сложнообслуживаемой системе, а можно подойти к вопросу с умом изначально и в итоге получить производительную и легкую в обслуживании систему (Прям как в жизни!)

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

Что мы будем делать?

Статья поделится на 7 частей:

  1. (эта) Вводная. Пробуем Монолит

  2. Пробуем Сервисо-ориентированную архитектуру

  3. Пробуем Основанную на сервисах архитектуру

  4. Пробуем Основанную на пространствах архитектуру

  5. Пробуем Событийно-управляемую архитектуру

  6. Пробуем Микросервисы

  7. Ищем новые Архитектурные стили

Мы будем брать какой-либо архитектурный стиль и будем попробовать реализовать её в игре Factorio, замерять и фиксировать различные параметры, а после будем сравнивать их. Собственно это всё: так мы сразу узнаем, какие Архитектурные стили хороши/плохи в сравнении друг с другом.

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

  1. запустить ракету в космос со спутником на борту

  2. перевести всё электрообеспечение на атомную энергетику и полностью отказаться от сжигания угля (оставить только для производства гранат, пластмасс и подобного сырья).

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

Далее у нас начнётся аналитика собранной информации: узнаем, как получается всё быстро, просто, понятно и дёшево. Тут мы сравним графики, различные аспекты производства и общие впечатления от работы с определённым стилем.

Ну и в конце, набравшись опыта и знаний, мы приступим к завершающей части: попробуем развернуть задание наизнанку и попробуем на основании уже сохранённых файлов игры Factorio найти концептуально новые Архитектурные стили.

Что ж, работы много, так что приступим!

Что у нас со стороны Архитектуры?

Начнём с того, что мы хотим привнести со стороны Архитектуры ПО в данный эксперимент.

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

Кратко опишем основные Архитектурные стили для освежения памяти или ввода в контекст.

Архитектурные стили

Монолит (Monolithic)

Собственно, начнём мы с оклемённым всеми Монолитом. Причина его включения в данный список проста: он всё ещё актуален и он всё ещё имеет свои преимущества.

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

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

Как ни крути, нам будет полезно сравнить остальные Архитектурные стили с Монолитом и ответить на вопрос: а действительно он так плох, как о нём говорят.

Сервисо-ориентированная архитектура (Service-Oriented Architecture или SOA)

Среди всех остальных Архитектурных стилей Сервисо-ориентированная самая непопулярная из-за её множества проблем, но именно она помогла отойти от концепции Монолита и тихо-мерно прийти к концепции Микросервисов.

Суть SOA заключается в попытке разбиения сервисов по логическим задачам и связывании их через некую "Сервисную шину". Сама шина занимается только тем, что забирает ответы от одних сервисов и передаёт этот ответ на выполнения другим, а потом забирает ответ и передаёт третьим и так далее до достижения некого финала (возврат ответа пользователю или занос результата в некое хранилище).

Как и Монолит, SOA так же имеет смысл внести в наш список для того, чтобы был предмет для сравнения.

Основанная на сервисах архитектура (Service-Based Architecture или SeBA)

Хоть от SOA от отказались как "неудачный опыт", найти что-либо в Гугле по нему было значительно легче, чем по Service-Based Architecture. Но сложно не невозможно, так что приступим.

Данный Архитектурный стиль является логическим развитием SOA и, относительно её, заключается в двух ключевых изменениях: первое, переход от Сервисной шины к API; второе, перевод логики определения передачи результатов сервиса на сам сервис (то есть теперь не шина решает, куда передать результат дальше на вычисление, а сам сервис). Если говорить проще, то SeBA является попытка сделать SOA проще для дальнейшей разработки. Ну и да: именно где-то тут начали пихать всё не в один исполняемый процесс, а переходить на мультипроцессное исполнение и ковайный API. А если ещё для каждого сервиса сделать свою БД и вынести Web-часть - уже получится знаменитая Микросервисная архитектура.

Эти изменения дали свои плюсы, но полностью ощутить мы их сможем только уже в ходе эксперимента.

Основанная на пространствах архитектура (Space-Based Architecture или SpBA)

Другая попытка отойти от проблем SOA есть данный Архитектурный стиль, но если SeBA нацелен больше на попытку упростить процесс разработки, SpBA нацелен на попытку решить проблему с масштабированием приложения для принятия больших нагрузок. Ну и тот факт, что информации в Гугле по SpBA значительно больше, чем по SeBA недвусмысленно говорит нам о том, что в мире ПО более важна именно работа под большой нагрузкой, чем обилие различных фич (но это не точно)

Кратно разберём данный Архитектурный стиль. В попытках принять большую нагрузку на своё приложение SOA ушло в чуть другую плоскость - использовать реплицированную In-Memory для хранения обрабатываемой информации, а так же небольшой модуль для управления всем этим процессом. Это даёт хороший буст в плане масштабировании, но и привносит ряд сложностей.

С продумыванием концепции In-Memory в Factorio у меня явно будут определённые сложности, но как-нибудь решим их.

Событийно-управляемая архитектура (Event-Driven Architecrute или EDA)

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

Если кратко разобрать принцип работы EDA, то можно сказать так: в SOA разбили Сервисную шину на очереди и управление очередью (т.н. "Брокер/Медиатор"). Теперь программистам достаточно кодить сами сервисы и просто задавать логику работы медиатра, а эксплуатации просто подключать к очередям столько экземпляров сервисов, сколько надо.

Самое плохое в данном Архитектурном стиле, что медиатор может работать в двух режимах: собственно, режим Брокера (тупая, заданная последовательность) и режим Медиатора (на основании внутренней логики). Как мы будем реализовывать это в Factorio и как нам реализовать два этих режима - ещё не понятней, чем с In-Memory (но это проблемы не мои... это проблемы будущего меня... так что... иди к чёрту будущий Я).

Микросервисный (Microservices)

У нас будет самый распиаренный Архитектурный стиль из всех актуальных - Его Превосходительство Миркосервисный Архитектурный стиль.

Если кратко, то его особенностью является разделение приложения на множество независимых друг от друга миниприложений (собственно, микросервисы), каждый из которых занимает только одной, вселенной ему частью логики. Общение между ними происходит по API. Логика передачи запроса тоже устанавливается каждым микросервисом самостоятельно. В общем и всё - ничего лишнего.

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

Что там со стороны Factorio?

Игра позиционирует себя больше как симулятор программиста, а не симулятор продукта, а значит нам придётся искать аналогии для сравнения их с реальным процессом производства ИТ-продукта. Так мы сможем чуть изменить понимание и правила игры для большей достоверности. В общем нужно, первое, провести аналогии каких-либо элементов и процессов игры с реальной разработкой; второе, подкорректировать правила игры (где-то облегчить, где-то усложнить и под.).

Итак, начнём с проведения аналогий и будем двигаться от общего к точечному

Организационные аналогии

Игра==Компания/Бизнес.

Тут всё просто: мы туда приходим, что-то строим, генерируем единицу пользы и жаждим получить со всего этого выгод

Планета==Проект.

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

Жуки==Бюджет.

В Мире/Проекте есть ограничивающий фактор, который ограничивает наш бесконечный рост. В компании это продуктовый бюджет, в Factorio - жуки. Если мы начнём разрастаться так, что бизнес уже начинает нервничать в виду возросших расходов на всё это добро - оно начнёт пихать в палки в колёса; если мы в ходе строительство своих зданий начнём загрязнением задевать территорию жуков - они начнут волноваться и нападать. Так или иначе, аналогия похожа: если мы переходим какие-либо пределы - начинается сопротивление. И чем дальше заходим, тем сопротивление больше. В игре жуки хорошо ещё тем, что чем больше вы хотите захватить территорий - тем сложнее эту территорию зачищать и оборонять (если кто не знает - чем дальше он спавна, тем сильнее охрана улий Жуков и тем их больше по количеству). Всё это просто идеально похоже на запрос дополнительного бюджета: чем больше/чаще мы его запрашиваем, тем больше/чаще ловим вопросы вида "Обоснуйте затраты".

Так же Жуки, при определённых обстоятельствах переквалифицируются в хакеров, но это мы рассмотрим ниже

Площадь==Расходы

Вытекающий из предыдущего пункта Жуков/Бюджета: если мы будем занимать малую площадь под свои заводы или обходиться компании малыми расходами - Бизнес нам слова не скажут. Соответственно, чем меньше у нас в итоге наши строения будут занимать площади, тем лучше мы справимся в плане расходов, но и тем больше проблем мы испытывает с ограниченным пространством (иначе говоря, можно сразу делать запас площади под постройки и сразу же наткнуться на Жуков/Бизнес, а можно экономить пространство, но зато лишний раз испытывать сложности с втулением вон той трубы через ровный строй заводов).

Исследования/Ракета==Доходы.

Что приносит Бизнесу доходы? Пользователи. Что хотят пользователи? Много фич. Что нужно сделать в Factorio? Добиться цели постройки ракеты. Что нужно, чтобы создать ракету? Провести тонны исследований и реализаций этих исследований.

В обоих случаях у нас работает правило "Чем быстрее, тем лучше", а значит тут мы попали в аналогию на 100%. В итоге у нас получается хорошая картина: чем быстрее мы сможем достичь конечной цели, тем лучше.

Единственное, тут есть пару оговорок:

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

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

Персонаж==Команда.

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

Месторождения==Пользователи.

Они приходят и просто вливают в наш продукт кучу запросов. Но Бизнес этому только рад и просит освоить ещё и ещё новых месторождений.

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

Технические аналогии

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

Конвейер/Трубы==Переменная.

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

Предметы/Жидкости==Данные.

Они хранятся либо в переменных (Конвейеры/Трубы типа ОЗУ), либо на долговременной памяти (Ящики/Резервуары типа ПЗУ). Соответственно, чем их больше, тем больше затрат на ту или иную ЗУ.

Завод/Фабрики/Печи==Вычисления.

Берём значение из переменных/конвейеров и как-то ими манипулируем в попытке добиться некого промежуточного итога.

Буры/Скважины==Браузер.

По сути это просто способ доставки запросов пользователей в наше приложение. Просто и тупо.

ЖД==Сеть.

Те же переменные с некой полезной информацией, но перемещаемой на большие расстояния. Ну и она не мгновенная и не резиновая - всё как в жизни.

Электроэнергия==Стенды.

Чем больше объёмов мы захотим, тем больше всего настроем и тем больше оно будет потреблять энергии. Большой проект будет требовать больше стендов как по количеству, так и по качеству, а затраты электроэнергии позволят это отследить в сумме. Так же это позволит нам ещё проверить соотношение площади застроек к потреблению электроэнергии и точно убедиться, что мы считаем Расходы верно.

Манипуляторы/Насосы==Программная логика.

Что-куда сунуть определяют именно всякие манипуляторы разных сортов и размеров (а для жидкостей - насосы). Они потребляют немного энергоресурсов, но их очень много.

Загрязнения==Перерасход.

Идеального кода/автоматики/стендов не бывает и по любому будет что-то неоптимизированно/криво/косо. Когда мы достигнем определённого Загрязнения/Перерасхода, то сразу же взбудоражутся Жуки/Бизнес и придётся иметь с ними дело. Именно поэтому я поставил переход на Атомную энергетику как основную цель. Именно поэтому у нас идёт настоящий пункт.

Стены/Турели==Отчёты/ИБ.

Жуки/Бизнес с определённого этапа развития продукта начнёт банально мешать производству: Бизнес будет требовать различные отчёты, объяснения, корректировки и прочее; Жуки - просто приходить и крушить. Постройка и обслуживание Стен и Турелей как раз является хорошим примером "отвлечения" на все эти мешающие аспекты.

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

Радары==Мониторинг.

Тут всё просто: затраты сравнительно малые, но позволяют следить за тем, что как работает.

Лаборатории==Бизнес-логика.

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

Ну и в целом всё. Всякие мелкий штуки вроде "Оружие", "Автомобиль", "ЛЭП" и прочее я классифицировать не буду т.к. они незначительные и больше запутают.

Соединяем Архитектуру и Игру

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

Например, если мы сравним игру с Монолитом и Микросервисами, то подход к постройку заводов будет кардинально разный:

Пока это план, а там в игре уже посмотрим как всё будет получаться.

Дальше, нам нужно будет сравнить все эти стили по ряду параметров и вот они:

Параметры
  • Evolvability - возможность развития. Показывает, как быстро продукт может обрастать различными фичами. Относительно игры, это скорость проведения исследований и скорость достижения двух, основных целей: запустить ракету и перейти на атомную энергетику. Замерять будем по ходу игры;

    • Сценарий:

      • Если выполнилось исследование или частично/полностью выполнилась цель игры - фиксируем время игры;

      • Повторять до победы.

  • Perfomance - производительность. Показывает, сколько пользователей сможет потянуть приложение. Относительно игры это соотношение производства сырья ключевых ресурсов (железные/медные плиты, различные микросхемы) к количеству финальных ресурсов (различные исследовательские пакеты, спутники, части ракеты, урановое топливо). Именно соотношение нам покажет на сколько нам придётся потратиться, чтобы сделать одну единицу пользы. Замерять будем после финала;

    • Сценарий:

      • Убиваем всех жуков;

      • Убираем манипуляторы к не целевым производствам;

      • Отключим пути для сырья от всего, кроме частей ракет и спутников;

      • Ждём, когда производство стабилизируется;

      • Замеряем производство частей ракет и спутников за 1 час.

  • Deployability - разворачивание. Насколько быстро можно развернуть второй и последующие экземпляры продукта. Опять же просто применим вертикальное масштабирование и замерим время. Замерять будем после финала;

    • Сценарий:

      • Убиваем жуков;

      • Изучаем скорость (10) и грузоподъёмность (3) дронов до 6;

      • Копируем основной завод на свободное место;

      • Засекаем время;

      • Строим второй завод из собственных запасов построек;

      • Подключаем столько же месторождений (только железо и медь);

      • Подключаем поставку воды;

      • Подключаем ЖД сеть.

  • Scalability - масштабирование. Оно показывает, насколько безболезненно приложение сможет вырасти горизонтально или вертикально. Под горизонтальным ростом у нас будет идти попытки увеличить производительность за счёт увеличения числа заводов в существующей цепочке; вертикальное - создание второй цепочки (за одно и проверим Deployability). Замерять будем после финала;

    • Сценарий:

      • Замеряем производство при вертикальном масштабировании:

        • Строим дополнительные фабрики на территории текущего завода;

        • Замеряем производство частей ракет и спутников за 1 час.

      • Замеряем производительность при горизонтальном масштабировании:

        • Строим вторую копию завода по чертежам (то, что делали в Deployability);

        • Подключаем новую ЖД-сеть к старой;

        • Удваиваемым количество поездов (только железо и уголь);

        • Замеряем производство частей ракет и спутников за 1 час.

      • Сравниваем полученный прирост после обоих типов масштабирования с тем, что мы получили Perfomance.

  • Agility - гибкость. Сколько времени требуется, чтобы разработать новую фичу. Относительно игры это сколько потребуется времени, чтобы открыть новое производство чего-либо. Замерять будем по ходу игры, но c момента изучения и внедрения ЖД;

    • Сценарий:

      • Если мы запускаем новое производство чего-либо необходимого на данный момент - фиксируем время;

      • Повторяем до победного.

  • Fault Tolerance - отказоустойчивость. Насколько приложение хорошо переживает разные сбоя. В игре будем пробовать "ломать" различные участки завода и смотреть, что из этого получится. Так как поломать систему можно двумя способами (кривыми руками и чрезмерной нагрузкой), то и реализуем мы два сценария. Замерять будем после финала;

    • Сценарий 1:

      • Отключаем подачу патронов в турели;

      • Засекаем время;

      • Убегаем в безопасное место;

      • Ждём, когда прекратится производство частей ракеты;

      • Фиксируем время.

    • Сценарий 2:

      • Фиксируем текущее количество поездов;

      • Спавним локомотивы, вагоны и топливо;

      • Засекаем время;

      • Равномерно заполняем ЖД поездами под разные маршруты. До упора. С паузами ~5 минут;

      • Ждём, когда прекратится производство частей ракеты;

      • Фиксируем время;

      • Фиксируем общее количество поездов

  • Configurability - возможность конфигурации. Как гибко можно управлять приложением для подстройки его под текущие приоритеты. Замерять будем путём попытки перевести избыток продукции на место, где испытывается недостаток (например, перевести всё на части ракеты). Замерять будем возможность сделать это и какой прирост получим к целевой продукции по факту реализации. Замерять будем во время игры, ближе к финалу;

    • Сценарии:

      • Фиксируем, какие производства мы перенаправляли;

      • По завершению - замеряем увеличение целевого производства за 1 час.

  • Domain Partitioning - разделение обязанностей. Если к приложению можно сказать, что вон та его часть отвечает за то-то и только за это - значит у нас хороший показатель. При этом, если у нас появляется множество мелких и плотно расположенных зон - значит это плохо. Замерять будем после финала;

    • Сценарий:

      • Делаем скриншот карты без отметок;

      • Цветами разделяем различные производства;

      • Считаем количество мелких, плотноприлегающих друг к другу зон.

  • Abstraction Level - абстрагирование. Показывает, насколько хорошо определённые компоненты приложения выполняют какую-то глобальную задачу (бизнес-логика, оркестрация, хранение и прочее). В игре мы поделим всю нашу карту на зоны "пользователи", "сырьё", "хранение" и прочее и попробуем связать всё это стрелками друг с другом. Если у нас получится много мелких зон с парой стрелок - это хуже, чем одна большая зона с множеством стрелок. Будем замерять после финала;

    • Сценарий:

      • Делаем скриншот карты без отметок;

      • Цветами разделяем следующие зоны:

        • Ресурсы - добыча их aka "Пользователи";

        • Переработка ресурсов - переработка сырья aka "Frontend";

        • Основной завод - центральное производство конечной продукты aka "Backend";

        • Элетро - электростанция aka "ЦОД";

        • Ж/Д - точка поставки ресурсов aka "API/HTTP(S)";

        • Хранилище - место складирования чего-либо aka "БД";

        • Шина - место логического управления производством ака "Оркестрация"

      • Замеряем, сколько зон пересекаются друг с другом и сколько из них дублируется.

  • Elacticity - эластичность. Как приложение может самоподстраиваться под текущую нагрузку. Тут уже отдельно замерять ничего не надо, а просто сложим показатели Scalability и Deployability. Замерять будем после финала.

    • Сценарий:

      • Получаем от горизонтального Scalability процент прироста производства;

      • Получаем от Deployability время разворачивания экземпляра завода;

      • Получаем некое контрольное число для сравнения по формуле: Scalability(%) x Deployability(min)

  • Testability - тестирование. Насколько хорошо приложение поддаётся тестированию. В игре мы будем пробовать находить узкие места при помощи буста входных ресурсов и замера производительности - наша задача тут, замерить сколько потратиться времени на сам замер и на попытки улучшения производительности. Будем замерять после финала;

    • Сценарий:

      • Целимся на производство частей ракеты:

        • Засекаем время;

        • Подключаем несколько бесконечных сундуков с компонентами для частей ракеты чуть дальше непосредственного места производства этих компонентов
          Замеряем производство частей ракеты за 1 час (это будет контрольный замер);

        • Фиксируем время;

        • Засекаем время;

        • Повторяем для компонентов для модулей управления ракетами, сплавов и замерим производство частей ракеты;

        • Замеряем производство частей ракеты за 1 час;

        • Фиксируем время;

        • Повторяем для сырья для компонентов для модулей управления ракетами, сплавов и замерим производство частей ракеты;

        • Замеряем производство частей ракеты за 1 час;

        • Получаем обзор того, где находятся наиболее медленные части производства.

  • Cost - стоимость. Насколько дорого обходится разработка и обслуживание продукта. По сути мы просто в игре замеряем площадь, занимаемой нашим заводом, общую площадь построек и, отдельно, сравним его с энергопотреблением. Замерять будем после финала.

    • Сценарий:

      • Делаем скриншот карты без отметок;

      • Узнаём координаты угловых частей общих построек;

      • Узнаём координаты угловых частей общего производства;

      • Высчитываем площадь двух получившихся фигур.

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

Правила игры

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

Правила игры
  • Режим игры - стандартный;

  • Всегда берём одну и ту же сгенерированную карту

    • Зерно - 2426146951

    • Ресурсы - стандартные;

    • Вода - максимальный масштаб, покрытие 50%;

    • Деревья - всё минимум

    • Скалы - отключены;

    • Тип местности - стандартный;

    • Враги:

      • Вражеские базы - стандартные

      • Размер начальной области без жуков - максимальная;

      • Экспансия - отключена;

      • Эволюция - отключена;

  • Сложность:

    • Стоимость рецептов - стандартная;

    • Загрязнение - стандартная;

    • Во время основной игры - можно использовать:

      • Команду на замер времени жизни карты - для фиксации времени важных событий;

      • Команду на вывод координат (мало ли пригодится);

      • Чит на перемотку времени. Стоять без дело придётся часто и пожалейте моё время

      • Чит на спав стартового комплекта вещей (об этом ниже) для идентичности лабораторных условий;

        • Если часть стартового комплекта потеряется во время игры (кроме тех, что с меткой "невосполнимый") - можно заспавнить новый взамен;

    • После финала - можно:

      • Всё вышеуказанное;

      • Чит на удаление врагов;

      • Чит на спавн вещей для создания логических цепей;

  • Искусственные ограничения:

    • Нельзя производить предметы руками - исключительно в зданиях. Причина проста - чтобы не сбивать ручным производство итоговую статистику;

    • Нельзя использовать "синие" типы конвейеров. Возьмём красные конвейера как максимально возможные для того, чтобы сравнение Архитектурных стилей было максимально лабораторным;

    • Нельзя уничтожать улии, кроме случая, когда он мешает строить (читай, помещается в экран рядом с постройкой). Ограничивающее меня правило, чтобы не было желания перебить всех жуков в округе и избавится от аспекта бизнеса и безопасности;

    • Нельзя наполнять заводы вручную - только выкладывать на конвейер (вручную или через манипулятор). Исключение - добавление твердотельного топлива. Сделано это, чтобы не возникал соблазн перетаскивать сырьё вручную в разные части базы и тем самым вручную увеличивать производительность (реально, выглятит так, как будто если посадить программиста на Прод, то он будет производить расчёты вместе с компьютером... бред);

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

    • Нельзя использовать логические сети до финала игры. Логические сети сильно скажутся на времени постройки завода: они имеют непредсказуемое время реализации и непредсказуемое окупаемость. И то и то будет паразитно в сравнении;

    • Нельзя ставить игру на паузу для продумывания дальнейших действий - пауза только для перерывов и естественных потребностей. Это позволит учитывать и время обдумывания какого-то решения, которое всегда присутствует в работе команды разработки. В общем, берём это в учёт;

    • Нельзя пользоваться чертежами, скачанными из Интернета или из предыдущих игр. Конечно, странно придумать программиста, не пользующемся StackOverflow, но помощь уже готовых чертежей выгладит сильно читерным (это как найти на StackOverflow не кусок полезного кода, а сразу идеально работающую программу). В общем, лучше просто это забанить и придумывать всё с нуля методом проб и ошибок;

    • Никаких модов. Только стандартный геймплей.

  • Искусственные привилегии:

    • Стартовый набор вещей:

      • Силовая броня МК2 х1

      • Портативный термоядерный реактор х2

      • Экзоскелет х4

      • ПНВ х1

      • Устройство игнорирования конвейров х1

      • Персональная дронстанция МК2 х4 (игра без дронов всё ровно что написание кода без копипаста)

      • Малый блок аккумуляторов х7

      • Строительные дроны х100

      • Автомобиль х1

      • Пистолет-пулемёт х1

      • Патроны х210 (невосп)

      • Деревянный ящик х100 (невосп)

      • Желтый конвейер х5000 (невосп)

      • Подземный желтый конвейер х100 (невосп)

      • Разделительный желтый конвейер х100 (невосп)

      • Желтый манипулятор х200 (невосп)

      • Красный манипулятор х100 (невосп)

      • Деревянный ЛЭП х1000 (невосп)

      • Труба х5 (невосп)

      • Бойлер х5 (невосп)

      • Паровой генератор х5 (невосп)

      • Бур х50 (невосп)

      • Насос х1 (невосп)

      • Твердотельный бур х31 (невосп)

      • Каменная печь х51 (невосп)

      • Серая фабрика х50 (невосп)

      • Разбитый корабль х1 (невосп)

      • Древесина х1 (невосп)

      • Пистолет х1 (невосп)

      • Железная плита х8 (невосп)

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

В общем, всё это выглядит вот так:

Ссылка на сценарий (Поместить в %USER%\AppData\Roaming\Factorio\scenarios)

Так же сценарий позволяет делать одну крутую вещь - записывать реплей.

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

Тактика/Стратегия

Как и любой проект, он начинает с пилота и каждый раз нам придётся начинать с постройки первых строений плюс-минус одинаково. Максимум, что мы сможем себе позволить тут - это представлять Архитектурный стиль нашего будущего завода и заранее стремиться строить под него. Именно поэтому прямо большой разницы в старте игры не будет, но как только будут изучены ЖД и грузовые поезда - с этого момента мы уже сможем сделать первую ЖД-сеть (подключить "пользователей") и дальше мы обязаны придерживаться выбранного Архитектурного стиля.

В итоге у нас должно получиться следующие жизненный циклы продукта:

  1. Пилот - просто налаживаем базовое производство, но ровно до тех пор, пока не изучим и не внедрим ЖД;

  2. Обрастание фичами - развиваем производства нашего завода, проводим большую часть исследований и плавно стремимся к конечным целям;

  3. Рывок до конечной цели - когда ракета и АЭС уже будет близко, то стоит переключить все ресурсы на неё, чтобы выпустить её быстрее. В общем, это Киллер-фича;

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

По ходу игры мы будем фиксировать следующие время:

  • Исследование завершилось;

  • Цель игры выполнена;

  • Новое производство чего-либо важного запущено;

  • Другие важные события, например:

    • Подключение пользователей;

    • Первая атака жуков;

    • Жуки сломали что-то важное;

    • Кончилось электричество;

    • Остановка производства исследований.

Все вышеуказанные временные замеры помогут нам в сравнении архитектурных стилей между собой.

Ну и приступаем!

Монолит

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

Особенности у нас такие:

  • ЖД используется только для сырья (ака Пользователи), а весь завод работает исключительно на конвейерах и трубах;

  • Выходящее из последнего пункта - всё будет находится рядом т.е. со стороны завод будет представлять из себя огромный комплекс.

Пилот

Старт был достаточно лихой: имея свободу в действиях и легко сделав базовое производство (плиты, первые колбы, ЖД). Проблемы начались когда я попытался внедрить ЖД: во-первых, к этому моменту уже опустошилось месторождение железа; во-вторых, поскольку у меня не было никакого запаса - резко возникла проблема с желтыми конвейерами (красные вообще еле производятся). В итоге пришлось останавливать производство железных и стальных плит и, буквально, выковыривать все некритичные части конвейера. В итоге их хватило тютелька-в-тютельку.

Обрастание фичами

Внедрение ЖД решила проблему с железом - я сразу получил буст по производству его раза в 3, но со сталью это проблема решилась не сразу и чувствую, что мы эту проблему будем испытывать ещё часто.

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

После того, как ЖД разогналось, ресурсов стало хватать вдоволь. Единственное, что сказывается ряд неудачных решений с синими колбами - их всё время не хватает, а разместить больше заводов не хватает места.

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

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

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

Когда запустилось АЭС сразу возник большой профицит в электроэнергии, а значит, что можно переходить на электрические печи. Займусь этим как только будет время.

Рывок до конечной цели

К моменту постройки Ракетной шахты у меня оставалось 3 видимые цели: перевести переплавку на электропечи, собрать ракету и произвести спутник. С двумя последними целями возникли проблемы.

Ракета собиралась медленно т.к. производилось очень мало Ракетных модулей, а производилось их очень мало из-за банального: не хватало "Зелёных" микросхем т.к. их перехватило производство "Синих" микросхем, а уже их перехватило производство "Жёлтых" колб. В итоге движение к двум конечным целям стали очень медленными. В итоге пришлось максимально искать "застойные" производства и перенаправлять их вышеуказанные цели.

В конце концов это помогло, правда производство стало прямо ощутимо запутанней.

Итого:

Затрачено реального времени 8 дней
Убито 32175 жуков

Видео реплея

Итоговая карта:

Файл с сохранением (Поместить в %USER%\AppData\Roaming\Factorio\saves)

Подведение итогов и эксплуатация

Далее смотрим, какие характеристики приложения у нас получились по окончанию разработки.

Evolvability

По ощущениям, разработка шла вполне ожидаемо (сначала очень быстро, а потом очень медленно), но тем не менее ощущается некоторое чувство сбалансированности. Однако дальше продолжать играть желания нет.

Итого у нас получилось:

Исследование

Время

Автоматизация

00:54:35

Логистический исследовательский пакет

01:01:53

Производство стали

01:04:37

Логистика

01:07:14

Пулемётная турель

01:08:41

Электроника

01:12:27

Логистика 2

01:29:01

Двигатель

01:38:41

Железные дороги

01:46:36

Автоматизация железных дорог

01:54:05

Железнодорожные сигналы

02:04:03

Военная промышленность

02:04:26

Каменная стена

02:04:45

Военная промышленность 2

02:05:47

Военный исследовательский пакет

02:08:42

Продвинутая металлургия

02:16:33

Огнестрельный урон

02:22:54

Скорострельность оружия

02:27:14

Огнестрельный урон 2

02:35:39

Скорострельность оружия 2

02:44:53

Огнестрельный урон 3

03:21:40

Быстрый манипулятор

03:22:17

Автоматизация 2

03:22:53

Транспортировка и хранение жидкостей

03:23:41

Вагон-цистерна

03:30:01

Переработка нефти

03:33:41

Скорость лабораторий

03:38:00

Скорость лабораторий 2

03:48:23

Электроснабжение 1

03:55:13

Обработка серы

04:08:43

Взрывчатые вещества

04:11:04

Аккумулятор

04:18:41

Пластмассы

04:31:33

Продвинутая электроника

04:52:07

Химические исследовательская пакет

04:57:29

Пояс для инструментов

05:04:18

Пакетный манипулятор

05:18:05

Бонус вместимости манипулятора 1

05:29:31

Бонус вместимости манипулятора 2

05:51:40

Модули

06:05:41

Модуль скорости

06:13:55

Модуль продуктивности

06:21:32

Стационарный аккумуляторы

06:43:18

Продуктивность добычи 1

07:26:42

Огнестрельный урон 4

07:43:50

Ворота

07:45:57

Оптика

07:46:10

Солнечная энергия

07:53:07

Скорострельность оружия 2

08:07:46

Горючие жидкости

09:11:45

Дрон-защитник

09:24:49

Количество следующих за персонажем дронов 1

09:58:13

Количество следующих за персонажем дронов 2

10:48:08

Бетон

10:52:31

Продвинутая переработка нефти

10:53:51

Смазочная жидкость

10:54:50

Продуктивность добычи 2

11:21:01

Переработка урана

11:33:58

Продвинутая металлургия 2

11:50:32

Ядерная энергия

12:37:14

Производственный исследовательский пакет

12:42:13

Конструкция малой плотности

13:02:14

Ракетное топливо

13:22:09

Процесс обогащения им. Коварекса

15:29:05

Переработка ядерного топлива

15:33:37

Электродвигатель

15:34:31

Робототехника

15:35:50

Скорость рабочего дрона 1

15:36:51

Сила торможения 2

15:37:14

Скорость рабочего дрона 2

15:38:35

Сила торможения 1

15:40:28

Продвинутая электроника 2

16:06:20

Вспомогательный исследовательский пакет

16:13:01

Скорость лабораторий 3

16:29:44

Скорострельность оружия 5

17:03:17

Сила торможения 3

17:19:43

Сила торможения 4

17:43:03

Сила торможения 5

18:13:07

Блок управления ракетой

19:15:06

Модуль скорости 2

19:16:09

Модуль продуктивности 2

19:17:12

Модуль продуктивности 3

19:25:36

Модуль скорости 3

19:34:08

Ракетная шахта

20:34:18

Космический исследовательский пакет

23:24:52

Если перевести это на диаграмму, то получим следующий график:

На графике видно ощутимый прирост при изучении Переработки Ядерного топлива и исследовании Космического пакета.

Agility

Что у нас по старту производств покажет следующая таблица:

Событие

Время

Первая лаборатория

00:52:56

Зелёные колбы

01:12:27

Производство красных конвейеров

01:44:19

Организовано ЖД производство

02:22:17

Черные колбы

02:24:34

Начато строительство ЖД

03:38:32

Запущена ЖД (железо)

06:35:07

Убрано старое производство (железо)

06:48:43

Переключено переплавка железных и стальных плит на ЖД

07:27:15

Первая атака жуков

08:10:37

Запущено выкачка нефти

09:08:44

Производство пластмассы

10:04:01

Производство синих колб

10:43:45

Производство мазута, дизеля и смазки

11:04:12

Производство соляной кислоты

11:20:06

Добыча урана

12:03:17

Переработка урана

12:20:23

Производство фиолетовых колб

12:59:12

Новая атака жуков

14:11:00

Процесс обогащения урана запущена

15:33:37

Поезда переведены на ракетное топливо

16:11:20

Запущено производство синих микросхем

16:35:14

Запущено производство жёлтых колб

18:02:56

Запущена АЭС

18:52:05

Запущено производство блоков управления ракетой

19:15:50

Запущена ЖД (камень)

19:32:27

Запущено производство ракетных шахт

20:56:03

Запущено производство частей ракет

21:01:03

Отказ от сжигания угля

22:20:34

Ракета собрана

23:18:24

Запущено производство спутников

23:19:52

Запущена ракета

23:47:36

В целом график более плавный, чем с Исследованиями и прямо явный стопор был только когда запускали ЖД (ака Пользователей):

Configurability

На конфигурировании было не много примеров, но цифры достаточно впечатляющие

Конфигурирование (Излишки на производство)

Прирост производства

Красные микросхемы на синие колбы

222,22%

Зелёные микросхемы на модули управления ракетой

900,00%

Железные плиты на стальные плиты

150,00%

Как и ожидалось, каждое конфигурирование увеличивало запутанность завода, но прирост часто того стоит.

Deployability

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

Подключить месторождения, ЖД, воду и прочее не составило труда. Ровно как и постороить основные здания. Проблема, как и ожидалась, была с Желтыми и, особенно, с Красными конвейерами - они сожрали две трети всего времени разворачивания. В итоге на полное разворачивание у меня ушло 7.88 часа, при этом через 3.3 часа у меня всё было уже настроено и я просто сидел и ждал, когда произведутся конвейера.

Событие

Количество минут (с нуля)

Нехватка конвейеров

200 минут

Запущено второе производство конвейеров

248 минут

Полный запуск второго завода

473 минут

Scalability/Perfomance/Testability

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

Производство

Производство базовое (контрольное)

При вертикальном масштабировании

При горизонтальном масштабировании

Части ракеты

99 ед/час (100%)

110 ед/час (111%)

192 ед/час (194%)

Спутник

2 ед/час (100%)

2 ед/час (100%)

3 ед/час (150%)

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

Горизонтально получилось удачней: если задублировать производство, то части ракеты стали производиться больше на 94%, а спутники на 50%

Если попробовать протестировать данную схему, то выяснится, что слабым звеном является именно производство компонентов ракеты т.к. даже при обилии ресурсов для создания Блоков управления ракетами, Конструкций малой плотности, Ракетного топлива и Спутников они не могут выдать сильно большего объёма, чем контрольный

Производство

Производство базовое (контрольное)

Тестирование на бесконечный спавн Конструкций малой плотности, Блоков управления ракетами, Ракетного топлива и Спутников

Тестирование на бесконечный спавн Плат всех цветов, Медных, Стальных и Железных плит, Ракетного топлива, Статичных аккумуляторов, Солнечных панелей и Радаров

Тестирование на бесконечный спавн Медных, Стальных, Железных и Пластмассовых плит, Серы и Дизельного топлива

Части ракеты

99 ед/час (100%)

757 ед/час (764%)

100 ед/час (101%)

99 ед/час (100%)

Спутник

2 ед/час (100%)

Вне учёта

47 ед/час (2350%)

2 ед/час (100%)

Время, затраченное на организацию тестирования

04:23

14:23

09:10

Elacticity

На основании двух вышеуказанных характеристик, можно сказать, что за 473 минут мы получаем прирост на 94% частей ракет и на 50% спутников.

Итого, умножаем это:

  • 0.94х473=444.6

  • 0.5х473=236.5

Оставим эти числа как некую оценку

Cost

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

Параметр

Значение

Площадь общая (любые постройки)

3402 m2

Площадь полезная (производственные здания)

2425 m2

Энергопотребление

125 МВт

Fault Tolerance

Тут всё просто: жуки прорвали оборону через 82 минуты. Будем использовать это число для сравнения.

С вторым вариантом (имитация DDoS) вышло интересней - на то, чтобы полностью застопорить работу завода путём посылания "паразитных" поездов (трафика), ушло 2:30:44 времени

По количеству поездов ситуация следующая:

Базовое количество поездов

Проблема стала видимой

Началось снижение производительности производства

Засорилась ЖД - стало сложно добавлять новые поезда

Полная остановка производства

19 (100%)

33 (173%)

68 (357%)

82 (431%)

110 (578%)

То есть в целом мы можем держать максимум 3-хкратную нагрузку. Примерно.

Domain Partitioning

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

В целом видна попытка выноса всего либо в прямоугольники, либо в линии, но не всё пошло так просто.

Итого:

  • Хорошо разграниченных зон: 33

  • Плотно стоящих зон: 30

В целом баланс хороший, но в идеале Плотно стоящих зон быть вообще не должно

Abstraction Level

Если же анализировать зоны по типу, то тут всё замечательней: явных пересечений нет, а отдельно стоящих зон вообще всего две (не считая "ресурсы"). Это означает следующее: на высоком уровне приложение будет понятно даже тому, кто недавно начал вливаться в работу над Проектом. Другое дело, что если он начнёт углубляться в некоторые зоны - там может зависнуть надолго.

Общий вывод по Монолиту

Пока ещё вышеуказанные данные являются голыми т.к. нам не с чем их сравнивать. Но в следующих статьях мы будем делать другие Архитектурные стили и сравнивать именно с Монолитом.

По собственным ощущениям скажу, что я вижу в Монолите следующие преимущества:

  • Бюджет - жуков мы задевали мало и только с одной стороны, а улии вообще не уничтожали. То есть мы смогли только чуть-чуть превысить бюджет. Энергопотребление так же выглядит низким.

  • Время - мы успели сделать всё почти за сутки, что является хорошим показателем. Всё потому-что мы следовали простому правилу "Нужно сделать - делаем"

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

Из ярких минусов можно выделить следующее:

  • Сложно расширяться - если впихнуть ещё ряд заводов кое-как можно, то вот сделать так, чтобы сырьё доходило до этих новых заводов, а не израсходовалось по пути - уже проблема.

  • Запутанное на низком уровне - я часто терялся на карте где какое производство у меня находится. И это ещё маленькие объёмы.

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

Отступление "Жёсткий монолит"

Где-то уже при создании Ракетной шахты я заметил, что в текущей игре я начал внутри Монолита применять другие Архитектурные стили типо SOA для Модулей управления ракетами. Они малы (по сути пару-тройку производств в цепочке), но уже могут влиять на конечный результат. То есть с одной стороны я показал, что те же Программисты тоже рано или поздно невольно начнут отходить от концепции Монолита; но с другой, я мог исказить свои замеры в текущей статье.

Где-то там у меня и родилась концепция "Жесткого монолита" - то есть взять за правило ни в коем случае не применять наработки из других Архитектурных стилей. Это сильно затянет игру и у меня сейчас нет ответа на вопрос "Нужно ли оно?". В общем, пока мы продолжаем работать с тем, что получилось, но если будет очевидно, что без этого замеры получились неточными или просто возникнет интерес сравнить ещё и его - сделаем это отдельной статьёй. Повторюсь, что тут я пытаюсь воссоздать условия реальной разработки некого приложения и я не уверен, что где-то есть команды разработки, которым на организационном уровне говорят "Пишите Монолит и не что иное". В общем, посмотрим...

Tags:
Hubs:
+25
Comments 24
Comments Comments 24

Articles