Kotlin~Visitor访问者模式

概念

将数据结构和操作分离,使操作集合可以独立于数据结构变化。

角色介绍

  • Visitor:抽象访问者,为对象结构每个具体元素类声明一个访问操作。
  • Element:抽象元素,定义一个accept方法
  • ConcreteElement:具体元素,实现抽象元素的accept方法,在accept方法中调用访问者的访问方法以完成对一个元素的操作。
  • ConcreteVisitor:具体访问者,实现抽象访问者声明操作。
  • ObjectStructure:对象结构,是一个集合用于存放元素对象并提供遍历内部元素的方法,通常由List、Set、Map等集合类实现。

UML

代码实现

kt 复制代码
interface Visitor {
    fun visit(wine: Wine): Float
    fun visit(pig: Pig): Float
    fun visit(television: Television): Float
}
interface Goods {
    fun accept(visitor: Visitor): Float
    fun account(): Float
}

/**
 * 酒类
 */
data class Wine(
    val count: Int,
    val price: Float
) : Goods {
    override fun accept(visitor: Visitor): Float {
        return visitor.visit(this)
    }

    override fun account(): Float {
        println("酒按瓶计价,购买数量为:${count}瓶,单价为$price")
        return count * price
    }
}

/**
 * 猪肉
 */
data class Pig(
    val count: Int,
    val price: Float
) : Goods {
    override fun accept(visitor: Visitor): Float {
        return visitor.visit(this)
    }

    override fun account(): Float {
        println("猪肉按斤计价,购买数量为:${count}斤,单价为$price")
        return count * price
    }
}

/**
 * 电视
 */
data class Television(
    val count: Int,
    val price: Float
) : Goods {
    override fun accept(visitor: Visitor): Float {
        return visitor.visit(this)
    }

    override fun account(): Float {
        println("电视按件台价,购买数量为:${count}台,单价为$price")
        return count * price
    }
}
class VisitorImpl : Visitor {
    override fun visit(wine: Wine): Float {
        return wine.account()
    }

    override fun visit(pig: Pig): Float {
        return pig.account()
    }

    override fun visit(television: Television): Float {
        return television.account()
    }
}
class ShoppingList {
    val list = ArrayList<Any>()
    fun add(any: Any) {
        list.add(any)
    }

    fun remove(any: Any) {
        list.remove(any)
    }
}
class AccountMachine {
    private var awt: Float = 0f

    fun getAwt(list: MutableList<Any>): Float {
        val visitor: Visitor = VisitorImpl()
        for (item in list) {
            awt += (item as Goods).accept(visitor)
        }
        return awt
    }
}

fun main() {
    val wine = Wine(10, 5f)
    val pig = Pig(2, 18f)
    val tv = Television(1, 2300f)
    val shoppingList = ShoppingList()
    shoppingList.add(wine)
    shoppingList.add(pig)
    shoppingList.add(tv)
    val accountMachine = AccountMachine()
    val awt = accountMachine.getAwt(shoppingList.list)
    println("总价:$awt")
}

优缺点

优点

  • 分离操作和数据结构
  • 增加新操作更容易
  • 集中化操作
    缺点
  • 增加新数据结构困难
  • 破坏封装

应用场景

适用于数据结构稳定,操作易变,对象的操作之间无关联的场景。

  • 编译器
  • 文档转化,比如markdown转html

总结

安卓开发中RecyclerView,Adapter是访问者对象,而RecyclerView.ViewHolder是一个被访问者对象。在RecyclerView.Adapter中,

我们需要实现 onCreateViewHolder()、onBindViewHolder()和getItemCount()等方法。这些方法被用于创建 ViewHolder对象、

绑定数据和获取列表项的数量等操作。在RecyclerView.ViewHolder中,我们需要定义列表项的视图控件,并在构造函数中将其初始化。

当Adapter对象需要绑定数据时,ViewHolder对象会被创建并传递给Adapter对象的onBindViewHolder()方法中,从而实现对列表项的访问和操作。

还有就是我们在写一些自定义Lint、Idea或者grade插件时也会见到访问者模式。

参考:

相关推荐
yzpyzp8 小时前
如果后台的Long类型的数据返回是null,那么Android客户端的数据bean的kotlin的Long类型的字段接受到数据后是null空指针吗?
android·kotlin
xvch12 小时前
Kotlin 2.1.0 入门教程(二十五)类型擦除
android·kotlin
有点感觉2 天前
Android级联选择器,下拉菜单
kotlin
zhangphil2 天前
Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(1)
android·kotlin
xvch2 天前
Kotlin 2.1.0 入门教程(二十三)泛型、泛型约束、协变、逆变、不变
android·kotlin
DachuiLi4 天前
访问者模式 Visitor Pattern
访问者模式
xvch4 天前
Kotlin 2.1.0 入门教程(二十四)泛型、泛型约束、绝对非空类型、下划线运算符
android·kotlin
zhangphil4 天前
Android Coil ImageLoader MemoryCache设置Key与复用内存缓存,Kotlin
android·kotlin
mmsx4 天前
kotlin Java 使用ArrayList.add() ,set()前面所有值被 覆盖 的问题
android·开发语言·kotlin
lavins4 天前
android studio kotlin项目build时候提示错误 Unknown Kotlin JVM target: 21
jvm·kotlin·android studio