SKILL·7768BA

go-design-patterns

eduardo-sl
Updated Yesterday
63
9
63
View on GitHub
Metaaidesign

About

This skill provides idiomatic Go implementations of common design patterns like functional options, builder, factory, and strategy patterns. Use it when you need guidance on structuring Go code with patterns adapted to Go's type system and composition philosophy. It specifically excludes interface design, package layout, and concurrency topics which are covered by other skills.

Quick Install

Claude Code

Recommended
Primary
npx skills add eduardo-sl/go-agent-skills -a claude-code
Plugin CommandAlternative
/plugin add https://github.com/eduardo-sl/go-agent-skills
Git CloneAlternative
git clone https://github.com/eduardo-sl/go-agent-skills.git ~/.claude/skills/go-design-patterns

Copy and paste this command in Claude Code to install this skill

Documentation

Go Design Patterns

Go favors composition over inheritance and simplicity over abstraction. These patterns are idiomatic Go — not Java patterns ported to Go.

Detailed reference material, loaded on demand:

  • references/creation-patterns.md — functional options (full example), options vs config struct, constructors, factory.
  • references/behavioral-patterns.md — strategy, middleware/decorator, result type, defer cleanup, sentinel vs zero values.

Read a reference file only when the summary below is not enough.

Pattern Selection

NeedPatternReference
Constructor with many optional settingsFunctional optionscreation-patterns.md
Config loaded from file/env, mostly required fieldsConfig structcreation-patterns.md
Enforce invariants at creationConstructor returning errorcreation-patterns.md
Pick implementation from runtime configFactory returning interfacecreation-patterns.md
Swap simple behavior at runtimeStrategy via function typebehavioral-patterns.md
Swap complex behavior at runtimeStrategy via interfacebehavioral-patterns.md
Wrap cross-cutting concerns (log, cache, metrics)Middleware / decoratorbehavioral-patterns.md
Value-or-error in concurrent pipelinesResult[T] structbehavioral-patterns.md

1. Functional Options (essentials)

type Option func(*Server)

func WithAddr(addr string) Option {
    return func(s *Server) { s.addr = addr }
}

func NewServer(opts ...Option) *Server {
    s := &Server{
        addr:        ":8080", // sensible defaults first
        readTimeout: 5 * time.Second,
        logger:      slog.Default(),
    }
    for _, opt := range opts {
        opt(s)
    }
    return s
}

srv := NewServer(WithAddr(":9090"))

Use when: many optional parameters with sensible defaults, API evolves over time (new options don't break callers), options need validation. Use a plain config struct instead when most fields are required or the configuration is deserialized from file/env.

2. Constructor Rules

  • Every exported type with invariants needs a constructor.
  • Validate required dependencies; return an error, don't panic:
// ✅ Good — constructor enforces invariants
func NewUserService(repo UserRepository, logger *slog.Logger) (*UserService, error) {
    if repo == nil {
        return nil, errors.New("user service: nil repository")
    }
    return &UserService{repo: repo, logger: logger}, nil
}

// ❌ Bad — struct literal with no validation
svc := &UserService{} // nil dependencies → panic at runtime

3. Factory

Return the interface, not a concrete type. The factory is the only place that knows about concrete implementations:

func NewStore(cfg Config) (Store, error) {
    switch cfg.StoreType {
    case "redis":
        return newRedisStore(cfg.RedisAddr)
    case "memory":
        return newMemoryStore(), nil
    default:
        return nil, fmt.Errorf("unknown store type: %s", cfg.StoreType)
    }
}

4. Middleware Chain

The standard HTTP composition pattern:

type Middleware func(http.Handler) http.Handler

func Chain(handler http.Handler, middlewares ...Middleware) http.Handler {
    for i := len(middlewares) - 1; i >= 0; i-- {
        handler = middlewares[i](handler)
    }
    return handler
}

handler := Chain(appHandler, Recoverer, RequestID, Logger, Auth)

The same shape works for any interface: stack decorators as cache → logging → metrics → actual repo (see references/behavioral-patterns.md).

5. Zero Values First

Prefer types whose zero value is useful (sync.Mutex, bytes.Buffer, nil slices). Reach for sentinel wrappers or pointers only when the zero value is ambiguous as an input (nil *float64 = "not configured").

Anti-Patterns to Avoid

// ❌ God interface — too many methods
type Service interface {
    GetUser(ctx context.Context, id string) (*User, error)
    CreateUser(ctx context.Context, u *User) error
    DeleteUser(ctx context.Context, id string) error
    ListOrders(ctx context.Context, userID string) ([]Order, error)
    // 20 more methods...
}
// → Split into focused interfaces: UserReader, UserWriter, OrderLister

// ❌ Premature abstraction — interface for one implementation
type UserCache interface {
    Get(key string) (*User, bool)
    Set(key string, user *User)
}
// If there's only ever one implementation, use the concrete type.
// Extract an interface when a second consumer or implementation appears.

// ❌ Java-style inheritance simulation
type BaseService struct{ /* ... */ }
type UserService struct{ BaseService } // embedding is NOT inheritance
// → Use composition: UserService has a dependency, not a parent.

Verification Checklist

  1. Functional options used for types with optional configuration
  2. Constructors validate required dependencies and return errors
  3. Factory functions return interfaces, not concrete types
  4. No god interfaces — each interface has 1-3 methods
  5. Middleware follows func(http.Handler) http.Handler signature
  6. Decorators wrap interfaces, not concrete types
  7. defer used for all resource cleanup (files, connections, locks)
  8. Zero values are meaningful — no unnecessary initialization
  9. No premature abstractions — interfaces extracted only when needed
  10. Composition used instead of embedding for code reuse

GitHub Repository

eduardo-sl/go-agent-skills
Path: skills/(architecture)/go-design-patterns
0
FAQ

Frequently asked questions

What is the go-design-patterns skill?

go-design-patterns is a Claude Skill by eduardo-sl. Skills package instructions and resources that Claude loads on demand, so Claude can perform go-design-patterns-related tasks without extra prompting.

How do I install go-design-patterns?

Use the install commands on this page: add go-design-patterns to Claude Code as a plugin, or clone its repository into your skills directory, then restart Claude so it picks up the skill.

What category does go-design-patterns belong to?

go-design-patterns is in the Meta category, tagged ai and design.

Is go-design-patterns free to use?

Yes. go-design-patterns is listed on AIMCP and free to install.

Related Skills

content-collections
Meta

This skill provides a production-tested setup for Content Collections, a TypeScript-first tool that transforms Markdown/MDX files into type-safe data collections with Zod validation. Use it when building blogs, documentation sites, or content-heavy Vite + React applications to ensure type safety and automatic content validation. It covers everything from Vite plugin configuration and MDX compilation to deployment optimization and schema validation.

View skill
polymarket
Meta

This skill enables developers to build applications with the Polymarket prediction markets platform, including API integration for trading and market data. It also provides real-time data streaming via WebSocket to monitor live trades and market activity. Use it for implementing trading strategies or creating tools that process live market updates.

View skill
creating-opencode-plugins
Meta

This skill helps developers create OpenCode plugins that hook into 25+ event types like commands, files, and LSP operations. It provides the plugin structure, event API specifications, and implementation patterns for JavaScript/TypeScript modules. Use it when you need to intercept, monitor, or extend the OpenCode AI assistant's lifecycle with custom event-driven logic.

View skill
sglang
Meta

SGLang is a high-performance LLM serving framework that specializes in fast, structured generation for JSON, regex, and agentic workflows using its RadixAttention prefix caching. It delivers significantly faster inference, especially for tasks with repeated prefixes, making it ideal for complex, structured outputs and multi-turn conversations. Choose SGLang over alternatives like vLLM when you need constrained decoding or are building applications with extensive prefix sharing.

View skill