医生治疗:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

type Docker struct{}

func (d *Docker) treatEye() {
fmt.Println("医生治疗眼睛")
}
func (d *Docker) treatNose() {
fmt.Println("医生治疗鼻子")
}

func main() {
docker := &Docker{}
docker.treatEye()
docker.treatNose()
}

这样的代码有一个问题。加入Docker是一个非常核心的模块。不希望和某个业务耦合度高。应该支持迪米特法则。修改成需要填写病单。

img

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
package main

import "fmt"

type Docker struct{}

func (d *Docker) treatEye() {
fmt.Println("医生治疗眼睛")
}
func (d *Docker) treatNose() {
fmt.Println("医生治疗鼻子")
}

type CommandTreatEye struct {
Docker *Docker
}

func (c *CommandTreatEye) Treat() {
c.Docker.treatEye()
}

type CommandTreatNose struct {
Docker *Docker
}

func (c *CommandTreatNose) Treat() {
c.Docker.treatNose()
}
func main() {
Docker := &Docker{}
CommandTreatEye := &CommandTreatEye{Docker}
CommandTreatNose := &CommandTreatNose{Docker}
CommandTreatEye.Treat()
CommandTreatNose.Treat()
}

这样还是很麻烦。当病人很多的时候,每个病人都需要知道如何去填病单。也就是说业务层的代码编写繁琐。

“护士”对接抽象的病单。通过多态对不同的实例对象实现不同的Treat()

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
55
package main

import "fmt"

type Docker struct{}

func (d *Docker) treatEye() {
fmt.Println("医生治疗眼睛")
}
func (d *Docker) treatNose() {
fmt.Println("医生治疗鼻子")
}

type Command interface {
Treat()
}
type CommandTreatEye struct {
Docker *Docker
}

func (c *CommandTreatEye) Treat() {
c.Docker.treatEye()
}

type CommandTreatNose struct {
Docker *Docker
}

func (c *CommandTreatNose) Treat() {
c.Docker.treatNose()
}

type Nurse struct {
CmdList []Command
}

func (n *Nurse) Notify() {
if n.CmdList == nil {
return
}
for _, cmd := range n.CmdList {
cmd.Treat()
}
}
func main() {
Docker := &Docker{}
CmdEye := &CommandTreatEye{Docker}
CmdNose := &CommandTreatNose{Docker}

nurse := new(Nurse)
nurse.CmdList = append(nurse.CmdList, CmdEye)
nurse.CmdList = append(nurse.CmdList, CmdNose)

nurse.Notify()
}

练习:设计烤串场景

有烤羊肉,烤鸡翅,有烤串师傅 ,有服务员。

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
55
56
57
58
package main

import "fmt"

type Cooker struct{}

func (c *Cooker) MakeChicken() {
fmt.Println("烤串师傅烤了鸡肉串儿")
}
func (c *Cooker) MakeChuaner() {
fmt.Println("烤串师傅烤了羊肉串儿")
}

type CommandCookChicken struct {
cooker *Cooker
}

func (cmd *CommandCookChicken) Make() {
cmd.cooker.MakeChicken()
}

type CommandCookChuaner struct {
cooker *Cooker
}

func (cmd *CommandCookChuaner) Make() {
cmd.cooker.MakeChuaner()
}

type Menu interface {
Make()
}

type WaiterMM struct {
MenuList []Menu
}

func (w *WaiterMM) Notify() {
if w.MenuList == nil {
return
}

for _, cmd := range w.MenuList {
cmd.Make()
}
}
func main() {
cooker := new(Cooker)
cmdChicken := CommandCookChicken{cooker}
cmdChuaner := CommandCookChuaner{cooker}

mm := new(WaiterMM)
mm.MenuList = append(mm.MenuList, &cmdChicken)
mm.MenuList = append(mm.MenuList, &cmdChuaner)

mm.Notify()
}