设计模式 - 外观(门面)模式就要这样学!

发布于:2024-06-30 ⋅ 阅读:(137) ⋅ 点赞:(0)

目录

开始

为什么要引入外观(门面)模式

外观(门面)模式概述

外观(门面)模式代码实现


开始


为什么要引入外观(门面)模式

问题:例如用户表,我们进行了水平分表操作,分成了用户基本信息表、用户统计表、用户头像表. 

在 SpringMVC 模式下,我们如果要实现对用户信息的 CRUD 可能就要设计到多张表,比如 查询用户所有信息,就涉及到了三张表的查询(一般是不允许 sql 联查的,笛卡尔积性能极低,因此需要三次查询数据库,最后组装VO),那么我们可能就会在 UserServiceImpl 中操作这些表的 Repo,组装 VO.

倘若查询了之后还有其他的业务逻辑需要处理,那么就会使得 UserServiceImpl 变得十分庞大,耦合度高(数据查询聚合 和 业务逻辑耦合).

为了解决整个问题,就引入外观模式.

外观(门面)模式概述

外观模式(Facade):也叫门面模式,为子系统中的一组接口提供了一个一致的界面,此模式定义了高层接口,这个接口使得这堆子系统更加容易使用.

通俗来讲,就是 外观类 对 大量的子系统又进行了一层封装,对外提供一个聚合了多个子系统功能的接口.

例如上述我们讲的 用户表 分表的情况,就可以在外观类中提供一个 查询接口,这个查询接口的工作就是 调用三张表的 Repo,查询到数据,然后聚合成 VO,并返回.  这样将来外部只需要调用这个 外观类 的查询接口,就实现了复杂查询和组装操作,无需知道内部实现细节~

外观(门面)模式代码实现

a)对数据库的操作

class UserinfoRepoImpl: UserinfoRepo {
    override fun save() = println("save userinfo ...")
    override fun query() = println("query userinfo ...")
}
class UserStatRepoImpl: UserStatRepo {
    override fun save() = println("save user_stat ...")
    override fun query() = println("query user_stat ...")
}
class UserAvatarRepoImpl: UserAvatarRepo {
    override fun save() = println("save user_avatar ...")
    override fun query() = println("query user_avatar ...")
}

interface UserinfoRepo {
    fun save()
    fun query()
}
interface UserStatRepo {
    fun save()
    fun query()
}
interface UserAvatarRepo {
    fun save()
    fun query()
}

b)外观类

class UserFacadeImpl(
    private val infoRepo: UserinfoRepo,
    private val statRepo: UserStatRepo,
    private val avatarRepo: UserAvatarRepo,
): UserFacade {

    override fun save() {
        infoRepo.save()
        statRepo.save()
        avatarRepo.save()
    }
    override fun query() {
        infoRepo.query()
        statRepo.query()
        avatarRepo.query()
        println("组装 VO ...")
    }
}
interface UserFacade {
    fun save()
    fun query()
}

c)客户端操作

fun main() {
    val userFacade: UserFacade = UserFacadeImpl(
        infoRepo = UserinfoRepoImpl(),
        statRepo = UserStatRepoImpl(),
        avatarRepo = UserAvatarRepoImpl(),
    )

    userFacade.save()
    println("------------------------------")
    userFacade.query()
}

运行结果如下:


网站公告

今日签到

点亮在社区的每一天
去签到