Irbisa · Шпаргалка
Архитектура и паттерны в Go
SOLID в Go, чистая и гексагональная архитектура, строительные блоки DDD, CQRS, паттерны в стиле Go, внедрение зависимостей
Что говорят пять принципов SOLID и как каждый из них выглядит в Go, где нет классов и наследования?
Что означают DRY, KISS и YAGNI и когда устранение дублирования делает код на Go хуже?
Что означают слабая связанность (low coupling) и сильная связность (high cohesion) и как по импортам и экспортируемым именам пакета Go видно, что их нет?
ReadOnlyCacheреализуетCache, возвращая ошибку изSet. Какой принцип SOLID он нарушает и как исправить дизайн?type Cache interface { Get(ctx context.Context, key string) ([]byte, bool) Set(ctx context.Context, key string, val []byte) error} var ErrReadOnly = errors.New("cache is read-only") // Serves a snapshot embedded in the binary.type ReadOnlyCache struct{ data map[string][]byte } func (c *ReadOnlyCache) Get(_ context.Context, key string) ([]byte, bool) { v, ok := c.data[key] return v, ok} func (c *ReadOnlyCache) Set(context.Context, string, []byte) error { return ErrReadOnly }Чем отличаются инверсия зависимостей (DIP), внедрение зависимостей (DI) и инверсия управления (IoC) и что из этого использует
mainна Go, собранный вручную?Как в Go делают внедрение зависимостей и нужен ли для этого фреймворк вроде
wireилиfx?package main import ( "context" "database/sql" "log"…Какими классическими паттернами проектирования вы реально пользуетесь в Go, а какие язык делает ненужными или сводит к одной функции?
Как реализовать паттерн Strategy в Go и когда функциональный тип вроде
http.HandlerFuncлучше интерфейса с одним методом?type Order struct { TotalCents int64 Coupon string} // The strategy: how the discount is computed.…Найдите баг: после того как
UserRepoобернули в кэширующий декоратор,UpdateEmailпроходит успешно, ноGetпродолжает возвращать старый email, пока не истечёт TTL.type cachedRepo struct { UserRepo // methods not defined below go straight to the database cache *ttlCache[int64, User]} func (r *cachedRepo) Get(ctx context.Context, id int64) (User, error) { if u, ok := r.cache.Get(id); ok { return u, nil } u, err := r.UserRepo.Get(ctx, id) if err == nil { r.cache.Set(id, u) } return u, err}Что такое Clean Architecture и гексагональная архитектура (порты и адаптеры), что такое правило зависимостей и когда это перебор для сервиса на Go?
Из-за чего через интерфейс репозитория протекает база данных (
*sql.Rows, куски SQL, модели ORM в сигнатурах) и что он должен отдавать вместо этого?// wrong: the database leaks through the interface.type LeakyOrderRepo interface { Query(ctx context.Context, where string, args ...any) (*sql.Rows, error) Get(ctx context.Context, id int64) (OrderRow, error) // sql.NullString fields inside}…Как не пустить типы стороннего SDK (платёжного провайдера, клиента S3) в доменный код и что даёт антикоррупционный слой (anti-corruption layer)?
// package payment: the port, in the domain's own terms.var ErrDeclined = errors.New("payment declined") type Charge struct { AmountCents int64 Currency string // ISO 4217: "EUR"…Что такое сущность, объект-значение и агрегат в DDD и как в Go защитить инварианты агрегата, если поля структуры экспортируемые?
// Money is a value object: no identity, compared with ==, never mutated.type Money struct { Cents int64 Currency string}…В Go нет sealed-классов и enum с данными. Как смоделировать закрытый набор вариантов, например способов оплаты или состояний заказа, чтобы пропущенный случай ловился?
// Method is a closed set: isMethod is unexported, so no other package can add a variant.////sumtype:decltype Method interface{ isMethod() } type Card struct{ Last4 string }…Что такое ограниченный контекст (bounded context) в DDD и как он определяет, где заканчивается один пакет или сервис на Go и начинается следующий?
Что такое CQRS, когда отдельная модель чтения себя оправдывает и чем за неё платят в согласованности?
Что такое event sourcing, чем он отличается от хранения текущего состояния плюс outbox и что делает его трудным в продакшене?
type Event interface{ isEvent() } type Placed struct{ ID string }type LineAdded struct{ Cents int64 }type Paid struct{}…