设计模式-Facade(门面模式)GO语言版本

前言

个人理解Facade模式其实日常生活中已经不知不觉就在使用了,基本核心内容就是暴露一些简单操作的接口,实现上将一些内容封装起来。

如上图,外界使用内部子系统时,只需要通过调用facade接口层面的功能,不需要了解子系统内部情况。但是实际情况上,外界也可调用一系列系统内部函数,所以子系统并不是黑盒一样被封装起来

问题

假设你必须在代码中使用某个复杂的库或框架中的众多对象。 正常情况下, 你需要负责所有对象的初始化工作、 管理其依赖关系并按正确的顺序执行方法等。

例如,有一个家庭影院系统,包含DVD、投影仪、音响等等子系统,现在想要通过小爱同学使用这个家庭影院系统,应该怎么做呢

解决方案

本质上就是使用接口进行隔离,降低耦合程度,以及使用成本。

那你总不能说小爱同学帮我打开DVD、打开投影仪、打开音响吧,每次想看个电影那也太累了。

所以聪明的已经将上面操作封装一下了,如下。

各个子系统,DVD、投影仪、音响

Go 复制代码
// Subsystem - DVDPlayer
type DVDPlayer struct{}

func (d *DVDPlayer) On() {
    fmt.Println("DVD Player is on")
}

func (d *DVDPlayer) Play(movie string) {
    fmt.Printf("DVD Player is playing %s\n", movie)
}

func (d *DVDPlayer) Off() {
    fmt.Println("DVD Player is off")
}

// Subsystem - Projector
type Projector struct{}

func (p *Projector) On() {
    fmt.Println("Projector is on")
}

func (p *Projector) SetInput(source string) {
    fmt.Printf("Projector set input to %s\n", source)
}

func (p *Projector) Off() {
    fmt.Println("Projector is off")
}

// Subsystem - SoundSystem
type SoundSystem struct{}

func (s *SoundSystem) On() {
    fmt.Println("Sound System is on")
}

func (s *SoundSystem) SetVolume(volume int) {
    fmt.Printf("Sound System volume set to %d\n", volume)
}

func (s *SoundSystem) Off() {
    fmt.Println("Sound System is off")
}

封装的facade家庭影院子系统

Go 复制代码
type HomeTheaterFacade interface {
	WatchMovie(movie string)
	EndMovie()
}

type HomeTheaterFacadeImp struct {
	dvdPlayer   *DVDPlayer
	projector   *Projector
	soundSystem *SoundSystem
}

func NewHomeTheaterFacade() HomeTheaterFacade {
	return &HomeTheaterFacadeImp{
		dvdPlayer:   &DVDPlayer{},
		projector:   &Projector{},
		soundSystem: &SoundSystem{},
	}
}

func (h *HomeTheaterFacadeImp) WatchMovie(movie string) {
	h.dvdPlayer.On()
	h.projector.On()
	h.projector.SetInput("DVD")
	h.soundSystem.On()
	h.soundSystem.SetVolume(10)
	h.dvdPlayer.Play(movie)
}

func (h *HomeTheaterFacadeImp) EndMovie() {
	h.dvdPlayer.Off()
	h.projector.Off()
	h.soundSystem.Off()
}

使用示例

Go 复制代码
type XiaoAI struct {
	homeTheater HomeTheaterFacade
}

func NewXiaoAI() *XiaoAI{
	return &XiaoAI{
        homeTheater: NewHomeTheaterFacade(),
    }
}
func (x *XiaoAI) Watch(movie string){
	x.homeTheater.WatchMovie(movie)
}

func (x *XiaoAI) End(){
	x.homeTheater.EndMovie()
}

这样你想看电影只需要对小爱同学说给我Watch一个电影,就可以了,也不用关心它是怎么放的。 所有的细节都是背后去实现的。

以上就是代码的类图之间的关系,可以看出外部只需要依赖接口而不用考虑具体实现。当然facade设计模式本身还具有很多变体,本质上是封装使用。所以如果上面的功能需要可以让小爱同学调节音量等功能,也可以在封装出调节音量的函数。

相关推荐
workflower3 小时前
Prompt Engineering的重要性
大数据·人工智能·设计模式·prompt·软件工程·需求分析·ai编程
ox00807 小时前
C++ 设计模式-中介者模式
c++·设计模式·中介者模式
扣丁梦想家7 小时前
设计模式教程:中介者模式(Mediator Pattern)
设计模式·中介者模式
花王江不语7 小时前
设计模式学习笔记
笔记·学习·设计模式
YXWik610 小时前
23种设计模式
java·设计模式
攻城狮7号10 小时前
【第三节】C++设计模式(创建型模式)-单例模式
c++·单例模式·设计模式
zh路西法12 小时前
【C++委托与事件】函数指针,回调机制,事件式编程与松耦合的设计模式(上)
开发语言·c++·观察者模式·设计模式
ox008012 小时前
C++ 设计模式-备忘录模式
c++·设计模式·备忘录模式
強云12 小时前
23种设计模式 - 备忘录模式
设计模式·备忘录模式
ox008015 小时前
C++ 设计模式-策略模式
c++·设计模式·策略模式