实践GoF的23种设计模式:SOLID原则

之前也有写过关于设计模式的文章《使用Go实现GoF的23种设计模式》,但是那个系列写了3篇文章就没再继续了,主要的原因是找不到合适的示例代码 。考虑到,如果以类似于“鸭子是否会飞”、“烘焙的制作流程”等贴近生活的事情举例,很难在我们日常的开发中产生联系 。(目前应该很少有这些逻辑的软件系统吧)
《实践GoF的23种设计模式》可以看成是《使用Go实现GoF的23种设计模式》系列的重启,吸取了上次烂尾的教训,本次在写文章之前就已经完成了23种设计模式的示例代码实现 。和上次不同,本次示例代码使用Java实现,以我们日常开发中经常碰到的一些技术/问题/场景作为切入点,示范如何运用设计模式来完成相关的实现 。
前言
从1995年GoF提出23种设计模式到现在,25年过去了,设计模式依旧是软件领域的热门话题 。设计模式通常被定义为:
设计模式( )是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性 。
从定义上看,设计模式其实是一种经验的总结,是针对特定问题的简洁而优雅的解决方案 。既然是经验总结,那么学习设计模式最直接的好处就在于可以站在巨人的肩膀上解决软件开发过程中的一些特定问题 。
学习设计模式的最高境界是吃透它们本质思想,可以做到即使已经忘掉某个设计模式的名称和结构,也能在解决特定问题时信手拈来 。设计模式背后的本质思想,就是我们熟知的SOLID原则 。如果把设计模式类比为武侠世界里的武功招式,那么SOLID原则就是内功内力 。通常来说,先把内功练好,再来学习招式,会达到事半功倍的效果 。因此,在介绍设计模式之前,很有必要先介绍一下SOLID原则 。
本文首先会介绍本系列文章中用到的示例代码demo的整体结构,然后开始逐一介绍SOLID原则,也即单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则 。
一个简单的分布式应用系统
本系列示例代码demo获取地址:–Java-
示例代码demo工程实现了一个简单的分布式应用系统(单机版),该系统主要由以下几个模块组成:
示例代码demo工程的主要目录结构如下:
├── db# 数据库模块,定义Db、Table、TableVisitor等抽象接口 【@单例模式】│├── cache# 数据库缓存代理,为Db新增缓存功能 【@代理模式】│├── console# 数据库控制台实现,支持dsl语句查询和结果显示 【@适配器模式】│├── dsl# 实现数据库dsl语句查询能力,当前只支持select语句查询 【@解释器模式】│├── exception# 数据库模块相关异常定义│├── iterator# 遍历表迭代器,包含按序遍历和随机遍历 【@迭代器模式】│└── transaction# 实现数据库的事务功能,包括执行、提交、回滚等 【@命令模式】【@备忘录模式】├── monitor# 监控系统模块,采用插件式的架构风格,当前实现access log日志etl功能│├── config# 监控系统插件配置模块【@抽象工厂模式】【@组合模式】││├── json# 实现基于json格式文件的配置加载功能││└── yaml# 实现基于yaml格式文件的配置加载功能│├── entity# 监控系统实体对象定义│├── exception# 监控系统相关异常│├── filter# Filter插件的实现定义【@责任链模式】│├── input# Input插件的实现定义【@策略模式】│├── output# Output插件的实现定义│├── pipeline# Pipeline插件的实现定义,一个pipeline表示一个ETL处理流程 【@桥接模式】│├── plugin# 插件抽象接口定义│└── schema# 监控系统相关的数据表定义 ├── mq# 消息队列模块├── network# 网络模块,模拟网络通信,定义了socket、packet等通用类型/接口【@观察者模式】│└── http# 模拟实现了http通信等服务端、客户端能力├── service# 服务模块,定义了服务的基本接口│├── mediator# 服务消息中介,作为服务通信的中转方,实现了服务发现,消息转发的能力 【@中介者模式】│├── registry# 服务注册中心,提供服务注册、去注册、更新、 发现、订阅、去订阅、通知等功能││├── entity# 服务注册/发现相关的实体定义 【@原型模式】【@建造者模式】││└── schema# 服务注册中心相关的数据表定义 【@访问者模式】【@享元模式】│└── shopping# 模拟在线商城服务群的定义,包含订单服务、库存服务、支付服务、发货服务 【@外观模式】└── sidecar# 边车模块,对socket进行拦截,提供http access log、流控功能 【@装饰者模式】【@工厂模式】└── flowctrl# 流控模块,基于消息速率进行随机流控 【@模板方法模式】【@状态模式】