嵌入委托 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package maintype Widget struct { X, Y int } type Label struct { Widget Text string } type Button struct { Label } type ListBox struct { Widget Texts []string Index int } func main () { label := Label{Widget{10 , 10 }, "State:" } label.X = 11 label.Y = 12 }
方法重写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 type Painter interface { Paint() } type Clicker interface { Click() } func (label Label) Paint() { fmt.Printf("%p:Label.Paint(%q)\n" , &label, label.Text) } 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) } func main () { var painter Painter = Button{Label{Widget{10 , 70 }, "ok" }} painter.Paint() }
多态 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 b1 := Button{Label{Widget{10 , 70 }, "OK" }} b2 := Button{Label{Widget{10 , 40 }, "Cancel" }} listBox := ListBox{Widget{10 , 40 }, []string {"AL" , "AK" , "AZ" , "AR" }, 0 } label := Label{Text: "aa" } for _, painter := range []Painter{label, listBox, b1, b2} { painter.Paint() } for _, widget := range []interface {}{label, listBox, b1, b2} { widget.(Painter).Paint() if clicker, ok := widget.(Clicker); ok { clicker.Click() } fmt.Println() }
控制反转
将控制逻辑和业务逻辑分开,让业务逻辑
依赖于控制逻辑
,要依赖抽象
,而非依赖具体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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] }
基于 IntSet 实现 Undo 功能,Undo 本身为控制逻辑
,与 IntSet 强耦合
,不利于复用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 type UndoableIntSet struct { IntSet functions []func () } func NewUndoableIntSet () UndoableIntSet { return UndoableIntSet{NewIntSet(), nil } } func (set *UndoableIntSet) Add(x int ) { 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 *UndoableIntSet) Delete(x int ) { 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 *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 } set.functions = set.functions[:index] return nil }
反转依赖
- 业务逻辑依赖控制逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 type Undo []func () func (undo *Undo) Add(function func () ) { *undo = append (*undo, function) } 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 } *undo = functions[:index] return nil } type IntSet struct { data map [int ]bool undo Undo } func NewIntSet () IntSet { return IntSet{data: make (map [int ]bool )} } func (set *IntSet) Undo() error { return set.undo.Undo() } func (set *IntSet) Contains(x int ) bool { return set.data[x] } func (set *IntSet) 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 *IntSet) Delete(x int ) { if set.Contains(x) { delete (set.data, x) set.undo.Add(func () { set.Add(x) }) } else { set.undo.Add(nil ) } }