Перевод. Оригинальная статья Brian Faust
https://blog.ark.io/lets-explore-ark-core-v3-part-1-infrastructure-5c8ba13c9c42Давайте исследуем ARK Core v3: Часть 1 - ИнфраструктураЭто первая часть Let's Explore ARK Core, в которой описывается разработка следующего основного выпуска ARK Coreнаряду с некоторыми советами и рекомендациями о том, как начать работу с вкладом и созданием ваших идеи сегодня.
ВступлениеВ первой части этой серии мы сосредоточимся на улучшениях инфраструктуры, которые были реализованы в ARK Core 3.0. Эти улучшения включают в себя то, как приложение загружается, как компоненты подключены, и как стало легче расширять, дополнять и тестировать систему с вашей функциональностью без необходимости непосредственного изменения наших релизов, что приводит к конфликтам, которые становится утомительным для разрешения.
Прежде чем мы начнем, давайте установим предпосылки, в соответствии с которыми ARK Core 3.0 было начато, перечислив проблемы, которые были у ядра 2.0, как они возникли, а затем мы рассмотрим, как ARK Core 3.0 стремится решить их.
-Трудно модифицировать из-за хрупкой и тесно связанной архитектуры, где любое небольшое изменение может иметь непреднамеренное воздействие.
-Сложно использовать из-за отсутствия ясности, поскольку функции и конструкторы классов имеют множество аргументов, что затрудняет их использование и тестирование.
-Трудно переписать существующую функциональность, такую как логика консенсуса.
-Трудно протестировать из-за ранее упомянутой тесно связанной архитектуры, что, в свою очередь, затрудняет расширение из-за отсутствия доверия к альтернативным реализациям.
ПриложениеПриложение является центральной точкой входа в ARK Core. Оно отвечает за загрузку и проверку конфигураций, принимает решение о том, какие пакеты следует зарегистрировать, запускает пакеты и служит соединением для обмена состояниями между всеми пакетами, которые разработчики добавляют в установку.
Core 2.0 предоставлял экземпляр приложения, с которым было трудно работать, потому что он состоял только из жестко закодированных объектов, таких как менеджер конфигурации, который был недоступен, загрузчик пакетов был недоступен, не было простого способа определить пути или специфичные для среды среды и многое другое. Все эти факторы в совокупности сделали тестирование и разработку пакетов неоправданно сложными, поскольку опыт разработчика (DX) в конце концов оказался слишком утомительным.
Решение всех этих проблем в текущем состоянии было бы трудным, поэтому полная переработка с нуля была самым лучшим решением. Core 3.0 имеет совершенно новое решение, которое было переписано с нуля с учетом простоты, маштабируемости и тестируемости.
// Core 2.0
import { app } from "@arkecosystem/core-container";
process.env.CORE_NETWORK // get the name of the network
process.env.CORE_TOKEN // get the name of the token
app.resolve("..."); // resolve a generic value
app.resolvePlugin("..."); // resolve a plugin
app.resolveOptions("..."); // resolve the options of a plugin
// Core 3.0
import { app } from "@arkecosystem/core-container";
app.network() // get the name of the network
app.token() // get the name of the token
app.get("..."); // resolve a generic value
Как вы можете видеть в приведенном выше примере, используется меньше строк, и вы, вероятно, также заметили, что методы resolve Plugin и resolveOptions исчезли. Это изменение было сделано, чтобы ослабить взаимосвязьи дать разработчикам больше свободы в том, как они разрабатывают свои пакеты, хранят их конфигурацию и получают доступ ко всем данным из них.
Давайте посмотрим на приведенный ниже код, который взят из пакета @arkecosystem/core-api.
Как вы можете видеть в приведенном выше коде, весь контроль над тем, как происходит взаимосвязь и что разрешается из контейнера, находится в руках разработчика пакета, а не ядра, решающего, как ваши данные должны храниться. Пакеты больше не рассматриваются как специальные объекты, а скорее как поставщик, который предоставляет любое количество услуг для Core 3.0, в отличие от Core 2.0, при условии, что предоставляется одна услуга.
Не беспокойтесь о поставщиках услуг сейчас, мы рассмотрим их в части 2 и рассмотрим, как мы можем использовать их преимущества для создания гибких пакетов, которые расширяют функциональность Core 3.0.
Мы надеемся, что эта недавно предоставленная простота, маштабируемость и тестируемость побудит больше разработчиков участвовать в разработке Ark Core и пакетов для экосистемы, чтобы значительно улучшить то, что Ark Core способен делать.
КонтейнерКонтейнер-это то, что обеспечивает хлеб и масло, необходимые для создания прочного фундамента для инфраструктуры, необходимой для достижения целей, поставленных Ark Core 3.0. Это позволяет нам связывать значения, функции и классы в единую сущность, которая заботится о хранении и управлении всеми взаимодействиями с ними.
Core 2.0 использовало Awilix в качестве своего контейнера и обеспечивало оболочку вокруг него с момента его реализации. В то время это работало нормально, поскольку требования были довольно низкими, поскольку кодовая база была написана на JavaScript, что означало, что концепция интерфейсов недоступна, поэтому следовать принципу «Проектирование по контракту» было довольно сложно, так как обычно оно идет рука об руку с зависимостью. Принцип инверсии, который требует, чтобы вы полагались на абстракции, а не на конкретные инструменты.
Давайте посмотрим на принцип инверсии зависимости, чтобы определить, что будет дальше. Возьмите приведенный ниже код, вы можете подумать, что реализация хороша, так как машина - это просто машина, и какое это имеет значение, как она реализована.
Теперь у вас есть разумная реализация автомобиля, которую вы можете запустить. Ну, проблема, с которой вы столкнетесь, заключается в том, что в наши дни существуют различные типы автомобилей, некоторые работают на электричестве, а некоторые на дизельном топливе. С приведенной выше реализацией, это станет беспорядочным для реализации конкретной логики двигателя, поскольку вам придется использовать операторы if, чтобы решить, что следует сделать, чтобы запустить автомобиль.
Лучший подход-предоставить контракт реализации, который является абстрактным и не делает никаких предположений о реализации, поскольку это детали, которые не должны касаться вашего приложения, когда оно потребляет сущность car. Автомобиль должен просто завестись, электрический или дизельный.
Если мы возьмем вышеприведенную реализацию и совместим ее с принципом инверсии зависимости, вы заметите, что мы больше не связаны с реализацией конкретного автомобиля, а скорее с договором на реализацию автомобиля, который затем будет преобразован в реализацию с электро или дизелем. Преимущества этого состоят в том, что нам не нужно ссылаться на конкретные классы, а также не нужно беспокоиться о том, как что-то реализовано, если это удовлетворяет указанному нами контракту.
Awilix to InversifyCore 3.0 заменил Awilix на InversifyJS. Мощная и легкая инверсия контейнера управления для приложений JavaScript и Node.js на базе TypeScript.
Теперь вы можете задаться вопросом, почему мы решили заменить контейнер, если Awilix выполнял свою работу. Основная причина заключается в том, что Inversify разработан для TypeScript, что означает, что истинное внедрение зависимостей возможно, когда вы связываете контракты реализаций (интерфейсы) с конкретными реализациями. Awilix пытается обслуживать JavaScript, поддерживая TypeScript посредством определений типов, что означает, что вы получаете преимущество подсказок типов, но не возможность использовать интерфейсы так, как это возможно с Inversify.
Использование нового контейнераИспользование нового контейнера с его полными возможностями становится возможным из-за двух факторов.
-Можно получить экземпляр контейнера, который используется внутри, а не просто оболочку, как это было в случае с Awilix. Это означает, что у вас есть доступ ко всем методам, доступным через Inversify.
-Прямо открывая контейнер вместо его упаковки, мы больше не делаем никаких предположений о том, как разработчик планирует использовать его, и в конечном итоге ограничивают то, что он может сделать.
Теперь это звучит замечательно на бумаге, но вы, вероятно, спрашиваете себя, какого черта вы действительно получаете от этого. Давайте проиллюстрируем преимущества несколькими примерами из самого Core 3.0.
Как вы можете видеть, возможности и синтаксис нового контейнера выразительны и просты, не отказываясь ни от какой функциональности. Мы считаем, что эта простота обеспечит лучший опыт разработчика в целом и даст разработчикам пакетов больше свободы и контроля.
Это только малая часть, на что способен Inversify, поэтому обязательно посмотрите официальный github Inversify и документацию. Посетите их github и Wiki, чтобы получить более подробное руководство о том, как работает контейнер и на что он способен.
https://github.com/inversify/InversifyJS#the-inversifyjs-features-and-apihttps://github.com/inversify/InversifyJS/tree/master/wiki