本文記錄如何自定義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是一種全平臺語言,
- 資料添加方便
- resId 和 資料混合使用方便,通常業務最好將resID和業務欄位分開管理
- 資料管理統一使用方便,會存在如下情況:
根據Mode轉換對應的Name Icon物件、根據config取出所有預設引數或對應模式的預設引數;
可以減少部分欄位需要轉換后再使用的作業量,如UI展示使用的bean和業務資料使用的bean未封裝在一起時會需要轉換,
有時僅用到了bean的部分欄位會有同學將bean轉換成另外一種bean
如果文章還不錯,歡迎點贊收藏~打賞~
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/301070.html
標籤:其他
