mirror of
https://github.com/crazybber/awesome-patterns.git
synced 2024-11-25 22:36:05 +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