От теории к практике: Чистый архитектурный дизайн в проектах Go
От теории к практике: Чистый архитектурный дизайн в проектах Go

статья:Практика разработки|О задачах сложения, вычитания, умножения и деления в пределах 100 к существующим ошибкам, с которыми сталкиваются клиенты на сайте Комментарий: В данной статье в основном рассказывается авторский процесс решения задачи анализа данных на площадке заказчика. Клиент обнаружил, что сумма процентов на круговой диаграмме не равна 100 % из-за потери точности данных и округления. Анализируя источники данных и сравнивая различные методы обработки, автор наконец принял алгоритм компенсации: при последнем процентном расчете вычитается сумма всех предыдущих процентов, чтобы гарантировать, что общая сумма равна 100%. Автор резюмирует проблемы с точностью, которые могут возникнуть при отображении данных в виде круговой диаграммы, подчеркивает важность устранения неполадок данных, оптимизации конфигураций инструментов и достижения компромиссов с клиентами, а также выражает свой опыт обучения общению с клиентами при решении проблем.

Предисловие

ты поддерживаешь Go Как выглядит архитектура кода проекта? Шестиугольная архитектура? Или луковая архитектура? Или, может быть, DDD?несмотря ни на чтопроект Какая архитектура используется?,Основные цели должны быть одинаковыми: сделать код простым для понимания, тестирования и сопровождения.

Эта статья начнется с Bob дяди Чистая архитектура(Clean Architecture)Отправляться,Кратко проанализируйте его основные идеи.,и объединить go-clean-arch Склад, подробный обзор того, как Go Эта архитектурная концепция реализована в проекте.

Вы готовы? Возьмите чашку любимого кофе или чая и узнайте, прочитав эту статью.

Чистая архитектура

Чистая архитектура(Clean Architecture)да Bob Концепция проектирования архитектуры программного обеспечения, предложенная Дядюшкой, целью которой является упрощение понимания, тестирования и обслуживания программных систем за счет иерархических структур и четких правил зависимостей. Основная идея состоит в том, чтобы разделить фокус наточка,Обеспечить основную бизнес-логику в системе(Use Cases)Не зависит от деталей реализации(как рамка、база данных и др.).

Clean Architecture Основная идея заключается в том, независимость

  • Независимый от фреймворка: не зависит от конкретной фреймворка (например, GinGRPC ждать). Фреймворки должны быть инструментами, а не ядром архитектуры.
  • независимый от UI:Пользовательский интерфейс можетк Легко изменить,не затрагивая другие части системы. Например,Web UI Можно заменить на консоль. UI,Нет необходимости изменять бизнес-правила.
  • независимый от База данных: Вы можете изменить базу данных (например, из MySQL Заменить на MongoDB),не затрагивая основную бизнес-логику.
  • независимый от Внешних инструментов: Внешние зависимости (например, сторонние библиотеки) следует изолировать, чтобы избежать их прямого влияния на ядро ​​системы.

Структурная схема

Как показано на картинке,Clean Architecture к концентрические круги описывается таким образом, что каждый уровень представляет собой различную ответственность системы:

  • основная организация(Entities
    • Местоположение: Самый внутренний слой
    • Обязанности: Определение бизнес-правил системы. Сущность является основным объектом приложения и имеет независимый жизненный цикл.
    • Независимость:полностьюнезависимый от Бизнес-правила, меняются только вместе с бизнес-правилами.
  • вариант использования(Use Cases / Service
    • Местоположение: один слой, непосредственно примыкающий к объекту.
    • Обязанности: Реализация бизнес-логики приложения. Определите процесс различных операций (вариантов использования) в системе, чтобы обеспечить удовлетворение потребностей пользователей.
    • Функция: вариант использования вызывает уровень сущности, координирует поток данных и определяет ответ.
  • интерфейсный адаптер(Interface Adapters) - Местоположение: на один уровень дальше снаружи - Обязанности: Отвечает за передачу данных из внешних систем (таких как пользовательский интерфейс, база данных и т. д.) в формат, понятный внутреннему уровню, а также используется для преобразования основной бизнес-логики в форму, пригодную для использования внешними системами. Например: будет HTTP Запрошенные данные преобразуются во внутреннюю модель (например, класс или структуру), либо пользователю отображаются выходные данные по варианту использования. - компоненты:Включает контроллер、шлюз(Gateways)、Presenter ждать.
  • Внешние фреймворки и драйверы(Frameworks & Drivers
    • Местоположение: самый внешний слой
    • Обязанности: Осуществлять взаимодействие с внешним миром.,например база данных、UI、Ожидание очереди сообщений.
    • Особенности: Этот слой зависит от внутреннего слоя, обратное неверно. Эту часть системы заменить проще всего.

проект go-clean-arch

go-clean-arch это осознать Чистая архитектура(Clean Architecture)один из Go Примерпроект。Долженпроект Существует четыре доменных слоя.(Domain Layer):

  • Models Layer слой модели
    • Роль: Определить основную структуру данных предметной области и нести ответственность за описание бизнес-объектов в проекте, таких как статьяавтор ждать.
    • Соответствующий теоретический уровень:слой сущности(Entities)。
    • Пример:
Язык кода:go
копировать
package domain

import (
	"time"
)

type Article struct {
	ID        int64     `json:"id"`
	Title     string    `json:"title" validate:"required"`
	Content   string    `json:"content" validate:"required"`
	Author    Author    `json:"author"`
	UpdatedAt time.Time `json:"updated_at"`
	CreatedAt time.Time `json:"created_at"`
}
  • Repository Layer слой хранения
    • Роль: отвечает за взаимодействие с источниками данных (такими как базы данных и кэши) и предоставление единого интерфейса для уровня вариантов использования для доступа к данным.
    • Соответствующий теоретический уровень:Внешние фреймворки и драйверыслой(Frameworks & Drivers)。
    • Пример:
Язык кода:go
копировать
package mysql

import (
	"context"
	"database/sql"
	"fmt"

	"github.com/sirupsen/logrus"

	"github.com/bxcodec/go-clean-arch/domain"
	"github.com/bxcodec/go-clean-arch/internal/repository"
)

type ArticleRepository struct {
	Conn *sql.DB
}

// NewArticleRepository will create an object that represent the article.Repository interface
func NewArticleRepository(conn *sql.DB) *ArticleRepository {
	return &ArticleRepository{conn}
}

func (m *ArticleRepository) fetch(ctx context.Context, query string, args ...interface{}) (result []domain.Article, err error) {
	rows, err := m.Conn.QueryContext(ctx, query, args...)
	if err != nil {
		logrus.Error(err)
		return nil, err
	}

	defer func() {
		errRow := rows.Close()
		if errRow != nil {
			logrus.Error(errRow)
		}
	}()

	result = make([]domain.Article, 0)
	for rows.Next() {
		t := domain.Article{}
		authorID := int64(0)
		err = rows.Scan(
			&t.ID,
			&t.Title,
			&t.Content,
			&authorID,
			&t.UpdatedAt,
			&t.CreatedAt,
		)

		if err != nil {
			logrus.Error(err)
			return nil, err
		}
		t.Author = domain.Author{
			ID: authorID,
		}
		result = append(result, t)
	}

	return result, nil
}

func (m *ArticleRepository) GetByID(ctx context.Context, id int64) (res domain.Article, err error) {
	query := `SELECT id,title,content, author_id, updated_at, created_at
  						FROM article WHERE ID = ?`

	list, err := m.fetch(ctx, query, id)
	if err != nil {
		return domain.Article{}, err
	}

	if len(list) > 0 {
		res = list[0]
	} else {
		return res, domain.ErrNotFound
	}

	return
}
  • Usecase/Service Layer Вариант использования/уровень обслуживания
    • Роль: определение базовой логики приложения системы.,Это мост между моделью предметной области и внешним взаимодействием.
    • Соответствующий теоретический уровень:вариант использованияслой(Use Cases / Service)。
    • Пример:
Язык кода:go
копировать
package article

import (
	"context"
	"time"

	"github.com/sirupsen/logrus"
	"golang.org/x/sync/errgroup"

	"github.com/bxcodec/go-clean-arch/domain"
)

type ArticleRepository interface {
	GetByID(ctx context.Context, id int64) (domain.Article, error)
}

type AuthorRepository interface {
	GetByID(ctx context.Context, id int64) (domain.Author, error)
}

type Service struct {
	articleRepo ArticleRepository
	authorRepo  AuthorRepository
}

func NewService(a ArticleRepository, ar AuthorRepository) *Service {
	return &Service{
		articleRepo: a,
		authorRepo:  ar,
	}
}

func (a *Service) GetByID(ctx context.Context, id int64) (res domain.Article, err error) {
	res, err = a.articleRepo.GetByID(ctx, id)
	if err != nil {
		return
	}

	resAuthor, err := a.authorRepo.GetByID(ctx, res.Author.ID)
	if err != nil {
		return domain.Article{}, err
	}
	res.Author = resAuthor
	return
}
  • Delivery Layer уровень доставки
    • Роль: отвечает за получение внешних запросов, вызов уровня вариантов использования и возврат результатов наружу (например, HTTP клиент или CLI пользователь).
    • Соответствующий теоретический уровень:интерфейсный адаптерслой(Interface Adapters)。
    • Пример:
Язык кода:go
копировать
package rest

import (
	"context"
	"net/http"
	"strconv"

	"github.com/bxcodec/go-clean-arch/domain"
)

type ResponseError struct {
	Message string `json:"message"`
}

type ArticleService interface {
	GetByID(ctx context.Context, id int64) (domain.Article, error)
}

// ArticleHandler  represent the httphandler for article
type ArticleHandler struct {
	Service ArticleService
}

func NewArticleHandler(e *echo.Echo, svc ArticleService) {
	handler := &ArticleHandler{
		Service: svc,
	}
	e.GET("/articles/:id", handler.GetByID)
}

func (a *ArticleHandler) GetByID(c echo.Context) error {
	idP, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		return c.JSON(http.StatusNotFound, domain.ErrNotFound.Error())
	}

	id := int64(idP)
	ctx := c.Request().Context()

	art, err := a.Service.GetByID(ctx, id)
	if err != nil {
		return c.JSON(getStatusCode(err), ResponseError{Message: err.Error()})
	}

	return c.JSON(http.StatusOK, art)
}

go-clean-arch Общая архитектура кода проекта выглядит следующим образом:

Язык кода:txt
копировать
go-clean-arch/
├── internal/
│   ├── rest/
│   │   └── article.go           # Delivery Layer уровень доставки
│   ├── repository/
│   │   ├── mysql/
│   │   │   └── article.go       # Repository Layer слой хранения
├── article/
│   └── service.go               # Usecase/Service Layer Вариант использования/уровень обслуживания
├── domain/
│   └── article.go               # Models Layer слой модели

существовать go-clean-arch В проекте зависимости между каждым слоем следующие:

  • Usecase/Service зависимость слоя Repository интерфейс, но не знает деталей реализации интерфейса.
  • Repository Уровень реализует интерфейс, но это внешний компонент, который зависит от Domain объект слоя.
  • Delivery слой (например, REST Handler)вызов Usecase/Service уровень, отвечающий за преобразование внешних запросов в вызовы бизнес-логики.

Эта конструкция соответствует принципу инверсии зависимостей, гарантируя, что основная бизнес-логика не зависит от деталей внешней реализации и имеет более высокую тестируемость и гибкость.

краткое содержание

Эта статья объединяет Bob дяди Чистая архитектура(Clean Architecture) и go-clean-arch Пример проекта, объясняет, как существовать Go Реализация в проекте Clean архитектура. Четкое разделение фокусов посредством иерархических структур, таких как основные сущности, варианты использования, адаптеры интерфейса и внешние структуры. наточка,Сделать основную бизнес-логику системы(Use Cases)с деталями внешней реализации(как рамка、база данных) развязка.

go-clean-arch В структуре проекта используется иерархический подход к организации кода с четкими обязанностями на каждом уровне:

  • Слой домена:Определить основные бизнес-структуры,независимый Внешняя реализация.
  • Уровень вариантов использования:Реализация логики приложения,Координирует взаимодействие сущностей с внешним миром.
  • Уровень репозитория:Конкретные детали реализации хранения данных。
  • Уровень доставки:Обрабатывать внешние запросы и возвращать результаты。

Это всего лишь пример проекта,Конкретный архитектурный дизайн проекта должен гибко корректироваться в соответствии с фактическими потребностями, привычками команды и спецификациями. Основная цель — сохранить принцип многоуровневого подхода.,Убедитесь, что код легко понять, протестировать и поддерживать.,В то же время он поддерживает долгосрочное расширение и развитие системы.


Здравствуйте, я Чэнь Мингён, разработчик, который любит технологии и готов ими делиться, а также энтузиаст открытого исходного кода.

Путь к успеху не переполнен. Вы заинтересованы в поиске партнера?

Следуйте за мной, добавляйте меня в друзья, учитесь и совершенствуйтесь вместе!

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose