当前位置:首页 » 《随便一记》 » 正文

Kotlin~自定义DSL_Hynson的学习笔记

6 人参与  2021年11月26日 10:03  分类 : 《随便一记》  评论

点击全文阅读


本文记录如何自定义DSL,帮助你从无脑的硬编码走出来。希望对提高团队代码质量有所帮助。

1. 实现

首先定义bean类,再给bean类添加相应的lambda函数。然后添加单例,我们使用单例来作为所有bean的容器,
并实现你需求的方法。

// DslRule.kt

class Button(){

}
class Text(){

}

class Layout{
    fun button(action: Button.() -> Unit){

    }
    fun text(action: Text.() -> Unit){

    }
}

fun layout(action:Layout.() -> Unit){

}

data class TempTime(val temp: Int, val time:Int)

data class Param(val name:String,val resId:Int, val mod: String, val recipe:Int,val tt: TempTime,val shake:Boolean)

class Product(val configMod:String){
    lateinit var hashSets:HashSet<Param>

    init {
        Builder.instance.getMap()[configMod] = this
    }

    fun init(action:Product.() -> Unit): Product{
        action.invoke(this)
        return this
    }

    fun add(vararg params: Param){
        hashSets = params.toHashSet()
    }

    fun printMap(){
        hashSets.forEach {
            println(it)
        }
    }


    override fun toString(): String {
        return "Product(configMod='$configMod')"
    }

}

/**
 * 1.根据config取出所有预设参数
 * 2.根据Mode取出对应的name icon
 *
 *
 */
class Builder(){
    companion object{
        val instance: Builder by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
            Builder()
        }
        private val map = HashMap<String,Product>()
    }

    fun getMap() : HashMap<String,Product>{
        return map
    }

    fun getNameByMode(mod: String) : String{
        map.forEach {
            it.value.hashSets.forEach { p ->
                if (p.mod == mod) return p.name
            }
        }
        return ""
    }

    fun printMap(){
        map.forEach {
            println(it.value)
        }
    }
}

fun build(lambda:Builder.() -> Unit) : Builder{
    val builder = Builder()
    lambda.invoke(builder)
    return builder
}

2. 测试

接下来便是测试使用

// DslTest.kt

fun main(){
    /**
     * 1.{}属于lambda体
     * 2.{}里面有button text 需要让它持有this
     */
    // infax 表达式必须是成对的
    // 模拟compose,,声明式UI
    layout {
        button {

        }
        text {

        }
    }

    val builder = build {
        Product("DS03").init {
            val tempTime = TempTime(12,34)
            add(
                Param("土豆",12,mod = "M1",24,tempTime,true),
                Param("烧烤",12,mod = "M2",24,tempTime,true)
            )
        }.printMap()

        Product("DS04")
            .add(
                Param("辣椒",12,mod = "M3",24,TempTime(12,34),true),
                Param("炒肉",12,mod = "M4",24,TempTime(12,34),true)
            )
        Product("DS06")
            .add(
                Param("螺蛳粉",12,mod = "M5",24,TempTime(12,34),true),
                Param("番茄",12,mod = "M6",24,TempTime(12,34),true)
        )
    }
    builder.printMap()
    println(Builder.instance.getNameByMode("M6"))
}

3. 优点整理

最后重点说一下,自定义Dsl的优点,这些优点主要体现在移动端开发。web后台也有相似优点,因为kt是一种全平台语言。

  1. 数据添加方便
  2. resId 和 数据混合使用方便,通常业务最好将resID和业务字段分开管理
  3. 数据管理统一使用方便,会存在如下情况:

根据Mode转换对应的Name Icon对象、根据config取出所有预设参数或对应模式的预设参数;
可以减少部分字段需要转换后再使用的工作量,如UI展示使用的bean和业务数据使用的bean未封装在一起时会需要转换,
有时仅用到了bean的部分字段会有同学将bean转换成另外一种bean

如果文章还不错,欢迎点赞收藏~打赏~


点击全文阅读


本文链接:http://zhangshiyu.com/post/31281.html

预设  字段  优点  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 完结文重生高考填报志愿时,我放任全班上大专好文分享列表_完结文重生高考填报志愿时,我放任全班上大专好文分享(颜禾晚宋津年叶淼淼)
  • 陆寒澈沈秋晚小说完本+外篇(相逢难逃别离)畅享阅读
  • 雪上春霜删减内容修复版本(温观意陆一然)_雪上春霜删减内容修复版本(温观意陆一然)
  • 骤雨淋落晚星(林晚星裴临川)全书浏览_骤雨淋落晚星全书浏览
  • 全书浏览重生高考填报志愿时我放任全班上大专+后续(叶淼淼宋津年颜禾晚)_重生高考填报志愿时我放任全班上大专+后续(叶淼淼宋津年颜禾晚)全书结局
  • 他的甜撩藏不住附加黎初谢时晏:结局+番外免费品鉴(他的甜撩藏不住)全本浏览阅读连载中
  • 全文他死遁后逼疯清冷女权臣+完结+后续(苏煜顾宛柔)列表_全文他死遁后逼疯清冷女权臣+完结+后续
  • 暑假毕业旅游,班花将我们身份证交给黑导游(江诗晗)全书浏览_暑假毕业旅游,班花将我们身份证交给黑导游全书浏览
  • 重生到高考前,我放任竹马为爱私奔新上热文_裴文远柳雨文远完结版_小说后续在线阅读_无删减免费完结_
  • 雨织离歌浮生浅节选_沈翊鸣苏之雨小姐完整文本_小说后续在线阅读_无删减免费完结_
  • 鬓边不是牡丹红精选(盛惟芳萧既明贺锦)_鬓边不是牡丹红精选盛惟芳萧既明贺锦
  • 宋岑月傅忠焜:结局+番外免费品鉴:结局+番外评价五颗星

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1