Pipeline Pattern with Golang

87 阅读1分钟

In some case when we need to process some data not all at once, this is when the pipeline pattern comes in.

The pipeline pattern contains two elements in all: node and pipeline, node is used to denote the process logic, and pipeline connects all the nodes together to finish the overall processing logic.

Here is my implementation of pipeline with golang, first comes in the node,

type Node interface {
	GetNext() Node
	SetNext(valve Node)
	Invoke(s string) string
}

type BaseNode struct {
	Next Node
}

func (v *BaseNode) GetNext() Node {
	return v.Next
}

func (v *BaseNode) SetNext(valve Node) {
	v.Next = valve
}

type FirstNode struct {
	BaseNode
}

func (v *FirstNode) Invoke(s string) string {
	s = strings.Replace(s, "11", "first", -1)
	fmt.Println("After the first valve, s: " + s)
	return s
}

type SecondNode struct {
	BaseNode
}

func (v *SecondNode) Invoke(s string) string {
	s = strings.Replace(s, "22", "second", -1)
	fmt.Println("After the second valve, s: " + s)
	return s
}

type ThirdNode struct {
	BaseNode
}

func (v *ThirdNode) Invoke(s string) string {
	s = strings.Replace(s, "33", "third", -1)
	fmt.Println("After the third valve, s: " + s)
	return s
}

then the pipeline interface and its implementation,

type Pipeline interface {
	GetHead() Node
	AddNode(valve Node)
	Invoke(s string)
}

type MyPipeline struct {
	Head Node
}

func (p *MyPipeline) GetHead() Node {
	return p.Head
}

func (p *MyPipeline) AddNode(valve Node) {
	if p.Head == nil {
		p.Head = valve
		p.Head.SetNext(nil)
	} else {
		current := p.Head
		for current.GetNext() != nil {
			current = current.GetNext()
		}
		current.SetNext(valve)
		current.GetNext().SetNext(nil)
	}
}

func (p *MyPipeline) Invoke(s string) {
	current := p.Head
	for current != nil {
		s = current.Invoke(s)
		current = current.GetNext()
	}
}

and last the main func,

func main() {
	firstValve := FirstNode{}
	secondValve := SecondNode{}
	ThirdValve := ThirdNode{}

	pipeline := MyPipeline{}
	pipeline.AddNode(&firstValve)
	pipeline.AddNode(&secondValve)
	pipeline.AddNode(&ThirdValve)

	pipeline.Invoke("11 22 33")
}

ok, that's all.