目录
一、适配器模式
一句话概括结构式模式
教你将类和对象结合再一起形成一个更强大的结构.
1.1、适配器模式概述
将一个类的接口转换成客户希望的另一个接口,使得原本不兼容的接口能一起工作.
比如,你有一个台灯的充电线式两孔的插头,而现在只有一个插座是三孔的,此时你可能就需要一个给这个三孔插座接一个插板,这个插板上就有 两孔的、三孔的.... 这样你的台灯就能用了对吧.
并且如果这个插板对应到我们程序中,如果是一个类的话,将来想要支持更多插孔,就直接引入即可. 不需要做太大的调整,满足开闭原则.
适配器模式包含以下主机角色:
- 目标接口:当前客户所期待的接口,它可以是抽象类或者接口(上述的 两孔插座).
- 适配者类:是被访问的现存组件库中的接口(上述的 两孔插头).
- 适配器类:是一个转换器,通过继承或引用目标接口,实现适配者类的所有方法,就可以实现转换效果.
1.3、案例(项目实战)
例如有一个博客系统,其中文章表被分表了,分成了 文章信息表、文章统计信息表 这两张表,此时就可以使用一个适配器,来对文章的信息的 CRUD 进行统一处理.
a)适配者类:文章信息数据库操作如下
data class ArticleInfo(
val id: Long,
val title: String,
val content: String,
)
//这里的实现就是对数据库的操作
interface ArticleInfoRepo {
fun queryById(id: Long): ArticleInfo
fun pageInfo(offset: Int, limit: Int): PageResp<ArticleInfo>
}
b)适配者类:文章统计信息数据库操作如下:
data class ArticleStat (
val id: Long,
val pv: Long,
val likeCnt: Long ,
val collectCnt: Long,
val commentCnt: Long,
)
//这里的实现就是对数据库的操作
interface ArticleStatRepo {
fun queryById(id: Long): ArticleStat
fun pageStat(offset: Int, limit: Int): PageResp<ArticleStat>
}
c)目标接口
interface ArticleDataHandler {
fun queryArticleById(id: Long): ArticleVo
fun pageArticleById(offset: Int, limit: Int): PageResp<ArticleVo>
//......
}
data class ArticleVo (
val id: Long,
val title: String,
val content: String,
val pv: Long,
val likeCnt: Long ,
val collectCnt: Long,
val commentCnt: Long,
)
d)适配器类
//@Component 表示这是个组件
class ArticleDataAdapter ( //构造方法注入
val infoRepo: ArticleInfoRepo,
val statRepo: ArticleStatRepo
): ArticleDataHandler {
override fun queryArticleById(id: Long): ArticleVo {
val info = infoRepo.queryById(id)
val stat = statRepo.queryById(id)
return map(info, stat)
}
override fun pageArticleById(offset: Int, limit: Int): PageResp<ArticleVo> {
val pageInfo = infoRepo.pageInfo(offset, limit)
val pageStat = statRepo.pageStat(offset, limit)
return map(pageStat, pageStat)
}
private fun map(info: PageResp<ArticleStat>, stat: PageResp<ArticleStat>): PageResp<ArticleVo> {
TODO("Not yet implemented")
}
private fun map(info: ArticleInfo, stat: ArticleStat): ArticleVo {
TODO("Not yet implemented")
}
}
分析:
将来如果想要继续对文章分表,那么直接引入相应的 Repo 即可,在适配器类中进行扩展即可.
1.4、优缺点(对象适配器模式)
优点
1. 适配现有类,且不修改类:在不改变现有类的基础上,实现现有类和目标类的接口的匹配.
2. 符合 合成/聚合 复用原则:持有引用,而不继承.
3. 符合开闭原则:如果引入新的目标接口,只需要在适配器类中进行扩展,不需要修改原代码.
缺点:
增加复杂性:编写适配器类时,要考虑全面,包括适配者和目标类.
1.5、应用场景
1. 以前开发的系统中存在满足当前业务所需要的类,但是接口和当前业务所需接口不一致.
2. 第三方提供的组件,但是组件接口定义和自己要求的接口定义不同.