Convert Figma logo to code with AI

tmrts logogo-patterns

Curated list of Go design patterns, recipes and idioms

24,954
2,191
24,954
65

Top Related Projects

Standard Go Project Layout

128,386

A curated list of awesome Go frameworks, libraries and software

18,744

ā¤ļø 1000+ Hand-Crafted Go Examples, Exercises, and Quizzes. šŸš€ Learn Go by fixing 1000+ tiny programs.

Learn Go with test-driven development

26,478

A standard library for microservices.

33,019

āš”ļø Express inspired web framework written in Go

Quick Overview

The tmrts/go-patterns repository is a curated collection of idiomatic design and application patterns for Go programming language. It serves as a comprehensive resource for developers to learn and implement best practices in Go, covering various aspects of software design and development.

Pros

  • Extensive coverage of design patterns and idioms specific to Go
  • Well-organized and categorized patterns for easy reference
  • Includes code examples and explanations for each pattern
  • Regularly updated and maintained by the community

Cons

  • Some patterns may be too advanced for beginners
  • Not all patterns are applicable to every project or use case
  • Lacks in-depth explanations for some complex patterns
  • May require additional research to fully understand and implement certain patterns

Code Examples

  1. Creational Pattern: Singleton
type singleton struct {}

var instance *singleton
var once sync.Once

func GetInstance() *singleton {
    once.Do(func() {
        instance = &singleton{}
    })
    return instance
}

This example demonstrates the Singleton pattern, ensuring only one instance of a struct is created.

  1. Behavioral Pattern: Observer
type Observer interface {
    Update(string)
}

type Subject struct {
    observers []Observer
    state     string
}

func (s *Subject) Attach(o Observer) {
    s.observers = append(s.observers, o)
}

func (s *Subject) Notify() {
    for _, observer := range s.observers {
        observer.Update(s.state)
    }
}

This code shows the Observer pattern, allowing multiple objects to watch and react to changes in another object.

  1. Concurrency Pattern: Worker Pool
func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Printf("worker %d started job %d\n", id, j)
        time.Sleep(time.Second)
        fmt.Printf("worker %d finished job %d\n", id, j)
        results <- j * 2
    }
}

func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)

    for w := 1; w <= 3; w++ {
        go worker(w, jobs, results)
    }

    for j := 1; j <= 5; j++ {
        jobs <- j
    }
    close(jobs)

    for a := 1; a <= 5; a++ {
        <-results
    }
}

This example illustrates the Worker Pool pattern, demonstrating how to manage and distribute tasks among multiple goroutines.

Getting Started

To use the patterns from this repository:

  1. Clone the repository:

    git clone https://github.com/tmrts/go-patterns.git
    
  2. Browse the patterns in the repository's directories.

  3. Study the pattern descriptions and code examples.

  4. Implement the desired pattern in your Go project, adapting it to your specific needs.

  5. Refer to the repository's README for additional information and resources.

Competitor Comparisons

Standard Go Project Layout

Pros of project-layout

  • Provides a comprehensive directory structure for Go projects
  • Includes explanations for each directory's purpose
  • Offers a standardized approach to organizing Go applications

Cons of project-layout

  • May be overly complex for smaller projects
  • Some developers argue it doesn't follow Go's simplicity principle
  • Can lead to unnecessary boilerplate in certain cases

Code Comparison

project-layout example structure:

ā”œā”€ā”€ cmd/
ā”‚   ā””ā”€ā”€ myapp/
ā”œā”€ā”€ internal/
ā”‚   ā””ā”€ā”€ pkg/
ā”œā”€ā”€ pkg/
ā”œā”€ā”€ vendor/
ā””ā”€ā”€ api/

go-patterns example (Design Pattern):

type Strategy interface {
    Execute()
}

type Context struct {
    strategy Strategy
}

func (c *Context) SetStrategy(strategy Strategy) {
    c.strategy = strategy
}

Key Differences

  • go-patterns focuses on design patterns and idiomatic Go code examples
  • project-layout emphasizes project structure and organization
  • go-patterns is more educational, while project-layout is a practical guide for project setup

Use Cases

  • Use go-patterns to learn about Go design patterns and best practices
  • Use project-layout as a starting point for structuring large Go applications

Community and Maintenance

  • Both repositories are popular and well-maintained
  • project-layout has more contributors and is updated more frequently
  • go-patterns has a larger number of stars, indicating high interest in design patterns
128,386

A curated list of awesome Go frameworks, libraries and software

Pros of awesome-go

  • Comprehensive collection of Go resources, libraries, and tools
  • Regularly updated with community contributions
  • Well-organized into categories for easy navigation

Cons of awesome-go

  • Lacks in-depth explanations of design patterns
  • May overwhelm beginners with the sheer volume of information

Code comparison

go-patterns provides specific code examples for design patterns:

type Strategy interface {
    Execute()
}

type Context struct {
    strategy Strategy
}

func (c *Context) SetStrategy(strategy Strategy) {
    c.strategy = strategy
}

awesome-go doesn't typically include code snippets, focusing instead on linking to external resources:

## Database

*Databases implemented in Go.*

* [BadgerDB](https://github.com/dgraph-io/badger) - Fast key-value DB in Go.
* [BigCache](https://github.com/allegro/bigcache) - Efficient key/value cache for gigabytes of data.

Summary

go-patterns focuses on explaining Go design patterns with code examples, while awesome-go serves as a comprehensive directory of Go-related resources. go-patterns is more suitable for developers looking to understand and implement specific patterns, whereas awesome-go is an excellent starting point for discovering a wide range of Go tools and libraries.

18,744

ā¤ļø 1000+ Hand-Crafted Go Examples, Exercises, and Quizzes. šŸš€ Learn Go by fixing 1000+ tiny programs.

Pros of learngo

  • Comprehensive learning resource with structured tutorials and exercises
  • Regularly updated with new content and improvements
  • Includes practical examples and hands-on projects

Cons of learngo

  • Primarily focused on learning, less suitable for quick reference
  • May not cover advanced design patterns in depth

Code Comparison

go-patterns example (Singleton pattern):

type singleton struct {}

var instance *singleton
var once sync.Once

func GetInstance() *singleton {
    once.Do(func() {
        instance = &singleton{}
    })
    return instance
}

learngo example (Basic variable declaration):

package main

import "fmt"

func main() {
    var speed int
    fmt.Println(speed)
}

The go-patterns repository focuses on design patterns and idiomatic Go code, providing concise examples of various patterns. In contrast, learngo is a more extensive learning resource, starting from basic concepts and progressing to more advanced topics.

go-patterns is better suited for experienced developers looking for quick references to design patterns, while learngo is ideal for beginners and those seeking a structured learning path in Go programming.

Both repositories offer valuable resources for Go developers, but they serve different purposes and target audiences. The choice between them depends on the user's experience level and specific learning or reference needs.

Learn Go with test-driven development

Pros of learn-go-with-tests

  • Focuses on test-driven development (TDD) approach
  • Provides hands-on learning experience with practical examples
  • Covers a wide range of Go concepts and features

Cons of learn-go-with-tests

  • May be less comprehensive in covering design patterns
  • Requires more time investment to work through examples
  • Might be challenging for absolute beginners in programming

Code Comparison

learn-go-with-tests example:

func TestHello(t *testing.T) {
    got := Hello("Chris")
    want := "Hello, Chris"
    if got != want {
        t.Errorf("got %q want %q", got, want)
    }
}

go-patterns example:

type Observer interface {
    Update(subject *Subject)
}

type Subject struct {
    observers []Observer
    state     int
}

Summary

learn-go-with-tests is ideal for those who want to learn Go through practical, test-driven development. It offers a hands-on approach but may require more time investment. go-patterns, on the other hand, focuses on design patterns and might be more suitable for experienced developers looking to improve their Go code structure. The choice between the two depends on the learner's goals and preferred learning style.

26,478

A standard library for microservices.

Pros of kit

  • Comprehensive microservices toolkit with production-ready components
  • Active development and community support
  • Extensive documentation and examples for real-world use cases

Cons of kit

  • Steeper learning curve due to its complexity and extensive features
  • May be overkill for smaller projects or simple applications
  • Requires more setup and configuration compared to simpler pattern libraries

Code Comparison

go-patterns focuses on design patterns and idiomatic Go code:

// Observer pattern example
type Observer interface {
    Update(string)
}

type Subject struct {
    observers []Observer
    state     string
}

kit provides more complex, production-ready components:

// Endpoint definition example
func makeUppercaseEndpoint(svc StringService) endpoint.Endpoint {
    return func(ctx context.Context, request interface{}) (interface{}, error) {
        req := request.(uppercaseRequest)
        v, err := svc.Uppercase(req.S)
        return uppercaseResponse{v, err}, nil
    }
}

go-patterns is ideal for learning and understanding Go patterns, while kit is better suited for building robust microservices in production environments.

33,019

āš”ļø Express inspired web framework written in Go

Pros of Fiber

  • Actively maintained and regularly updated web framework
  • High-performance and low memory footprint
  • Extensive documentation and large community support

Cons of Fiber

  • Focused solely on web development, not a general-purpose pattern collection
  • Steeper learning curve for beginners compared to simple pattern examples
  • May be overkill for small projects or learning basic Go concepts

Code Comparison

go-patterns (Singleton pattern):

type singleton struct {}

var instance *singleton
var once sync.Once

func GetInstance() *singleton {
    once.Do(func() {
        instance = &singleton{}
    })
    return instance
}

Fiber (Basic HTTP server):

app := fiber.New()

app.Get("/", func(c *fiber.Ctx) error {
    return c.SendString("Hello, World!")
})

app.Listen(":3000")

Summary

go-patterns is a collection of design patterns and idioms in Go, serving as a reference for various programming concepts. Fiber, on the other hand, is a full-fledged web framework focused on building high-performance web applications. While go-patterns is excellent for learning and understanding Go patterns, Fiber provides a complete toolkit for web development with features like routing, middleware, and templating.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Go Patterns
build-status awesome license

A curated collection of idiomatic design & application patterns for Go language.

Creational Patterns

PatternDescriptionStatus
Abstract FactoryProvides an interface for creating families of releated objectsĆ¢ĀœĀ˜
BuilderBuilds a complex object using simple objectsĆ¢ĀœĀ”
Factory MethodDefers instantiation of an object to a specialized function for creating instancesĆ¢ĀœĀ”
Object PoolInstantiates and maintains a group of objects instances of the same typeĆ¢ĀœĀ”
SingletonRestricts instantiation of a type to one objectĆ¢ĀœĀ”

Structural Patterns

PatternDescriptionStatus
BridgeDecouples an interface from its implementation so that the two can vary independentlyĆ¢ĀœĀ˜
CompositeEncapsulates and provides access to a number of different objectsĆ¢ĀœĀ˜
DecoratorAdds behavior to an object, statically or dynamicallyĆ¢ĀœĀ”
FacadeUses one type as an API to a number of othersĆ¢ĀœĀ˜
FlyweightReuses existing instances of objects with similar/identical state to minimize resource usageĆ¢ĀœĀ˜
ProxyProvides a surrogate for an object to control it's actionsĆ¢ĀœĀ”

Behavioral Patterns

PatternDescriptionStatus
Chain of ResponsibilityAvoids coupling a sender to receiver by giving more than object a chance to handle the requestĆ¢ĀœĀ˜
CommandBundles a command and arguments to call laterĆ¢ĀœĀ˜
MediatorConnects objects and acts as a proxyĆ¢ĀœĀ˜
MementoGenerate an opaque token that can be used to go back to a previous stateĆ¢ĀœĀ˜
ObserverProvide a callback for notification of events/changes to dataĆ¢ĀœĀ”
RegistryKeep track of all subclasses of a given classĆ¢ĀœĀ˜
StateEncapsulates varying behavior for the same object based on its internal stateĆ¢ĀœĀ˜
StrategyEnables an algorithm's behavior to be selected at runtimeĆ¢ĀœĀ”
TemplateDefines a skeleton class which defers some methods to subclassesĆ¢ĀœĀ˜
VisitorSeparates an algorithm from an object on which it operatesĆ¢ĀœĀ˜

Synchronization Patterns

PatternDescriptionStatus
Condition VariableProvides a mechanism for threads to temporarily give up access in order to wait for some conditionĆ¢ĀœĀ˜
Lock/MutexEnforces mutual exclusion limit on a resource to gain exclusive accessĆ¢ĀœĀ˜
MonitorCombination of mutex and condition variable patternsĆ¢ĀœĀ˜
Read-Write LockAllows parallel read access, but only exclusive access on write operations to a resourceĆ¢ĀœĀ˜
SemaphoreAllows controlling access to a common resourceĆ¢ĀœĀ”

Concurrency Patterns

PatternDescriptionStatus
N-BarrierPrevents a process from proceeding until all N processes reach to the barrierĆ¢ĀœĀ˜
Bounded ParallelismCompletes large number of independent tasks with resource limitsĆ¢ĀœĀ”
BroadcastTransfers a message to all recipients simultaneouslyĆ¢ĀœĀ˜
CoroutinesSubroutines that allow suspending and resuming execution at certain locationsĆ¢ĀœĀ˜
GeneratorsYields a sequence of values one at a timeĆ¢ĀœĀ”
ReactorDemultiplexes service requests delivered concurrently to a service handler and dispatches them syncronously to the associated request handlersĆ¢ĀœĀ˜
ParallelismCompletes large number of independent tasksĆ¢ĀœĀ”
Producer ConsumerSeparates tasks from task executionsĆ¢ĀœĀ˜

Messaging Patterns

PatternDescriptionStatus
Fan-InFunnels tasks to a work sink (e.g. server)Ć¢ĀœĀ”
Fan-OutDistributes tasks among workers (e.g. producer)Ć¢ĀœĀ”
Futures & PromisesActs as a place-holder of a result that is initially unknown for synchronization purposesĆ¢ĀœĀ˜
Publish/SubscribePasses information to a collection of recipients who subscribed to a topicĆ¢ĀœĀ”
Push & PullDistributes messages to multiple workers, arranged in a pipelineĆ¢ĀœĀ˜

Stability Patterns

PatternDescriptionStatus
BulkheadsEnforces a principle of failure containment (i.e. prevents cascading failures)Ć¢ĀœĀ˜
Circuit-BreakerStops the flow of the requests when requests are likely to failĆ¢ĀœĀ”
DeadlineAllows clients to stop waiting for a response once the probability of response becomes low (e.g. after waiting 10 seconds for a page refresh)Ć¢ĀœĀ˜
Fail-FastChecks the availability of required resources at the start of a request and fails if the requirements are not satisfiedĆ¢ĀœĀ˜
HandshakingAsks a component if it can take any more load, if it can't, the request is declinedĆ¢ĀœĀ˜
Steady-StateFor every service that accumulates a resource, some other service must recycle that resourceĆ¢ĀœĀ˜

Profiling Patterns

PatternDescriptionStatus
Timing FunctionsWraps a function and logs the executionĆ¢ĀœĀ”

Idioms

PatternDescriptionStatus
Functional OptionsAllows creating clean APIs with sane defaults and idiomatic overridesĆ¢ĀœĀ”

Anti-Patterns

PatternDescriptionStatus
Cascading FailuresA failure in a system of interconnected parts in which the failure of a part causes a domino effectĆ¢ĀœĀ˜