Разработчикам приложений нет необходимости изобретать велосипед для каждого нового проекта. В большинстве случаев можно прибегнуть к сторонней библиотеке, которая предлагает стабильную реализацию нужной функциональности. Поговорим о подходе, который гарантирует, что сторонние библиотеки будут хорошо взаимодействовать с приложением.
Используйте библиотеку как плагин
При работе со сторонней библиотекой нужно учитывать следующее.
- Приложение не должно знать о существовании библиотеки. В будущем может понадобиться ее поменять, и это не должно нарушать работу системы.
- Обеспечьте согласованность модели данных. В некоторых случаях модель данных приложения несовместима с моделью данных библиотеки. Поэтому может потребоваться некоторое преобразование данных.
- Обеспечьте минимальную степень связанности. Приложению могут не требоваться все функции, которые предлагает библиотека. Необходимо применять только те, что вам нужны.
По сути, все сводится к тому, что не нужно чрезмерно полагаться на библиотеки. К ним необходимо относиться как к плагинам, которые при необходимости можно легко подключить или отключить. Поговорим о том, как это можно сделать.
Шаблон “Адаптер” в React
Один из способов убедиться, что все упомянутые выше пункты учтены, — использовать шаблон “Адаптер”.
Шаблон “Адаптер” преобразует интерфейс класса в другой интерфейс, ожидаемый клиентами. Адаптер позволяет классам работать вместе, что в противном случае было бы невозможно из-за несовместимых интерфейсов.
Чтобы применить этот шаблон в React, нужно создать оболочку вокруг сторонней библиотеки. Она будет служить адаптером, гарантирующим, что у приложения всегда будет стабильная ссылка на функциональность, которая будет обернута.
В React допустимы два типа оболочек:
- оболочка компонента (для обертывания компонентов библиотеки);
- оболочка функций (для обертывания библиотечных функций).
В этой статье мы сосредоточимся на оболочках компонентов. Рассмотрим пример.
Оболочка компонента в действии
Для примера мы создадим адаптер для React Flow — библиотеки для построения диаграмм.
React Flow предоставляет много функциональных возможностей, но для этого примера нужны лишь следующие:
- визуализация основных узлов диаграмм;
- реакция при выборе узла;
- реакция при отсутствии выбора.
Чтобы добиться этого, сначала внедрим Diagram Adapter
:
import ReactFlow, { isNode } from "react-flow-renderer";
const DiagramAdapter = ({ nodes, onActivateNode, onDeactivateAll }) => {
const onSelectionChange = (elements) => {
if (elements) {
const selectedNodes = elements.filter((els) => isNode(els));
if (selectedNodes.length > 0) {
onActivateNode(selectedNodes[0].id);
}
}
};
const onPaneClick = () => onDeactivateAll();
return (
<div style={{ height: 650 }}>
<ReactFlow
elements={nodes}
onSelectionChange={onSelectionChange}
onPaneClick={onPaneClick} />
</div>
);
}
export default DiagramAdapter;
В приведенном выше коде мы обернули компонент ReactFlow
и привязали к нему несколько слушателей событий. Затем эти слушатели преобразуют данные из событий и вызывают функции onActivateNode
и onDeactivateAll
, передаваемые родительским компонентом адаптера.
Таким образом, родительскому компоненту даже не нужно знать, какая библиотека импортирована. Он просто знает, что onActivateNode
и onDeactivateAll
доступны для использования.
К слову, адаптер также можно использовать вот так:
function App() {
const nodes = [
{
id: "node_0",
position: { x: 150, y: 25 },
data: { label: "Start" }
},
{
id: "node_1",
position: { x: 150, y: 225 },
data: { label: "End" }
},
{
id: "node_0-node_1", type: "step", source: "node_0", target: "node_1"
}
];
const onActivateNode = (node) => {
console.log("Activated", node);
};
const onDeactivateAll = (node) => {
console.log("Deactivated all");
};
return (
<DiagramAdapter
nodes={nodes}
onActivateNode={onActivateNode}
onDeactivateAll={onDeactivateAll} />
);
}
Заключение
Вы успешно применили шаблон проектирования “Адаптер” в приложении на React!
Теперь можно пользоваться преимуществами отделения приложения от сторонних библиотек: приложение не знает про библиотеки, модели данных согласованы, а степень связанности минимальна.
Читайте также:
- Создание компонента Timer с React и Bit
- Как создать библиотеку компонентов для совместного использования
- Секретные материалы: тайная сторона Redux становится явной ?
Читайте нас в Telegram, VK и Дзен
Перевод статьи Kenneth Angelo Reyes: How to Use the Adapter Design Pattern in React