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插件时也会见到访问者模式。

参考:

相关推荐
molong9315 小时前
Kotlin 内联函数、高阶函数、扩展函数
android·开发语言·kotlin
低调小一9 小时前
Kuikly 小白拆解系列 · 第1篇|两棵树直调(Kotlin 构建与原生承载)
android·开发语言·kotlin
Android-Flutter13 小时前
kotlin - 正则表达式,识别年月日
java·kotlin
ROO_KIE1 天前
[Java、C语言、Python、PHP、C#、C++]——深度剖析主流编程语言的核心特性与应用场景
kotlin
alexhilton1 天前
Kotlin互斥锁(Mutex):协程的线程安全守护神
android·kotlin·android jetpack
太过平凡的小蚂蚁1 天前
Kotlin 异步数据流三剑客:Flow、Channel、StateFlow 深度解析
android·kotlin
铉铉这波能秀2 天前
如何在Android Studio中使用Gemini进行AI Coding
android·java·人工智能·ai·kotlin·app·android studio
爱学啊3 天前
3.Android Compose 基础系列:在 Kotlin 中创建和使用函数
kotlin·compose·android compose开发基础
低调小一3 天前
LRU缓存科普与实现(Kotlin 与 Swift)
开发语言·缓存·kotlin