Попытка реализовать Чистую Архитектуру на Golang. Часть 2

Попытка реализовать Чистую Архитектуру на Golang. Часть 2

Practical.DEV

После описания моего опыта в статье «Попытка реализовать Чистую Архитектуру на Golang» (https://hackernoon.com/golang-clean-archithecture-efd6d7c43047) я узнал много нового от людей и в частности от пользователей Go. Я получил множество писем, комментариев и даже Github issue в моем проекте. Все это помогло мне понять, что я пропустил и где ошибся.

Цикличный импорт

Вспоминая мой старый проект из первой части статьи, я могу сказать, что он и его структура ограничены для Golang. Одна из самых больших проблем, с которой я столкнулся, – это наличие нескольких зависимостей в моделях. Из-за этого появляется циклический импорт, как упоминал пользователь daf0rth здесь: https://github.com/bxcodec/go-clean-arch/issues/7.

Система пакетов

Другой вопрос в том, что Golang отличается от других языков программирования. Он использует систему пакетов. Другими словами, будет лучше, если вся структура проекта или функция хранится в одном пакете, так безопаснее. Я вижу это решение во многих проектных библиотеках или открытых исходных кодах на Github. Возьмем в качестве примера проект logrus (https://github.com/sirupsen/logrus). Все структуры и функции хранятся в одном пакете, а он находится в корне пакета проектов. Таким образом, мы можем легко импортировать logrus в виде пакета для любых других наших проектов.

Решение?

Поэтому, осознав эти проблемы, я попробовал множество подходов, не упуская из виду концепцию “Чистой Архитектуры”, которая является независимой, тестируемой, поддерживаемой и чистой. При всем при этом не теряя идентичности Golang. И, в конце концов, я сделал обновление своих старых проектов: https://github.com/bxcodec/go-clean-arch

– Предотвращение циклических импортов

Чтобы избежать циклического импорта, я разделяю модели в одном пакете. Так, если у нас имеются связи между моделями, мы можем разрешить их, зная, что они уже хранятся в одном пакете.

– Восстановление идентичности Golang с помощью системы пакетов

И, чтобы не терять идентичность Golang, как пакетного языка программирования, я перемещаю интерфейс (слой варианта использования и слой репозитория) в их пакет корневого домена.

domain package golang clean architecture
article
├── delivery
│   └── http
│       ├── article_handler.go
│       └── article_test.go
├── mocks
│   ├── ArticleRepository.go
│   └── ArticleUsecase.go
├── repository //Encapsulated Implementation of Repository Interface
│   ├── mysql_article.go
│   └── mysqlarticle_test.go
├── repository.go // Repository Interface
├── usecase //Encapsulated Implementation of Usecase Interface
│   ├── articleucase_test.go
│   └── artilce_ucase.go
└── usecase.go // Usecase Interface.

Таким образом, исходя из этой структуры проектов, другие домены, такие как домен Author, знают только об интерфейсе и функции, а не об их реализации.

Ну, на самом деле, я просто напросто перемещаю интерфейс репозитория и варианта использования в их корневой домен.

article/usecase/usecase.go >>>> article/usecase.go
article/repository/repository.go >>>> article/repository.go

И я оставил их реализации в старых папках. И следуя этому замыслу, я все еще могу редактировать их без изменения соглашения между ними. Я так же могу изменить базу данных репозитория с MySQL на MongoDB, или логику варианта использования, не меняя выходящие и входящие данные функций.

Тестирование?

Концепция до сих пор не поменялась. Как и тестирование. Все то же самое. Эти изменения касаются только предотвращения циклического импорта, а также восстановления идентичности Golang в качестве пакетного языка.

Последнее, но не менее значимое

Весь этот замысел основан на моем собственном и на полученном от других людей опыте. Некоторые функции я взял, возможно, из другого исходного кода, а в некоторых из них я сделал несколько улучшений. Я буду очень признателен за любой вопрос, комментарии или поправку, если я делаю что-то неправильно или пропускаю что-то в своей статье.

В Golang, нет стандартной архитектуры. Мы можем свободно перепробовать множество подходов, как мы можем сделать и узнать. Для некоторых людей предлагаемая мной архитектура полезна, но для других действительно не подходит и не решает реальную проблему. Но я хочу сказать, что Golang свободен и никогда будет иметь стандартов. Вы можете разработать свой собственный стандарт, или попробовать то, что делают другие. Ведь там так много предложенной разными людьми Чистой Архитектуры, которая, возможно, поможет вам больше.

Report Page