简介
外观模式(Facade Pattern)是一种结构型设计模式,旨在为复杂子系统提供一个简化的接口,从而使客户端代码更容易使用。外观模式通过创建一个高层接口,将子系统的一组接口聚合在一起,从而隐藏了子系统的复杂性,使得客户端只需要与外观接口交互,而不需要直接与子系统的多个组件打交道。 外观模式涉及到的几个主要角色为:
外观
外观是外观模式的核心,它提供了一个简化的接口,将客户端请求委派给子系统的各个组件处理
子系统
子系统是外观模式的多个组件,实际上完成了系统的具体功能,外观通过与子系统的交互来完成客户端的请求
客户端
客户端是使用外观模式的一方,它通过外观的简化接口来与子系统进行交互,而不需要了解子系统的具体实现。
还是车,比如你有一辆宝马车,你最常见的就是启动和关闭,而汽车启动需要启动发动机、启动冷却系统、启动润滑系统,自动开启音乐让你听,关闭的时候,需要把以上系统全部关闭,然后关闭音乐等等。你启动汽车的时候,应该是一键启动吧,这些系统应该都不需要你独立的去启动吧。嗯,这就是外观模式,外观理解为启动按钮,子系统理解为发动机、冷却、润滑系统等等,客户端就是你的手指。
Demo
type operate interface {
open() string
close() string
}
type engine struct {
}
func (e *engine) open() string {
return "open engine"
}
func (e *engine) close() string {
return "close engine"
}
type music struct {
}
func (e *music) open() string {
return "open music"
}
func (e *music) close() string {
return "close music"
}
type Facade struct {
eng engine
mus music
}
func NewFacade() *Facade {
return &Facade{
eng: engine{},
mus: music{},
}
}
// 启动车子
func (f *Facade) startCar() string {
result := "车子启动中...\n"
result += f.eng.open() + "\n"
result += f.mus.open()
return result
}
// 车子熄火
func (f *Facade) stopCar() string {
result := "车子熄火中...\n"
result += f.eng.close() + "\n"
result += f.mus.close()
return result
}
测试
func TestOperateCar(t *testing.T) {
fmt.Println(NewFacade().startCar())
fmt.Println(NewFacade().stopCar())
}
作用和场景
简化复杂系统接口
很明显,我们通过提供一个简单的接口,启动或者熄火车子,而隐藏了下面复杂的子系统的实现细节,使得客户端无需直接与系统的多个组件交互
解耦客户端和子系统
降低了客户端和子系统的耦合度,客户端只需要与外观接口交互,不需要了解系统内部的具体实现
提高灵活性
系统的改变,只需要更新外观类而不需要修改客户端代码,比如开启音乐,使用随机播放,就可以在开启音乐的系统中做业务逻辑了
所以,当一个系统由多个子系统组成,而客户端只需要使用其中一部分功能的时候,就可以使用外观模式提供一个简单的接口了。
总的来说,外观模式适用于需要简化复杂系统接口、解耦客户端和子系统、提高系统灵活性以及隐藏实现细节的情况。通过提供一个统一的外观接口,外观模式使得系统更易于维护、扩展和理解。