package
0.0.0-20240828052546-079cc6e6950d
Repository: https://github.com/kokoiruby/go_learning.git
Documentation: pkg.go.dev
# README
IoC
Inversion of Control 反转控制:一种软件设计原则,将控制权从代码内部转移给外部容器或框架,以实现松散耦合和可重用性。
最常见的实现:DI Dependency Injection 依赖注入,通过外部将依赖关系传递给组件,而不是组件自己创建或查找依赖关系。
思想:将控制逻辑 & 业务逻辑分离,业务逻辑依赖控制逻辑 = 控制逻辑注入业务逻辑 = 将控制逻辑转换成接口,让业务逻辑去实现。
例子:
- 开关是控制逻辑,电器是业务逻辑,不要在电器中实现开关,而是把开关抽象成一种协议,让电器都依赖之。
- 如果某个类需要一个成员对象,那么这个对象不应该是类自己生成,而是由外部传入类构造器。
Composite
Go 中通过组合 Composite 将一个结构体嵌入另一个。
type Widget struct {
X, Y int
}
type Label struct {
Widget // Embedding (delegation)
Text string // Aggregation
}
label := Label{Widget{10, 10}, "State:"}
label.X = 11
label.Y = 12
// Button ← Label ← Widget
type Button struct {
Label // Embedding (delegation)
}
// ListBox ← Widget
type ListBox struct {
Widget // Embedding (delegation)
Texts []string // Aggregation
Index int // Aggregation
}
通过接口 interface 实现方法重写
type Painter interface {
Paint()
}
type Clicker interface {
Click()
}
实现:
- Label → Painter
- Button & ListBox → Painter & Clicker
func (label Label) Paint() {
fmt.Printf("%p:Label.Paint(%q)\n", &label, label.Text)
}
// if not implemented, will call Label.Paint()
// if implemented, overriding
func (button Button) Paint() {
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)
}
多态:父类指针/引用 → 子类的具体实现
button := Button{Label{Widget{10, 70}, "OK"}}
listBox := ListBox{Widget{10, 40}, []string{"AL", "AK", "AZ", "AR"}, 0}
for _, painter := range []Painter{button, listBox} {
painter.Paint()
}
Practice
IntSet
is buz while Undo
is logic control.
// bad
type IntSet struct {
data map[int]struct{}
}
type UndoableIntSet struct {
IntSet // buz in logic
functions []func()
}
// good
type Undo []func()
func (undo *Undo) Add(function func()) { ... }
func (undo *Undo) Undo() error { ... }
type IntSetNew struct {
data map[int]bool
undo Undo // dep inject, logic in buz
}