Kotlin~Visitor访问者模式

news2024/9/29 9:34:37

概念

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

角色介绍

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

UML

访问者模式

代码实现

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

参考:

  • 访问者模式及其应用场景
  • 重新认识访问者模式:从实践到本质
  • 设计模式-访问者模式及应用
  • 设计模式:访问者(Visitor)模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/837590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML编码

目录 1.HTML编码概述2.实体编码3.URLcode编码4.unicode编码5.解码实例 1.HTML编码概述 通常一个网页中可解析的总共有三种编码&#xff0c;每种编码都能用来代替表示字符&#xff0c;按解析顺序依次是“html实体编码”“urlcode码”“Unicode码”&#xff0c;在执行过程中会在…

Flowable-顺序流

目录 顺序流标准顺序流定义图形标记XML内容使用示例 条件顺序流定义图形标记XML内容界面操作 默认顺序流定义图形标记XML内容使用示例视频教程 顺序流 顺序流是一端带有箭头的实线&#xff0c;可在流程图中连接流程内的各个元素&#xff0c;并显示各个元素的执行顺序。 Flowa…

Flink学习教程

最近因为用到了Flink&#xff0c;所以博主开了《Flink教程》专栏来记录Flink的学习笔记。 【Apache Flink v1.16 中文文档】 【官网 - Apache Flink v1.3 中文文档】 一、基础 参考链接如下&#xff1a; Flink教程&#xff08;01&#xff09;- Flink知识图谱Flink教程&…

[Docker实现测试部署CI/CD----自由风格的CI操作[最终架构](5)]

目录 11、自由风格的CI操作&#xff08;最终&#xff09;Jenkins容器化实现方案修改 docker.sock 权限修改 Jenkins 启动命令后重启 Jenkins构建镜像推送到Harbor修改 daemon.json 文件Jenkins 删除构建后操作Jenkins 添加 shell 命令重新构建 Jenkins通知目标服务器拉取镜像目…

Java阶段五Day18

Java阶段五Day18 文章目录 Java阶段五Day18缓存方案面试题整理 项目功能新增审核业务流程图 账户账户表格和ER图账号服务功能账号的创建当前实现功能时序图&#xff08;对应全景图&#xff09; 抢单相关时序图供应商和需求单 附录布隆过滤器 缓存方案 面试题整理 目标&#xf…

【Unity3D应用案例系列】Unity3D中实现文字转语音的工具开发

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 在开发中&#xff0c;会遇到将文字转语音输出的需求&#xff0…

[每周一更]-(第57期):用Docker、Docker-compose部署一个完整的前后端go+vue分离项目

文章目录 1.参考项目2.技能点3.GO的Dockerfile配置后端的结构如图Dockerfile先手动docker调试服务是否可以启动报错 4.Vue的Dockerfile配置前端的结构如图nginx_docker.confDockerfile构建 5.docker-compose 整合前后端docker-compose.yml错误记录&#xff08;1&#xff09;ip端…

宇树Unitree Z1机械臂使用教程

宇树Unitree Z1机械臂使用教程 作者&#xff1a;Herman Ye Galbot Auromix Auromix是一个机器人爱好者组织&#xff0c;欢迎参与我们Github上的开源项目 更新日期&#xff1a;2023/08/04 注意&#xff1a;此文档在该日期下测试有效。 以下内容参考宇树官方的Z1 Docs。 由宇树…

idea调节文字大小、日志颜色、git改动信息、单击打开代码覆盖原标签问题

idea调节菜单栏文字大小&#xff1a; 调节代码文字大小&#xff1a; 按住ctrl滚动滑轮可以调节代码文字大小&#xff1a; ctrl单击打开代码覆盖原标签问题&#xff1a; idea在控制台对不同级别的日志打印不同颜色 &#xff1a; “grep console”插件 点击某一行的时候&#x…

docker-compose --version报错

在部署docker-compose后&#xff0c;查看版本时有如下报错: 解决方法: 解决方法&#xff1a; 直接在release中下载对应的linux发行版【docker-compose-linux-x86_64】 https://github.com/docker/compose/releases/tag/v2.18.1 下载完后将软件上传至 Linux的【/usr/local/bin】…

高忆管理:教你一招短线选股法?

投资者在进行短线买卖时&#xff0c;需求把握一些可行的股票战略&#xff0c;以进步成功率。本文将从商场状况、技能剖析、基本面剖析和资金流向四个视点&#xff0c;教你一招短线选股法。 一、商场状况 在短线买卖中&#xff0c;行情是至关重要的。商场上有“牛市”和“熊市”…

【前端实习生备战秋招】—HTML面试题汇总,建议收藏

【前端实习生备战秋招】—HTML面试题汇总&#xff0c;建议收藏 文章目录 【前端实习生备战秋招】—HTML面试题汇总&#xff0c;建议收藏1. src和href的区别2. 对HTML语义化的理解3. DOCTYPE(⽂档类型) 的作⽤4. script标签中defer和async的区别5. 常⽤的meta标签有哪些6. HTML5…

14-3_Qt 5.9 C++开发指南_QUdpSocket实现 UDP 通信_UDP 单播和广播

文章目录 1.UDP通信概述2. UDP 单播和广播2.1 UDP 通信实例程序功能2.2 主窗口类定义和构造函数2.3 UDP通信的实现2.4 源码2.4.1 可视化UI设计2.4.2 mainwindow.h2.4.3 mainwindow.cpp 1.UDP通信概述 UDP(User Datagram Protocol&#xff0c;用户数据报协议)是轻量的、不可靠的…

hcip的mgre和ospf实验

题目 拓扑图 一、配置环回和IP地址 R1 < Huawei>sy Enter system view, return user view with CtrlZ. [Huawei]sysname r1 [r1]int g0/0/1 [r1-GigabitEthernet0/0/1]ip add 64.1.1.1 24 Aug 4 2023 18:56:07-08:00 r1 %%01IFNET/4/LINK_STATE(l)[0]:The line protocol…

python 常见数据类型和方法

不可变数据类型 不支持直接增删改 只能查 str 字符串 int 整型 bool 布尔值 None None型特殊常量 tuple 元组(,,,)回到顶部 可变数据类型&#xff0c;支持增删改查 list 列表[,,,] dic 字典{"":"","": ,} set 集合("",""…

mysql函数及用法

目录 一、前言 二、函数 2.1五大聚合函数 2.2 日期函数 3.字符串函数 三. 总结&#xff1a; 一、前言 mySQL 是一种常见的关系型数据库管理系统&#xff0c;提供了大量的函数可以帮助开发者有效地操作和管理数据库。mySQL根据这些函数将数据更好的进行操作&#xff0c;从…

局域网部署,用WorkPlus视频会议保密又安全

用户采用私有化部署视频会议软件的情况主要有以下几种因素&#xff1a; 1. 针对机密性高的会议&#xff1a;如果有涉及高度机密的商业谈判或敏感信息交流等重要会议&#xff0c;政府、军工、企业等用户会选择局域网内部署视频会议软件&#xff0c;以保证信息安全。 2. 频繁进…

【云原生】k8s中Contrainer 生命周期回调/策略/指针学习

个人主页&#xff1a;征服bug-CSDN博客 kubernetes专栏&#xff1a;kubernetes_征服bug的博客-CSDN博客 目录 1 容器生命周期 2 容器生命周期回调/事件/钩子 3 容器重启策略 4 自定义容器启动命令 5 容器探针 1 容器生命周期 Kubernetes 会跟踪 Pod 中每个容器的状态&am…

【大数据】LPG日志采集方案(官网入门案例)

文章目录 1. LPG简介2. 安装3. 测试日志方案的效果3.1. 测试1&#xff1a;Promtail监控/var/log目录的变化3.2. 测试2&#xff1a;Grafana可视化查看日志3.3. 测试3&#xff1a;可以预见部署Spring Boot程序的日志也可以被Grafana查看3.4. 踩坑记录 4. 官方入门案例介绍4.1. 获…

收藏!9款好用的前端可视化工具推荐

“可视化开发”是上个世纪90年代软件界最大的热点之一。 当初&#xff0c;可视化开发主要专注于用户界面的构建&#xff0c;让开发者通过简单的拖拽操作&#xff0c;快速搭建用户界面&#xff0c;一些成熟产品更是实现了“所见即所得”。在与当时最先进的高级编程语言相比较时&…