Begin /* Покер на конечных автоматах. Архитектура
Отличие от дизайна
Программистская терминология характеризуется одновременно своей специфичностью, когда термин обозначает весьма конкретный феномен, когда для каждого конкретного термина существует свое определение, и, вместе с этим, отсутствием отдельных собственных слов для этого. Программисты берут слово из какой-то совершенно общей области знаний и сопоставляют его с каким-то своим понятием. Файл, сокет, семафор, баг, фича, шаблон, проект, дизайн... Так и в случае с программной "архитектурой" - это не совсем, а скорее совсем не то, что под этим понимает строитель или любой другой непосвященный обыватель. Собственно общего между обыкновенной архитектурой и архитектурой программной одно - это некий уровень или стадия процесса создания. Архитектура это наиболее абстрактное и общее, а соответственно и одно из начальных описаний объекта, который предстоит построить. До архитектуры идет в общем случае только формулировка требований - техническое задание.
Дальше в общем-то никакого отношения к архитектуре в общем смысле, архитектура программного продукта не имеет. Это никак не выбор местности, ни общий ландшафтный план, ни подбор материалов и фундамента, ни подсчет каких бы-то ни было ресурсов. Архитектура ПО это первичное разбиение технического задания на подзадачи и определение структурных элементов будущего продукта. Это могут быть модули, компоненты, слои, интерфейсы. Архитектура определяет по большей части взаимодействие этих элементов между собой для максимальной оптимизации процесса реализации и дальнейшей эксплуатации.
В строительстве, конечно, так же продумываются общие принципы того, как в дальнейшем будет строиться, обслуживаться и эксплуатироваться объект, но речь здесь идет как правило о материальных ресурсах: какие строительные материалы доступны в конкретной географической местности, какие технологические и человеческие ресурсы потребуются для реализации. Часто строительный проект предполагает строительство множества побочных обслуживающих строений, разработки полезных ископаемых, дополнительные логистические и транспортные решения. Архитектура ПО так же может требовать вполне конкретных материальных ресурсов, таких как вычислительные мощности, хранилища данных, сети передачи данных и кадровый ресурс. Но в конечном итоге цель архитектуры ПО сводится к информационному взаимодействию. Материальные ресурсы как правило рассматриваются с точки зрения побочного эффекта. Если архитектура жилого массива в основном продиктована такими внешними факторами как климат, водоснабжение, транспортная, хозяйственная, энергетическая инфраструктура и собственно потребность в нем будущих обитателей, то для программы важнее то каким образом устроены коммуникации между пользователями, а подводка нужных кабелей и установка новых железок, наим и обучение программистов для этого дело поправимое и менее значительное.
А вот с дизайном все чуть проще. Дизайн программного продукта или его компонента как термин в принципе достаточно хорошо коррелирует с общеупотребительным значением этого слова. Дизайн это принципиальная схема, того как должна работать программа. Это все еще не конкретное указание к способу реализации, но уже и не архитектурное решение. Если архитектор здания планирует материальную основу, связывает доступные ресурсы и требования, определяет общий внешний вид и функциональное назначение всего объекта, то дизайнер разрабатывает концепцию устройства внутренних пространств, служебных помещений, технологических каналов и ниш, конкретизирует внешний вид конструкций и материалы элементов для взаимодействия с конкретным пользователем. Дизайн предполагает конкретный функционал тех или иных элементов, но не указывает как и кем именно он будет реализован.
Дизайн программы в данном конкретном случае это то, что было описано в первой части цикла, в которой описывается как-раз общая концепция того как внутри будет устроена программа - ее основной функционал - бек-энд - движок. Так же с точки зрения дизайна будет далее описан интерфейс взаимодействия с конечным пользователем. Будет ли это клиентское приложение, веб-интерфейс или чат-бот - фронт-энд - не принципиально. А вот то как будет устроено взаимодействие между фронтом и беком, где это все будет расположено, будут ли при этом задействованы какие-то промежуточные слои и компоненты - это вопрос архитектуры.
Технологический процесс
По поводу того как правильно надо создавать годные программные продукты, в том числе как правильно выстроить архитектуру и дизайн, что за чем следует и в каких рамках должен быть выполнен тот или иной этап сказано более чем достаточно. Я бы даже сказал слишком много. От частных практик индивидуальных программистов, до государственных стандартов и регламентов транснациональных софтверных гигантов. От измышлений отдельных специалистов, до комплексных научных трудов команд уважаемых академиков. С другой стороны, все это говорит о том, что технологический процесс создания программ, относительно других индустрий, все еще молод и выработка общих подходов к этой процедуре еще впереди.
Я же в свою очередь осмелюсь представить свой вариант видения технологического процесса относительно того, чем я сам же и занимаюсь. То есть небольшие проекты в части автоматизации бизнес-процессов. Схема постоянно редактируется и является лишь моей компиляцией разных источников с моими же домыслами. Ей я и буду пользоваться в дальнейшем.
Здесь процесс не поделен на этапы напрямую. Здесь речь в основном о последовательности принимаемых решений и документировании процесса. Однако понятно, что сверху вниз имеются ввиду как-раз этапы где первые верхние два блока отвечают за управленческие решения, экономические предпосылки и техническое задание. Далее за архитектуру и дизайн отвечают блоки до непосредственной реализации "Startup procedures". Они переплетены хитрым образом с наличием все тех же материальных ресурсов и доступных (моих) компетенций. Здесь видно, что архитектура зависит от ресурсов как при обычном планировании, но это всего лишь продиктовано тем, что именно в моем конкретном случае они ограничены. На самом же деле блоки выбора моделей данных и архитектурных шаблонов проектирования могут стоять, и как правило стоят, выше методологии разработки, а уж тем более платформы и компетенций. Это к слову о влиянии внешних факторов на архитектуру программную и обычную.
Например, при создании учебного или демонстрационного проекта я в праве перескочить с уровня требований к архитектурному шаблону. Так что бы он максимально отвечал не существующим компетенциям и кадровым ресурсам, а был в первую очередь правильным с точки зрения взаимодействия компонентов информационной системы. С другой стороны, так как это публичный проект, то на архитектуру все-таки снаружи должен повлиять фактор доступности. То есть проект должен быть максимально открыт и неплохо бы сделать его доступным не только с личной рабочей станции. Можно раскрыть исходный код и предложить каждому самостоятельно разобраться с запуском. Но так же понятно, что можно развернуть рабочий экземпляр на общедоступном ресурсе. Можно это все дело разместить на каком-нибудь хостинге общего назначения, который как правило либо платный, либо подразумевает какие-то ограничения или рекламу. А еще можно разместить в модном нынче облачном хостинге в качестве сервиса. Это сразу обеспечивает доступность и вместе с этим минимальные расходы, что тоже в данном конкретном случае является определяющим фактором. В принципе эти обстоятельства могут просто являться частью требований в техническом задании и, таким образом схема процесса в этом смысле не нарушается.
Сферический покер в облаке
Облако - еще один программистский, в основе своей, термин, взятый из обычного словаря в качестве метафоры. В облаках программных нет никаких молекул водяного пара или какого-то другого газа. Они ни где не летают, они не белые, из них не идет дождь, не сверкают в них молнии, но вот тем не менее выдумщики программисты взяли именно это слово. А может это были маркетологи. Что ж, тем не менее, в облаках компьютерных и обычных есть нечто общее. Это, скажем так, некая бесформенность, неосязаемость. Облако оно вроде бы где-то есть, но определенно очертить границы облака не получается. Так же и компьютерное облако, в отличии от "железных" или даже виртуальных хостнигов, не имеет конкретных характеристик, вычислительных ресурсов, да и вообще какой-либо физической платформы. С этой точки зрения термин довольно хороший.
Облако это некоторая абстрактная среда для выполнения абстрактного же кода. Единственная точка соприкосновения с этим абстрактным кодом в облаке и внешним миром это URL API этого кода. По сути облако это та самая максимально абстрактная машина, у которой нет никаких технических характеристик, ограничений, внешних устройств - только вычислительное ядро, которое умеет выполнять алгоритмы на фактически любых языках описания алгоритмов. Более того, программы могут общаться между собой внутри облака, так как будто это одна какая-то физическая машина, с установленными в ней разнообразными службами. Что и делает такой подход настолько популярным нынче. Плюс - гибкая тарифная политика.
Что из себя представляет абстрактная игра в облаке? Это всего лишь некая конструкция, принимающая на вход события от абстрактных игроков и выдающая на выходе абстрактные же результаты этих действий. Один игрок повысил ставку, игра поменяла одно состояние в другое, второй игрок уже не может пропустить ход, ему нужно выполнить одно из трех действий: пас, ответ или повышение ставки. Игра на все действия отличные от этих трех должна отвечать ошибкой. Этим будет заниматься автомат, который в первой части и который про дизайн. Архитектура же заключается в том, что таким образом "движок" игры можно отделить от всего остального мира посредством некоего шлюза передачи событий и реакций на них. Интерфейс между конечном пользователем в такой архитектуре будет расшифровывать конкретные действия игроков и обрабатывать ответные реакции от движка. Как он это будет делать, с помощью ли графического интерфейса элементами управления, расшифровкой ли текста, распознаванием ли голоса и визуальных образов - так же вопрос дизайна. Обычно такой компонент называют клиентским слоем или в просторечии "фронт". Вот в общем и вся архитектура.
Есть, разумеется, и другие вопросы, касающиеся хранилища состояний автомата, производительности, многопользовательского доступа, безопасности и прочего, но глобально игра это два программных слоя взаимодействующих между собой. Взаимодействие при этом может быть построено как внутри облака, посредством служб предоставляемых этим облаком, брокера сообщений например, так и посредством внешнего API, к которому можно подключаться с некой клиентской программы.
Гнильца в Датском королевстве
Звучит все просто и логично, если бы не пара оговорок. В реальной жизни конечно же не все так гладко. Во-первых реализация этих облаков все-таки не идеальная. Они есть разные, с разными тарифными планами, с разными службами, понимающие разные алгоритмические языки. И из этого зоопарка нужно выбрать подходящий. Когда речь идет о "proof of concept" особой разницы нет. Однако, для более серьезных задач подумать придется крепко изначально, так как миграция с одного облака на другое уже существующей конструкции может оказаться проблематичной, если не невозможной.
Во-вторых, как-раз при эксплуатации низко нагруженных программ облака имеют ряд недостатков. Программа, которая вызывается редко имеет тенденцию убираться все глубже и глубже в более и более медленные реальные физические хранилища. Таким образом облака экономят на ресурсах, которые понятно все же конечны и стоят денег. Причем чем больше программа, чем больше в ней зависимостей, тем больше времени будет затрачиваться на вытягивание ее из медленных хранилищ в оперативный кэш облака. Программа с низкой и редкой нагрузкой соответственно должна быть компактной и иметь меньше зависимостей. При каждом импорте следует крепко задуматься, стоит ли оно того увеличения времени отклика. И замерять это время фактически придется как-то руками.
Впрочем, как-раз таки дизайн программы в виде автомата, как-раз то решение, которое позволит программе быть компактной. Особенно если реализовать автомат без привлечения каких-то сложных, хитровыдуманных, универсальных фреймворков. И это именно то чем я собираюсь заняться - сделать автомат самостоятельно в объеме необходимом и достаточном для реализации игры. Большой проблемы в том, что иногда игра будет подтормаживать на сотню миллисекунд или даже на секунду, в данном случае нет.
Не так безоблачно обстоят дела и с управлением облачными сервисами. Можно, конечно, дойти до всего методом тыка, но лучше все-таки что бы кто-то показал как это все работает. Благо нынче учебных пособий и видеороликов достаточно, что бы осилить замысловатые команды и веб-интерфейсы облачных систем. Какие-то из них достаточно логичны и очевидны, какие-то требуют достаточно емкого понимания того что на самом деле происходит под капотом разных кнопочек и сценариев. Одной из облачных систем, в которой выдержан некий баланс между простотой и функциональностью, пожалуй является поделка от Google. Но исторически лично я впервые ознакомился с AWS господина Безоса. Не сказать, что там все так уж сложно, но некий элемент избыточной функциональности, особенно на старте, прямо скажем, присутствует. Особенно учитывая то, что каждый производитель стремится назвать свои, в общем-то более или менее одинаковые по смыслу, подсистемы какими-то яркими и оригинальными названиями. Тут уже явно поработали граждане маркетологи, никакой связи смыслов или метафор вы в наименованиях не обнаружите. В общем, как бы то ни было, AWS.
Serverless
Работать с облаком Амазона можно тремя более или менее разными способами. Первый и самый очевидный - веб-интерфейс - то что обычно приходит в голову новичку. Хочется посмотреть, так сказать, прощупать. Тут то и становится несколько больно, от безобразного количества новых словечек и весьма не очевидных способов их подключения и использования. Нужно иметь очень хорошее представление что же на самом деле означают ES2, EKS, RDS, VPC и прочие заклинания.
Впрочем, предварительно изучить внутреннюю терминологию придется и при втором способе работы - через консольное приложение. Это второй способ. Он не проще чем веб-интерфейс, но как-то, знаете, ближе к телу. Приходит понимание что и зачем надо разворачивать, в какой очередности. Становится более или менее понятно, как можно автоматизировать этот процесс средствами других инструментов.
Есть и третий и, как мне показалось, наиболее гуманный способ взаимодействия с облачным провайдером это через специальный инструмент незатейливо названый "serverless". Это специальный фреймворк разработчика для создания, собственно, serverless приложений для AWS. Видимо кому-то ну очень припекло. Но, опять же, надо иметь четкое системное понимание того что происходит. На примерах и коротких туториалах далеко не уплыть. Тем не менее вот. AWS + Serverless + Maven + IntelliJ IDEA вроде как должны облегчить жизнь программиста на столько, что как будто-бы вся боль настройки и развертывания должна свестись к паре толковых и ловких движений. И позволить программисту сконцентрироваться на логике, а не на нюансах использования всяких хитрых команд и ключей к ним.