当前位置: 首页 > 工具软件 > IOC-golang > 使用案例 >

golang ioc 控制反转

米裕
2023-12-01
package main

import (
	"errors"
	"fmt"
)

type Widget struct {
	X, Y int
}

type Label struct {
	Widget        // Embedding (delegation)
	Text   string // Aggregation
}

func (label Label) Paint() {
	fmt.Printf("%p:Label.Paint(%q)\n", &label, label.Text)
}

type Button struct {
	Label
}

// Embedding (delegation)}

type ListBox struct {
	Widget          // Embedding (delegation)
	Texts  []string //Aggregation
	Index  int      //Aggregation
}

// 因为这个接口可以通过 Label 的嵌入带到新的结构体,
// 所以,可以在 Button 中重载这个接口方法

func (button Button) Paint() { // Override
	fmt.Printf("Button.Paint(%s)\n", button.Text)
}
func (button Button) Click() {
	fmt.Printf("Button.Click(%s)\n", button.Text)
}

func (listBox ListBox) Paint() {
	fmt.Printf("ListBox.Paint(%q)\n", listBox.Texts)
}
func (listBox ListBox) Click() {
	fmt.Printf("ListBox.Click(%q)\n", listBox.Texts)
}

type Painter interface {
	Paint()
}

type Clicker interface {
	Click()
}
func main() {
	label := Label{
		Widget: Widget{
			X: 1,
			Y: 2,
		},
		Text: "88888888899999",
	}
	label.Paint()

	button := Button{
		Label: label,
	}
	button.Paint()

	button1 := Button{
		Label{
			Widget{10, 70},
			"OK",
		},
	}
	button2 := Button{
		Label{
			Widget{50, 70},
			"Cancel",
		},
	}
	listBox := ListBox{
		Widget{10, 40},
		[]string{"AL", "AK", "AZ", "AR"},
		0,
	}

	for _, painter := range []Painter{label, listBox, button1, button2} {
		painter.Paint()
	}

	for _, widget := range []interface{}{label, listBox, button1, button2} {
		widget.(Painter).Paint()
		if clicker, ok := widget.(Clicker); ok {
			clicker.Click()
		}
		fmt.Println() // print a empty line
	}
}

type IntSet struct {
	data map[int]bool
}
func NewIntSet() IntSet {
	return IntSet{make(map[int]bool)}
}
func (set *IntSet) Add(x int) {
	set.data[x] = true
}
func (set *IntSet) Delete(x int) {
	delete(set.data, x)
}
func (set *IntSet) Contains(x int) bool {
	return set.data[x]
}

type UndoableIntSet struct { // Poor style
	IntSet    // Embedding (delegation)
	functions []func()
}

type IntSetV2 struct {
	data map[int]bool
	undo Undo
}


func NewUndoableIntSet() UndoableIntSet {
	return UndoableIntSet{NewIntSet(), nil}
}

func NewIntSetV2() IntSetV2 {
	return IntSetV2{data: make(map[int]bool)}
}

func (set *UndoableIntSet) Add(x int) { // Override
	if !set.Contains(x) {
		set.data[x] = true
		set.functions = append(set.functions, func() { set.Delete(x) })
	} else {
		set.functions = append(set.functions, nil)
	}
}

// 控制反转

func (set *IntSetV2) Add(x int) {
	if !set.Contains(x) {
		set.data[x] = true
		set.undo.Add(func() { set.Delete(x) })
	} else {
		set.undo.Add(nil)
	}
}

func (set *UndoableIntSet) Delete(x int) { // Override
	if set.Contains(x) {
		delete(set.data, x)
		set.functions = append(set.functions, func() { set.Add(x) })
	} else {
		set.functions = append(set.functions, nil)
	}
}

// 控制反转

func (set *IntSetV2) Delete(x int) {
	if set.Contains(x) {
		delete(set.data, x)
		set.undo.Add(func() { set.Add(x) })
	} else {
		set.undo.Add(nil)
	}
}

// 控制反转

func (set *IntSetV2) Contains(x int) bool {
	return set.data[x]
}

// 控制依赖业务

func (set *UndoableIntSet) Undo() error {
	if len(set.functions) == 0 {
		return errors.New("No functions to undo")
	}
	index := len(set.functions) - 1
	if function := set.functions[index]; function != nil {
		function()
		set.functions[index] = nil // For garbage collection
	}
	set.functions = set.functions[:index]
	return nil
}

// 控制和业务解耦
// 控制反转-----------业务逻辑依赖控制,实现代码复用;

func (set *IntSetV2) Undo() error {
	return set.undo.Undo()
}

// 反转依赖

type Undo []func()

// 控制逻辑---业务依赖控制逻辑

func (undo *Undo) Add(function func()) {
	*undo = append(*undo, function)
}

// 业务依赖控制,undo没有和业务相关的依赖

func (undo *Undo) Undo() error {
	functions := *undo
	if len(functions) == 0 {
		return errors.New("No functions to undo")
	}
	index := len(functions) - 1
	if function := functions[index]; function != nil {
		function()
		functions[index] = nil // For garbage collection
	}
	*undo = functions[:index]
	return nil
}

 类似资料: