Created
February 19, 2023 20:29
-
-
Save Apurer/c992b731fcdd3c14ee8387e945ac9b18 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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()) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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!") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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!") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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