Skip to content

Instantly share code, notes, and snippets.

@Apurer
Created February 19, 2023 20:29
Show Gist options
  • Save Apurer/c992b731fcdd3c14ee8387e945ac9b18 to your computer and use it in GitHub Desktop.
Save Apurer/c992b731fcdd3c14ee8387e945ac9b18 to your computer and use it in GitHub Desktop.
package main
import "fmt"
// Product contains the information about a product
type Product struct {
Name string
Price int
Quantity int
}
// Builder is used to build a product
type Builder interface {
SetName(string) Builder
SetPrice(int) Builder
SetQuantity(int) Builder
Build() Product
}
// ProductBuilder is used to build a product
type ProductBuilder struct {
name string
price int
quantity int
}
// SetName sets the name of the product
func (pb *ProductBuilder) SetName(name string) Builder {
pb.name = name
return pb
}
// SetPrice sets the price of the product
func (pb *ProductBuilder) SetPrice(price int) Builder {
pb.price = price
return pb
}
// SetQuantity sets the quantity of the product
func (pb *ProductBuilder) SetQuantity(quantity int) Builder {
pb.quantity = quantity
return pb
}
// Build builds the product
func (pb *ProductBuilder) Build() Product {
return Product{
Name: pb.name,
Price: pb.price,
Quantity: pb.quantity,
}
}
func main() {
// Create a new product builder
pb := &ProductBuilder{}
// Use the builder to build a product
product := pb.SetName("MyProduct").SetPrice(1000).SetQuantity(2).Build()
fmt.Printf("Product: %+v\n", product)
}
//Here is a simple implementation of the Command Pattern in Go:
package main
import "fmt"
// Command interface defines the contract for all concrete commands
type Command interface {
Execute()
}
// ConcreteCommand holds the receiver for the command
type ConcreteCommand struct {
Receiver Receiver
}
// Execute runs the command
func (c *ConcreteCommand) Execute() {
fmt.Println("Executing command")
c.Receiver.Action()
}
// Receiver holds the action to be performed by the command
type Receiver struct {
}
// Action is the method to be performed by the receiver
func (r *Receiver) Action() {
fmt.Println("Action has been performed")
}
func main() {
// Create receiver
receiver := &Receiver{}
// Create command and set its receiver
command := &ConcreteCommand{
Receiver: receiver,
}
// Execute command
command.Execute()
}
//An example of Dependency Injection in Golang is as follows:
package main
import (
"fmt"
)
type Service interface {
DoSomething() string
}
type ServiceImpl struct {
//...
}
func (s *ServiceImpl) DoSomething() string {
return "This is a service implementation"
}
type Client struct {
Service Service
}
func NewClient(service Service) *Client {
return &Client{Service: service}
}
func (c *Client) DoSomething() string {
return c.Service.DoSomething()
}
func main() {
service := &ServiceImpl{}
c := NewClient(service)
fmt.Println(c.DoSomething())
}
//Here is an example of dependency inversion in Go:
// Create an interface
type Printer interface {
Print(string)
}
// Create two implementations of the Printer interface
type ConsolePrinter struct {
}
func (cp *ConsolePrinter) Print(text string) {
fmt.Println(text)
}
type FilePrinter struct {
fileName string
}
func (fp *FilePrinter) Print(text string) {
f, _ := os.Create(fp.fileName)
f.WriteString(text)
f.Close()
}
// Create a struct that depends on the Printer interface
type PrintService struct {
printer Printer
}
// Dependency injection, inject the Printer implementation
func (ps *PrintService) SetPrinter(p Printer) {
ps.printer = p
}
// Use the Printer implementation
func (ps *PrintService) PrintText(text string) {
ps.printer.Print(text)
}
// Create a ConsolePrinter and a FilePrinter
consolePrinter := &ConsolePrinter{}
filePrinter := &FilePrinter{"example.txt"}
// Create a PrintService and inject the ConsolePrinter
printService := &PrintService{}
printService.SetPrinter(consolePrinter)
printService.PrintText("Hello World!")
// Inject the FilePrinter into the PrintService
printService.SetPrinter(filePrinter)
printService.PrintText("Hello World!")
The best design patterns for Golang programming language are:
1. Builder Pattern
2. Singleton Pattern
3. Observer Pattern
4. Factory Pattern
5. Strategy Pattern
6. Dependency Injection
7. Command Pattern
// A type factoryFunc is a function that takes a string and returns a type.
type factoryFunc func(string) interface{}
// A type registry is a map of strings to factory functions.
type registry map[string]factoryFunc
// A type Factory is a registry of factory functions.
type Factory struct {
registry registry
}
// NewFactory returns a new instance of Factory initialized with the
// given registry of factory functions.
func NewFactory(registry registry) *Factory {
return &Factory{
registry: registry,
}
}
// Create takes a string and uses it to look up a factory function in the
// registry. It then calls the factory function to create and return a new
// instance of the type.
func (f *Factory) Create(name string) interface{} {
factoryFunc, ok := f.registry[name]
if !ok {
return nil
}
return factoryFunc(name)
}
// Example usage:
// Create a registry of factory functions.
registry := registry{
"foo": func(name string) interface{} {
return &Foo{Name: name}
},
"bar": func(name string) interface{} {
return &Bar{Name: name}
},
}
// Create a new factory with the registry.
factory := NewFactory(registry)
// Create a new instance of "foo".
foo := factory.Create("foo").(*Foo)
//This is a basic example of an observer pattern in Golang:
//Observer interface
type Observer interface {
OnNotify(data interface{})
}
//Observable interface
type Observable interface {
Register(obs Observer)
Unregister(obs Observer)
NotifyObservers(data interface{})
}
//Observable struct
type observable struct {
observers []Observer
}
func (o *observable) Register(obs Observer) {
o.observers = append(o.observers, obs)
}
func (o *observable) Unregister(obs Observer) {
for i, oo := range o.observers {
if oo == obs {
o.observers = append(o.observers[:i], o.observers[i+1:]...)
break
}
}
}
func (o *observable) NotifyObservers(data interface{}) {
for _, obs := range o.observers {
obs.OnNotify(data)
}
}
//Observer struct
type observer struct {
id int
}
func (o *observer) OnNotify(data interface{}) {
fmt.Printf("Observer %d received data: %v\n", o.id, data)
}
func main() {
//Create observable
observable := &observable{}
//Create observers
observer1 := &observer{id: 1}
observer2 := &observer{id: 2}
//Register observers
observable.Register(observer1)
observable.Register(observer2)
//Notify observers
observable.NotifyObservers("Hello World!")
}
//Here is a code example of a Singleton pattern in Golang:
package singleton
import (
"sync"
)
var instance *Singleton
var once sync.Once
// Singleton struct
type Singleton struct{}
// GetInstance returns a singleton object
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{}
})
return instance
}
//Here is a good example of Strategy Pattern in Golang:
package main
import "fmt"
// Strategy is an interface
type Strategy interface {
DoOperation() int
}
// ConcreteStrategyA is a concrete implementation of Strategy interface
type ConcreteStrategyA struct {
}
// DoOperation is a method of ConcreteStrategyA which implements Strategy interface
func (s *ConcreteStrategyA) DoOperation() int {
return 1
}
// ConcreteStrategyB is a concrete implementation of Strategy interface
type ConcreteStrategyB struct {
}
// DoOperation is a method of ConcreteStrategyB which implements Strategy interface
func (s *ConcreteStrategyB) DoOperation() int {
return 2
}
// Context is a struct which holds a Strategy
type Context struct {
strategy Strategy
}
// SetStrategy is a method of Context which sets a strategy
func (c *Context) SetStrategy(strategy Strategy) {
c.strategy = strategy
}
// ExecuteStrategy is a method of Context which executes a strategy
func (c *Context) ExecuteStrategy() int {
return c.strategy.DoOperation()
}
func main() {
context := Context{}
context.SetStrategy(&ConcreteStrategyA{})
fmt.Println("Strategy A: ", context.ExecuteStrategy())
context.SetStrategy(&ConcreteStrategyB{})
fmt.Println("Strategy B: ", context.ExecuteStrategy())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment