天天看点

Go设计模式(15)-门面模式

门面模式也叫外观模式,英文为 Facade Design Pattern。门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。 门面模式的思想更常用在架构设计上,在编写代码层面大家很少提门面模式,但却一直在默默的使用。

UML类图位置:https://www.processon.com/diagraming/609b375407912943913a4c13

本文代码链接为:https://github.com/shidawuhen/asap/blob/master/controller/design/15facade.go

1定义

1.1门面模式

门面模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

UML:

Go设计模式(15)-门面模式

1.2分析

门面模式没有太多好分析的,思想比较简单。我方系统中包含多个子系统,完成一项任务需要多个子系统通力合作。

我们可以选择将子系统所有接口暴露给Client,让Client自行调用。但这会导致一些问题,一是后期沟通成本会很高,加入完成一个功能需要调用多个接口,Client联调时出问题率会飙升,系统提供者需要不断答疑。二是如果有多个Client,相同代码Client需要重复开发,而且后期代码有变更,各方都会很烦费力。三是影响响应时间和性能,多个接口往返,白白增加了很多通信时间和请求量。

另一种方式是,对于指定功能,系统端做好封装,只提供一个接口。好处有很多,沟通成本低、Client不需要重复开发、功能更改影响范围小、提高响应时间和性能。一般这些接口会有对应的OpenAPI,实现了功能对外开放的效果。

2.使用场景

对于使用场景,简单的举一个例子。

电商系统一般包含商品、库存、营销、商家、交易、支付、售后、履约、物流、仓储等子系统。拿商品详情页来说,商详页接口一般会涉及商品、库存、营销、商家等系统。电商系统的客户端有PC、Mobile、Android、IOS等,如果让这些客户端调用接口拼凑出商详页的数据,感觉客户端的同学能拿着大砍刀和服务端同学谈心。为了避免这种情况,一般商品组同学会提供商详页接口,该接口获取商详页的所有信息,返回给客户端。

当然,如果流量特别大,需要优化接口性能,可以根据具体情况将接口做拆分,客户端需要请求多个接口,但即使这样,相关的接口也是封装好的。如果真实场景中遇到这种拆分的情况,那恭喜你,说明公司在发展,流量在增加,能够推动大家更快的成长。

3.代码实现

门面模式应该是大家用的最自然的一种设计模式了。简单写一下电商系统的门面模式代码,以便和其它文章保持一致。

package main

import "fmt"

type ProductSystem struct {
}

func (p *ProductSystem) GetProductInfo() {
   fmt.Println("获取到商品信息")
}

type StockSystem struct {
}

func (s *StockSystem) GetStockInfo() {
   fmt.Println("获取到库存信息")
}

type PromotionSystem struct {
}

func (p *PromotionSystem) GetPromotionInfo() {
   fmt.Println("获取营销信息")
}

func ProductDetail() {
   product := &ProductSystem{}
   stock := &StockSystem{}
   promotion := &PromotionSystem{}
   product.GetProductInfo()
   stock.GetStockInfo()
   promotion.GetPromotionInfo()
   fmt.Println("整理完成商品详情页所有数据")
}
func main() {
   ProductDetail()
}
           

输出:

➜ myproject go run main.go

获取到商品信息

获取到库存信息

获取营销信息

整理完成商品详情页所有数据

3.总结

门面模式是程序员最常用的一种设计模式了,在架构设计中往往自然而然的就会用到。很好的满足了接口隔离原则和迪米特法则。

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

Go设计模式(15)-门面模式

往期文章回顾:

招聘

  1. 字节跳动|内推大放送
  2. 字节跳动|今日头条广州服务端研发工程师内推
  3. 字节跳动|抖音电商急招上海前端开发工程
  4. 字节跳动|抖音电商上海资深服务端开发工程师-交易
  5. 字节跳动|抖音电商武汉服务端(高级)开发工程师
  6. 字节跳动|飞书大客户产品经理内推咯
  7. 字节跳动|抖音电商服务端技术岗位虚位以待
  8. 字节跳动招聘专题

设计模式

  1. Go设计模式(13)-装饰器模式
  2. Go设计模式(12)-桥接模式
  3. Go设计模式(11)-代理模式
  4. Go设计模式(10)-原型模式
  5. Go设计模式(9)-建造者模式
  6. Go设计模式(8)-抽象工厂
  7. Go设计模式(7)-工厂模式
  8. Go设计模式(6)-单例模式
  9. Go设计模式(5)-类图符号表示法
  10. Go设计模式(4)-代码编写优化
  11. Go设计模式(4)-代码编写
  12. Go设计模式(3)-设计原则
  13. Go设计模式(2)-面向对象分析与设计
  14. Go设计模式(1)-语法

语言

  1. 再也不怕获取不到Gin请求数据了
  2. 一文搞懂pprof
  3. Go工具之generate
  4. Go单例实现方案
  5. Go通道实现原理
  6. Go定时器实现原理
  7. Beego框架使用
  8. Golang源码BUG追查
  9. Gin框架简洁版
  10. Gin源码剖析

架构

  1. 分页复选设计的坑
  2. 支付接入常规问题
  3. 限流实现2
  4. 秒杀系统
  5. 分布式系统与一致性协议
  6. 微服务之服务框架和注册中心
  7. 浅谈微服务
  8. 限流实现1
  9. CDN请求过程详解
  10. 常用缓存技巧
  11. 如何高效对接第三方支付
  12. 算法总结

存储

  1. MySQL开发规范
  2. Redis实现分布式锁
  3. 事务原子性、一致性、持久性的实现原理
  4. InnoDB锁与事务简析

网络

  1. HTTP2.0基础教程
  2. HTTPS配置实战
  3. HTTPS连接过程
  4. TCP性能优化

工具

  1. GoLand实用技巧
  2. 根据mysql表自动生成go struct
  3. Markdown编辑器推荐-typora

读书笔记

  1. 《毛选》推荐
  2. 原则
  3. 资治通鉴
  4. 敏捷革命
  5. 如何锻炼自己的记忆力
  6. 简单的逻辑学-读后感
  7. 热风-读后感
  8. 论语-读后感
  9. 孙子兵法-读后感

思考

  1. 为动员一切力量争取胜利而斗争
  2. 反对自由主义
  3. 实践论
  4. 评价自己的标准
  5. 服务端团队假期值班方案
  6. 项目流程管理
  7. 对项目管理的一些看法
  8. 对产品经理的一些思考
  9. 关于程序员职业发展的思考
  10. 关于代码review的思考

继续阅读