装饰模式实现分享功能

发布时间:2021-07-19  修改时间:2021-07-19  作者:归零幻想

在看业务代码时发现了一段代码,应用了装饰模式处理了分享功能的实现,非常巧妙,共赏。

装饰模式.svg.png.lin.png

代码

业务代码不可能直接贴出来,我按照大致的设计写了如下demo。

import java.lang.IllegalArgumentException

fun main() {
    listOf(
        ShareData(listOf("图1", "图2", "图3"), true),
        ShareData(listOf("图1", "图2", "图3"), false),
        ShareData(listOf("视频1", "视频2", "视频3"), true),
        ShareData(listOf("视频1", "视频2", "视频3"), false),
        ShareData(listOf("图1", "视频2", "图3"), true),
        ShareData(listOf("图1", "视频2", "图3"), false)
    ).forEach {
        println("测试$it")
        if (it.handler.requestPermission()) {
            it.handler.doShare(it)
        } else {
            println("申请权限失败")
        }
        println()
    }
}

class ShareData(val urls: List<String>, val isFromSDK: Boolean) {
    companion object {
        const val IMAGE = 0x1
        const val VIDEO = 0x2
        const val MIX = IMAGE.or(VIDEO)
    }

    val handler by lazy {
        var res: ShareHandler = ShareHandlerImpl()
        res = if (isFromSDK) ShareFromSdkHandler(res) else ShareFromSystemHandler(res)
        var result = 0
        urls.forEach { result = result.or(getUrlType(it)) }
        res = when (result) {
            IMAGE -> ShareImageHandler(res)
            VIDEO -> ShareVideoHandler(res)
            MIX -> ShareMixHandler(res)
            else -> throw IllegalArgumentException("不能处理的参数类型")
        }
        res
    }

    private fun getUrlType(url: String): Int = if (url.contains("图")) IMAGE else VIDEO

    override fun toString(): String {
        return "ShareData(urls=$urls, isFromSDK=$isFromSDK)"
    }
}

interface ShareHandler {
    fun validate(shareData: ShareData): Boolean
    fun requestPermission(): Boolean
    fun doShare(shareData: ShareData)
}

class ShareHandlerImpl : ShareHandler {
    override fun validate(shareData: ShareData): Boolean {
        return shareData.urls.isNotEmpty()
    }

    override fun requestPermission() = throw NotImplementedError("未实现")
    override fun doShare(shareData: ShareData) = throw NotImplementedError("未实现")
}

class ShareFromSdkHandler(shareHandler: ShareHandler) : ShareHandler by shareHandler {
    override fun requestPermission(): Boolean {
        println("申请SDK分享权限")
        return true
    }
}

class ShareFromSystemHandler(shareHandler: ShareHandler) : ShareHandler by shareHandler {
    override fun requestPermission(): Boolean {
        println("申请系统分享权限")
        return true
    }
}

class ShareImageHandler(shareHandler: ShareHandler) : ShareHandler by shareHandler {
    override fun doShare(shareData: ShareData) {
        println("分享图片内容$shareData")
    }
}

class ShareVideoHandler(shareHandler: ShareHandler) : ShareHandler by shareHandler {
    override fun doShare(shareData: ShareData) {
        println("分享视频${shareData}")
    }
}

class ShareMixHandler(shareHandler: ShareHandler) : ShareHandler by shareHandler {
    override fun doShare(shareData: ShareData) {
        println("分享混合内容$shareData")
    }
}

还用上了位运算和Kotlin的类委托,太卷了。

尝试画一下类图,这都是啥跟啥?

ShareHandler.svg.png.lin.png

我对照着菜鸟教程确认了半天,确定这确实是个装饰模式。插入两个省略掉的抽象类就清楚很多了。

装饰模式.svg.png.lin.png

怎么说呢,代码简洁实现优雅,我要学习的还有很多!