From golang-workflow
Compose interfaces through embedding for flexible contracts
npx claudepluginhub jamesprial/prial-plugins --plugin golang-workflowThis skill uses the workspace's default tool permissions.
Go interfaces can embed other interfaces to create larger contracts. Use this for composition, not inheritance.
Guides Go interface usage: defining/implementing, abstractions, mockable testing boundaries, embedding, accepting interfaces vs concrete returns, type assertions/switches. Includes compliance check script.
Guides Go interface design patterns: consumer-side definition, accept-interfaces-return-structs, composition, implicit satisfaction, and pitfalls. For decoupling packages, defining contracts, reviewing usage, refactoring for testability.
Designs, reviews, and audits Go interfaces using discovery-over-design principles. Flags oversized interfaces, wrong definition sites, premature abstractions, and usage smells.
Share bugs, ideas, or general feedback.
Go interfaces can embed other interfaces to create larger contracts. Use this for composition, not inheritance.
CORRECT - Compose small interfaces
type Reader interface {
Read(p []byte) (n int, err error)
}
type Closer interface {
Close() error
}
type ReadCloser interface {
Reader
Closer
}
// Any type implementing both Reader and Closer satisfies ReadCloser
WRONG - Giant interface instead of composition
type FileHandler interface {
Read(p []byte) (n int, err error)
Write(p []byte) (n int, err error)
Close() error
Seek(offset int64, whence int) (int64, error)
// Kitchen sink approach
}
Progressive enhancement:
type BasicCache interface {
Get(key string) ([]byte, error)
Set(key string, val []byte) error
}
type ExpiringCache interface {
BasicCache
SetWithTTL(key string, val []byte, ttl time.Duration) error
}
func UseCache(c BasicCache) { /* Works with any cache */ }
func UseAdvanced(c ExpiringCache) { /* Needs TTL support */ }
Optional behavior detection:
type Processor interface {
Process(data []byte) error
}
type BatchProcessor interface {
Processor
ProcessBatch(items [][]byte) error
}
func Handle(p Processor, items [][]byte) error {
if bp, ok := p.(BatchProcessor); ok {
return bp.ProcessBatch(items) // Use batch if available
}
// Fallback to individual processing
for _, item := range items {
if err := p.Process(item); err != nil {
return err
}
}
return nil
}