外观模式

  1. Facade Pattern
  2. 例子
    1. 实现
    2. 使用
  3. 优缺点
    1. 优点
    2. 缺点
  4. 应用情景

Facade Pattern

   外观模式其实就是把复杂的东西给封装,由统一的接口进行操作。这样可以简化用户的使用。

例子

  如果要开一家饭馆,一个饭馆分为采购的,管仓库的,切菜的,炒菜的,吃菜的。

  而采购的,管仓库的,切菜的,炒菜的,是厨房。吃菜的,是客户。客户并不希望知道厨房工作的细节,只希望告诉厨房自己想吃什么就行了,他不想告诉厨房要去买什么菜,怎么切,怎么炒。而巧的是,厨房也只希望给客户提供有限的选择即可,具体工作的细节由自己控制就行。因此厨房和客户之间只隔着一个菜单和服务员。

实现

  先来实现厨房的各个部门

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

// 虽然把蔬菜定义在厨房的采购部并不合理
// 但是我还是这么做了
const (
STATUS_BUYED = iota
STATUS_STORED
STATUS_CUTED
STATUS_COOKED
STATUS_EATED
)

type VegStatus int

type Vegetable struct {
name string
status VegStatus
}

func BuyVegetable(name string) *Vegetable {
return &Vegetable{name, STATUS_BUYED}
}

func Eat(veg *Vegetable) {
veg.status = STATUS_EATED
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package facade
// 买回来就要保存
var storage []*Vegetable = make([]*Vegetable, 0)

func SaveVegetables(veg ...*Vegetable) {
storage = append(storage,veg...)
for _,v := range veg{
v.status=STATUS_STORED
}
}

func GetVegetables() *Vegetable {
l := len(storage)
res := storage[l-1]
storage = storage[:l-1]
return res
}


1
2
3
4
5
6
7
8
9
10
package facade
// 切菜
// 具体拿去做什么不知道
// 只管切
func CutVegtable(veg ...*Vegetable)[]*Vegetable{
for _,v := range veg{
v.status=STATUS_CUTED
}
return veg
}


1
2
3
4
5
6
7
8
9
10
package facade
// 炒菜
// 给谁吃不知道
// 炒就是了
func CookVegtable(vec ...*Vegetable)[]*Vegetable{
for _,v := range vec{
v.status=STATUS_COOKED
}
return vec
}


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

// 菜单
// 客户随意选择
// 制作方式可以由主厨决定
// 只要客户喜欢
func SauteVegtable()[]*Vegetable{
qc := BuyVegetable("青菜")
suan := BuyVegetable("蒜")
jiang := BuyVegetable("姜")
SaveVegetables(qc,suan,jiang)

vegs := CookVegtable(CutVegtable(storage...)...)
return vegs
}


使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
func EatVegtables(veg ...*Vegetable){
for _,v :=range veg{
Eat(v)
}
}

func main(){

// No Facade
bc := BuyVegetable("白菜")
SaveVegetables(bc)
vecs := CookVegtable(GetVegetables())
EatVegtables(vecs...)
for _,v := range vecs{
fmt.Println(*v)
}

// Favade
sauteVegtable := SauteVegtable()
EatVegtables(sauteVegtable...)
for _,v := range sauteVegtable{
fmt.Println(*v)
}
}


优缺点

优点

  • 它对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
  • 它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。

缺点

  • 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
  • 对客户访问子系统类做太多的限制则减少了可变性和灵活性。

应用情景

  • 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。
  • 客户程序与多个子系统之间存在很大的依赖性。
  • 在分层结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。



转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件