Senior
Šta znate o arhitekturi portova i adaptera?
sobes.tech АИ
Одговор од АИ
Архитектурата на портовете и адаптерите, известна също като хексагонална архитектура (Hexagonal Architecture), разделя логиката на приложението (Core) от външните зависимости (интерфейси на потребителите, бази данни, външни услуги).
Основни концепции:
- Порти: Определят интерфейсите, чрез които Core взаимодейства с външния свят. Портовете са два вида:
- Входни (Driving Ports): Използват се от външни същности за извикване на функционалността на Core (например, API интерфейс).
- Изходни (Driven Ports): Използват се от Core за извикване на функционалността на външни същности (например, интерфейс на repository за достъп до данни).
- Адаптери: Реализират портовете, свързвайки Core с конкретни външни технологии или рамки.
- Входни (Driving Adapters): Реализират входните портове и преобразуват входящите заявки от външната среда в извиквания към Core (например, REST контролер).
- Изходни (Driven Adapters): Реализират изходните портове и преобразуват извикванията от Core за взаимодействие с външната среда (например реализация на repository за работа с конкретна база данни).
- Core (Домен): Съдържа бизнес логиката на приложението. Той е напълно изолиран от външните детайли и взаимодейства с тях само чрез портове.
Предимства:
- Тестване: Изолацията на Core улеснява юнит тестовете на бизнес логиката без необходимост да се мокват сложни външни зависимости.
- Гъвкавост: Позволява лесно заместване или добавяне на нови външни технологии (бази данни, рамки) без промяна на Core. Достатъчно е да се напише нов адаптер за съществуващ порт.
- Чист код: Спомага за създаването на по-чист и поддържан код, като фокусира Core само върху бизнес правилата.
- Разделяне на отговорностите: Ясно разделя зоните на отговорност.
Връзка с Frontend:
В архитектурата на фронтенда, портовете и адаптерите се прилагат за:
- Разделяне на бизнес логиката на компонента от източниците на данни: Компонентът взаимодейства с "порт" (интерфейс), който може да бъде реализиран от различни "адаптери" (получаващи данни от API, Local Storage, тестови мокове и др.).
- Обработка на външни събития: Входните портове могат да представляват обработчици на събития от UI, а адаптерите преобразуват тези събития в извиквания към вътрешната логика.
- Инкапсулация на взаимодействието с външните библиотеки: Адаптерите могат да обвиват обращения към външни библиотеки (например, библиотека за работа с карти), предоставяйки на Core прост и стабилен интерфейс.
Пример на JavaScript (схема):
// Пример за изходен порт (интерфейс за получаване на данни)
class DataGateway {
getData() {
throw new Error("Методът getData трябва да бъде реализиран");
}
}
// Пример за изходен адаптер (реализация на порт за API)
class ApiDataGateway extends DataGateway {
async getData() {
const response = await fetch('/api/data');
return response.json();
}
}
// Пример за входен порт (интерфейс за бизнес логика)
class BusinessLogicPort {
constructor(dataGateway) {
this.dataGateway = dataGateway;
}
async processData() {
throw new Error("Метод processData трябва да бъде реализиран");
}
}
// Пример за Core (бизнес логика)
class MyBusinessLogic extends BusinessLogicPort {
async processData() {
const data = await this.dataGateway.getData();
// Логика за обработка на данните
console.log("Данните са обработени:", data);
return data;
}
}
// Пример за входен адаптер (използване на логиката в UI)
async function initApp() {
const apiGateway = new ApiDataGateway(); // Конкретен адаптер
const businessLogic = new MyBusinessLogic(apiGateway); // Core използва порт
await businessLogic.processData(); // Входен адаптер извиква Core
}
initApp();