mirror of
https://github.com/crazybber/awesome-patterns.git
synced 2024-11-22 04:36:02 +03:00
added builder pattern
This commit is contained in:
parent
4dd2bfaabf
commit
9651c9747d
67
go_design_pattern_book/concurrent_pattern/pipeline/main.go
Normal file
67
go_design_pattern_book/concurrent_pattern/pipeline/main.go
Normal file
@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func main() {
|
||||
in := gen(2, 3)
|
||||
|
||||
// Distribute the sq work across two goroutines that both read from in.
|
||||
c1 := sq(in)
|
||||
c2 := sq(in)
|
||||
|
||||
// Consume the merged output from c1 and c2.
|
||||
for n := range merge(c1, c2) {
|
||||
fmt.Println(n) // 4 then 9, or 9 then 4
|
||||
}
|
||||
}
|
||||
|
||||
func gen(nums ...int) <-chan int {
|
||||
out := make(chan int, len(nums))
|
||||
go func() {
|
||||
for _, n := range nums {
|
||||
out <- n
|
||||
}
|
||||
close(out)
|
||||
}()
|
||||
return out
|
||||
}
|
||||
|
||||
func sq(in <-chan int) <-chan int {
|
||||
out := make(chan int)
|
||||
go func() {
|
||||
for n := range in {
|
||||
out <- n * n
|
||||
}
|
||||
close(out)
|
||||
}()
|
||||
return out
|
||||
}
|
||||
|
||||
func merge(cs ...<-chan int) <-chan int {
|
||||
var wg sync.WaitGroup
|
||||
out := make(chan int, 1) // enough space for the unread inputs
|
||||
|
||||
// Start an output goroutine for each input channel in cs. output
|
||||
// copies values from c to out until c is closed, then calls wg.Done.
|
||||
output := func(c <-chan int) {
|
||||
for n := range c {
|
||||
out <- n
|
||||
}
|
||||
wg.Done()
|
||||
}
|
||||
wg.Add(len(cs))
|
||||
for _, c := range cs {
|
||||
go output(c)
|
||||
}
|
||||
|
||||
// Start a goroutine to close out once all the output goroutines are
|
||||
// done. This must start after the wg.Add call.
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(out)
|
||||
}()
|
||||
return out
|
||||
}
|
84
go_design_pattern_book/creational/builder/main.go
Normal file
84
go_design_pattern_book/creational/builder/main.go
Normal file
@ -0,0 +1,84 @@
|
||||
package main
|
||||
|
||||
// Builder design pattern tried to
|
||||
// 1. Abstract complex creations so that object creation is seperated from object user.
|
||||
// 2. Create an object step by step by filling it's fields and creating embedded objects.
|
||||
// 3. Reuse the object creation algorithm between many objects.
|
||||
// Builder design pattern is often described as a relationship between a director and builders.
|
||||
// Director in charge of construction of objects.
|
||||
// Builders are the ones that return actual products.
|
||||
|
||||
// BuildProcess is a procceding interface defines each steps needed for building vehicle.
|
||||
type BuildProcess interface {
|
||||
SetWheels() BuildProcess
|
||||
SetSeats() BuildProcess
|
||||
SetStructure() BuildProcess
|
||||
GetVehicle() VehicleProduct
|
||||
}
|
||||
|
||||
// VehicleProduct is the product that we want to retrieve while using manufacturing.
|
||||
type VehicleProduct struct {
|
||||
Wheels int
|
||||
Seats int
|
||||
Structure string
|
||||
}
|
||||
|
||||
// ManufacturingDirector is the one that in charge of accepting builders.
|
||||
// It has a Construct method that will use builder that is stored in Manufacturing, and will reproduce the required steps.
|
||||
type ManufacturingDirector struct {
|
||||
builder BuildProcess
|
||||
}
|
||||
|
||||
func (f *ManufacturingDirector) Construct() {
|
||||
f.builder.SetSeats().SetStructure().SetWheels()
|
||||
}
|
||||
|
||||
func (f *ManufacturingDirector) SetBuilder(b BuildProcess) {
|
||||
f.builder = b
|
||||
}
|
||||
|
||||
type CarBuilder struct {
|
||||
v VehicleProduct
|
||||
}
|
||||
|
||||
func (c *CarBuilder) SetWheels() BuildProcess {
|
||||
c.v.Wheels = 4
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CarBuilder) SetSeats() BuildProcess {
|
||||
c.v.Seats = 5
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CarBuilder) SetStructure() BuildProcess {
|
||||
c.v.Structure = "Car"
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *CarBuilder) GetVehicle() VehicleProduct {
|
||||
return c.v
|
||||
}
|
||||
|
||||
type BikeBuilder struct {
|
||||
v VehicleProduct
|
||||
}
|
||||
|
||||
func (b *BikeBuilder) SetWheels() BuildProcess {
|
||||
b.v.Wheels = 2
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *BikeBuilder) SetSeats() BuildProcess {
|
||||
b.v.Seats = 2
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *BikeBuilder) SetStructure() BuildProcess {
|
||||
b.v.Structure = "Bike"
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *BikeBuilder) GetVehicle() VehicleProduct {
|
||||
return b.v
|
||||
}
|
24
go_design_pattern_book/creational/builder/main_test.go
Normal file
24
go_design_pattern_book/creational/builder/main_test.go
Normal file
@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBuilderPatter(t *testing.T) {
|
||||
manufacturingComplex := ManufacturingDirector{}
|
||||
carBuilder := &CarBuilder{}
|
||||
manufacturingComplex.SetBuilder(carBuilder)
|
||||
manufacturingComplex.Construct()
|
||||
car := carBuilder.GetVehicle()
|
||||
if car.Wheels != 4 {
|
||||
t.Errorf("number of wheels in car should be 4, it is %d", car.Seats)
|
||||
}
|
||||
|
||||
bikeBuilder := &BikeBuilder{}
|
||||
manufacturingComplex.SetBuilder(bikeBuilder)
|
||||
manufacturingComplex.Construct()
|
||||
bike := bikeBuilder.GetVehicle()
|
||||
if bike.Wheels != 2 {
|
||||
t.Errorf("number of wheels on bike should be 2, it is %d", bike.Seats)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user