Если вы видите что-то необычное, просто сообщите мне.

Простая инструкция изучения Цепочи обязаностей в Golang

Что такое цепочка обязаностей(Chain of Responsibility)?

Проблема

Представим, вы рабоаете над приложениме онлаин курсов. Вот список проверок перед тем как можно использовать курс.

Having a big headache

Solution

Diagram

Handler

Base handler

Main

Concrete Handlers

Pros and Cons Pros

Cons

How to code a simple Chain of Responsibility in Golang?

Section

package main

type section interface {
	execute(*task)
	setNext(section)
}

Material

package main

import (
	"fmt"
)

type material struct {
	next section
}

func (m *material) execute(t *task) {
	if t.materialCollected {
		fmt.Println("Material already collected")
		m.next.execute(t)
		return
	}
	fmt.Println("Material section gathering materials")
	t.materialCollected = true
	m.next.execute(t)
}

func (m *material) setNext(next section) {
	m.next = next
}

Assembly

package main

import (
	"fmt"
)

type assembly struct {
	next section
}

func (a *assembly) execute(t *task) {
	if t.assemblyExecuted {
		fmt.Println("Assembly already done")
		a.next.execute(t)
		return
	}
	fmt.Println("Assembly section assembling...")
	t.assemblyExecuted = true
	a.next.execute(t)
}

func (a *assembly) setNext(next section) {
	a.next = next
}
view raw

Packaging

package main

import (
	"fmt"
)

type packaging struct {
	next section
}

func (p *packaging) execute(t *task) {
	if t.packagingExecuted {
		fmt.Println("Packaging already done")
		p.next.execute(t)
		return
	}
	fmt.Println("Packaging section doing packaging")
}

func (p *packaging) setNext(next section) {
	p.next = next
}

Task

package main

type task struct {
	name				string
	materialCollected	bool
	assemblyExecuted	bool
	packagingExecuted	bool
}

Main

package main

func main() {
	packaging := &packaging{}

	// set next for assembly section
	assembly := &assembly{}
	assembly.setNext(packaging)

	material := &material{}
	material.setNext(assembly)

	task := &task{name: "truck_toy"}
	material.execute(task)
}

Explanation

section.go is a Handler interface. This interface handling requests and sets the next handler on the chain.

material.go is a Concrete handler. It decides if the request to collect material should be processed and can move up the chain.

assembly.go is a Concrete handler. It decides if the request to perform the assembly work should be processed and can move up the chain.

packaging.go is a Concrete handler. It decides if the request to perform the packaging work should be processed and can move up the chain.

main.go is a client. Initializes up the chain of handlers.

How to run

Command:

go run .

Material section gathering materials
Assembly section assembling…
Packaging section doing packaging

Takeaways

I hope you understand how to code a simple abstract factory in Golang and more importantly understand how a chain of responsibility design pattern can help you to design your code better and to ensure maintainability.


Revision #1
Created 2021-09-09 06:22:35 UTC by gasick
Updated 2023-04-16 19:30:04 UTC by gasick