Страницы

среда, 17 апреля 2019 г.

Trying Clean Architecture on Typescript

В моей библиотеке книги Роберта Мартина занимают почетное место - на рабочем столе, рядом с публикациями Мартина Фаулера, Стива Макконнелла и еще нескольких менее известных авторов. Отзывы о его последней книге, Clean Architecture, неоднозначны: кому-то не хватает деталей, а кто-то просто пытается реализовать свое понимание усвоенного материала на своей любимой платформе. Недавно мне попалась на глаза одна такая попытка на Go, потом еще одна, потом еще одна на Python, и я решил попробовать написать что-то подобное на TypeScript.

Например сервис генерации случайных целых чисел в определенном диапазоне, а также не менее случайных строк определенной длины, состоящих из цифр и букв латинского алфавита. TL;DR: исходный код.

Познакомиться с Uncle Bob's Clean Architecture можно здесь.

Ready, Set, Go!

Шаг 1.

Начнем с Entities.

- src/random/int.ts - генерирует числа
- src/random/str.ts - генерирует строки

- npm test 

Шаг 2.

Добавим Use Cases.

- src/random/index.ts

Сейчас этот слой может показаться лишним, но в дальнейшем, когда требования изменятся, смысл его существования станет очевидным.

- npm test 

Шаг 3.

Interface Adapters. На этом этапе нет необходимости хранить какие-либо данные, поэтому достаточно адаптера "внешних" интерфейсов.

- src/server/http/random.ts - контроллер HTTP-запросов на генерацию случайных значений
- src/server/http/server.ts - HTTP-сервер

Добавляем файл запуска сервиса - самый "грязный" компонент.

- src/index.ts

Билдим.

- npm run build

Запускаем.

- node lib/index.js

OK. А дальше, как это часто бывает, легенда меняется: сервис должен отдавать одинаковые ответы на запросы с одинаковым уникальным ключом.

Шаг 4.

Обновляем Use Cases. Добавляем интерфейс шлюза к какому-нибудь key-value хранилищу, я назвал его Cache.

- src/random/index.ts

- npm test

Шаг 5.

Реализуем Cache. В качестве хранилища используем Redis.

- src/cache/index.ts
- src/cache/redis.ts

Шаг 6.

Обновляем контроллер HTTP-запросов.

- src/server/http/random.ts

Обновляем файл запуска сервиса.

- src/index.ts

Билдим.

- npm run build

Запускаем.

- node lib/index.js


OK. Похоже на правду, но текущая реализация не гарантирует одинаковый ответ если сервис получит несколько запросов с одинаковым уникальным ключом одновременно.

Шаг 7.

Добавляем интерфейс для распределенной блокировки ключа, я назвал его Locker.

- src/random/index.ts

- npm test

Шаг 8.

Реализация интерфейса Locker у меня уже есть в виде модуля. Обновляем контроллер HTTP-запросов.

- src/server/http/random.ts

Обновляем файл запуска сервиса.

- src/index.ts

Билдим.

- npm run build

Запускаем.

- node lib/index.js

Устанавливаем значения ключей локера руками.

Попытаемся выполнить запросы к серверу.

Это нормально т.к. не мешало бы установить TTL ключей.

Попытаемся выполнить запросы к серверу еще раз.

Вот теперь все OK.

И в завершение дисклеймер: я художник, я так вижу.

Комментариев нет:

Отправить комментарий

Комментарий будет опубликован после модерации