Вопрос проверяет понимание паттерна единого коннектора для унификации приёма данных из разных источников и форматов.
Паттерн единого коннектора (Unified Connector) решает проблему интеграции с различными источниками данных, которые могут предоставлять информацию в разных форматах (XML, JSON, GraphQL). Основная идея — создать абстрактный интерфейс, который скрывает детали реализации каждого формата и предоставляет единый способ получения данных.
Для каждого формата создаётся отдельный класс-адаптер, реализующий общий интерфейс. Адаптер отвечает за подключение к источнику, парсинг данных и преобразование их в единый внутренний формат (например, объект JavaScript).
// Единый интерфейс коннектора
class DataConnector {
async fetchData(query) {
throw new Error('Must implement fetchData');
}
}
// Адаптер для JSON
class JSONConnector extends DataConnector {
constructor(url) {
super();
this.url = url;
}
async fetchData(query) {
const response = await fetch(this.url);
const data = await response.json();
return this.transform(data);
}
transform(data) {
// Преобразование в единый формат
return { items: data.results };
}
}
// Адаптер для XML
class XMLConnector extends DataConnector {
constructor(url) {
super();
this.url = url;
}
async fetchData(query) {
const response = await fetch(this.url);
const text = await response.text();
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(text, 'text/xml');
return this.transform(xmlDoc);
}
transform(xmlDoc) {
// Преобразование XML в единый формат
const items = Array.from(xmlDoc.querySelectorAll('item')).map(el => ({
id: el.querySelector('id').textContent,
name: el.querySelector('name').textContent
}));
return { items };
}
}
// Адаптер для GraphQL
class GraphQLConnector extends DataConnector {
constructor(endpoint) {
super();
this.endpoint = endpoint;
}
async fetchData(query) {
const response = await fetch(this.endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
});
const result = await response.json();
return this.transform(result);
}
transform(data) {
// Преобразование GraphQL ответа в единый формат
return { items: data.data.items };
}
}Клиентский код использует единый интерфейс, не зная, какой конкретный коннектор используется. Это упрощает добавление новых форматов и делает систему гибкой.
async function processData(connector) {
const data = await connector.fetchData('{ items { id name } }');
console.log(data.items);
}
const jsonConnector = new JSONConnector('https://api.example.com/data');
const xmlConnector = new XMLConnector('https://api.example.com/data.xml');
const graphqlConnector = new GraphQLConnector('https://api.example.com/graphql');
processData(jsonConnector);
processData(xmlConnector);
processData(graphqlConnector);Паттерн единого коннектора стоит применять в системах, где необходимо интегрироваться с множеством разнородных источников данных. Он обеспечивает единообразие кода, упрощает поддержку и расширение функциональности, а также снижает связанность между компонентами.