Lab 03: Generics Architecture
Overview
Step 1: Generic Repository Pattern
package main
import (
"context"
"fmt"
)
// Constraint: any ID type that supports == comparison
type Repository[T any, ID comparable] struct {
store map[ID]T
}
func NewRepository[T any, ID comparable]() *Repository[T, ID] {
return &Repository[T, ID]{store: make(map[ID]T)}
}
func (r *Repository[T, ID]) Save(_ context.Context, id ID, item T) error {
r.store[id] = item
return nil
}
func (r *Repository[T, ID]) FindByID(_ context.Context, id ID) (T, bool) {
item, ok := r.store[id]
return item, ok
}
func (r *Repository[T, ID]) All(_ context.Context) []T {
items := make([]T, 0, len(r.store))
for _, v := range r.store {
items = append(items, v)
}
return items
}
func (r *Repository[T, ID]) Delete(_ context.Context, id ID) bool {
_, ok := r.store[id]
delete(r.store, id)
return ok
}
func (r *Repository[T, ID]) Count() int {
return len(r.store)
}Step 2: Generic Result Type
Step 3: Generic EventBus
Step 4: Generic Pipeline — Stage[I,O]
Step 5: Type Constraint Composition
Step 6: Generic Middleware Chain
Step 7: Generic Cache
Step 8: Capstone — Generic Repository + EventBus
Summary
Pattern
Generic API
Type Safety
Last updated
