【设计模式】9、facade 外观模式

embedded/2024/9/25 15:28:48/

文章目录

  • 九、外观模式
    • 9.1 player
      • 9.1.1 player_test.go
      • 9.1.2 player.go
    • 9.2 login_register
      • 9.2.1 account_test.go
      • 9.2.2 account.go

九、外观模式

https://refactoringguru.cn/design-patterns/facade

如果有一个复杂的系统, 内部有很多子系统, 可以用 facade 封装一层, 只暴露出用户关心的简单接口.

注意: 随着需求增多, 不要做一个大而全的 facade, 而可以做多个小而美的 facade.

优点: 封装一层, 对外部用户屏蔽细节, 简化使用
缺点: 容易让所有系统, 都和 facade 耦合, 从而无法区分.

9.1 player

https://www.codingexplorations.com/blog/design-pattern-series-understanding-the-facade-design-pattern-in-go

播放电影, 需要各个子系统共同参与, 这种过程式的代码太繁琐, 可以抽象出 facade, 简化用户的操作

09facade/091player
├── player.go
├── player_test.go
└── readme.md

9.1.1 player_test.go

package _91playerimport "testing"/*
=== RUN   TestPlayMovie
开始播放电影...
Playing audio...
Playing video...
Showing screen...
结束播放电影...
--- PASS: TestPlayMovie (0.00s)
PASS
*/
func TestPlayMovie(t *testing.T) {f := &MultimediaFacade{audioPlayer:   &AudioPlayer{},videoPlayer:   &VideoPlayer{},screenManager: &ScreenManager{},}f.PlayMovie()
}

9.1.2 player.go

package _91playerimport ("fmt"
)// AudioPlayer 子系统
type AudioPlayer struct{}func (a *AudioPlayer) PlayAudio() {fmt.Println("Playing audio...")
}// VudioPlayer 子系统
type VideoPlayer struct{}func (v *VideoPlayer) PlayVideo() {fmt.Println("Playing video...")
}// ScreenManager 子系统
type ScreenManager struct{}func (s *ScreenManager) ShowScreen() {fmt.Println("Showing screen...")
}// MultimediaFacade 外观
type MultimediaFacade struct {audioPlayer   *AudioPlayervideoPlayer   *VideoPlayerscreenManager *ScreenManager
}func (f *MultimediaFacade) PlayMovie() {fmt.Println("开始播放电影...")f.audioPlayer.PlayAudio()f.videoPlayer.PlayVideo()f.screenManager.ShowScreen()fmt.Println("结束播放电影...")
}

9.2 login_register

网站都提供登录, 注册两种方式, 用户经常分不清楚

现在很多 APP 都提供了登录或注册功能, 即只需要输入手机号即可. 内部的逻辑是:

  • 如果未注册, 则注册并登录
  • 如果已注册, 则登录

可以提供一个 facade, 实现[登录或注册]的功能

09facade/092login_register
├── account.go
├── account_test.go
└── readme.md

9.2.1 account_test.go

package _92login_registerimport ("testing"
)/*
=== RUN   TestAccount
登录或注册
登录
--- PASS: TestAccount (0.00s)
PASS
*/
func TestAccount(t *testing.T) {a := &accountFacadeService{service: &accountService{}}a.loginOrRegister()
}

9.2.2 account.go

package _92login_registerimport "fmt"type iAccount interface {login()register()
}type iAccountFacade interface {loginOrRegister()
}type accountService struct{}func (s *accountService) login() {fmt.Println("登录")
}func (s *accountService) register() {fmt.Println("注册")
}// 是否已注册
func (s *accountService) isRegistered() bool {return true
}type accountFacadeService struct {service *accountService
}func (s *accountFacadeService) loginOrRegister() {fmt.Println("登录或注册")if !s.service.isRegistered() {s.service.register()}s.service.login()
}

http://www.ppmy.cn/embedded/15463.html

相关文章

【汇编语言】流程转移和子程序

【汇编语言】流程转移和子程序 文章目录 【汇编语言】流程转移和子程序前言一、“转移”综述二、操作符offset三、jmp指令jmp指令——无条件转移jmp指令:依据位移进行转移两种段内转移远转移:jmp far ptr 标号转移地址在寄存器中的jmp指令转移地址在内存…

csdn上最详细的黑客技术入门教程,从零基础到精通 看这一篇就够了

引言 网络安全领域的快速发展为技术爱好者提供了广阔的学习与实践平台。本文旨在为初学者提供一个由浅入深的学习路线图,特别是在建立必要的基础知识上。 第一阶段:基础知识建设 黑客技术的有效学习需要在多个核心领域内建立坚实的基础。以下是初学者…

OpenAIGPT-4.5提前曝光?

OpenAI GPT-4.5的神秘面纱:科技界的震撼新篇章 在人工智能的世界里,每一次技术的飞跃都不仅仅是一次更新,而是对未来无限可能的探索。近日,科技巨头OpenAI似乎再次站在了这场革命的前沿,其潜在的新产品——GPT-4.5 Tur…

[Java基础面试题] volatie 与 synchronized

1. 说一下 volatie 在Java中,volatile 关键字用于修饰变量,表示该变量是易变的,其值可能会被不同的线程修改。使用volatile关键字声明的变量具有两个特性: 原子性:volatile 变量的读写操作都是原子性的,即…

MySQL事务--隔离级别

1 事务的隔离级别 事务的隔离级别是数据库管理系统(DBMS)提供的一种机制,用于控制并发事务之间的相互影响程度。隔离级别决定了一个事务对于其他事务所做的修改是否可见,以及在多个事务并发执行时可能出现的各种问题的程度。 常…

基于CANoe从零创建以太网诊断工程(3)—— Port Configuration 选项

🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe&…

【Linux —— 再谈软硬链接】

Linux —— 再谈软硬链接 再识软硬链接用ln -s指令创建软链接用ln指令创建硬链接 软硬链接的特征软硬链接的作用(使用场景)软链接快捷方式 硬链接1. 节省空间2. 备份和同步3. 数据一致性4. 避免意外删除 为什么硬链接不能链接目录示例:假设硬链接可以链接目录循环引…

C++11可变模板参数

我最近开了几个专栏,诚信互三! > |||《算法专栏》::刷题教程来自网站《代码随想录》。||| > |||《C专栏》::记录我学习C的经历,看完你一定会有收获。||| > |||《Linux专栏》&#xff1…