摒弃反模式:使用Kotlin委托优化Android BaseActivity

摒弃反模式:使用Kotlin委托优化Android BaseActivity

在Android开发中,许多开发者习惯于创建名为“BaseActivity”或“BaseFragment”的基类,以便在所有Activity或Fragment中共享一些通用行为。这种方法乍一看似乎是个好主意,但实际上它是一种反模式。本文将深入探讨这个问题,并介绍如何通过Kotlin委托来解决这个问题。

什么是反模式?

“BaseActivity”或“BaseFragment”这类命名模式从一开始就是一种反模式。这类基类通常包含了多种职责,使得代码难以维护和扩展。其主要问题在于:

  1. 职责不明确:命名应明确反映类的职责,而“BaseActivity”这种命名模糊不清,无法表明类的实际功能。
  2. 职责混杂:一个基类往往包含多种职责,使得子类难以理解和修改。
  3. 继承层次复杂:当项目规模增大时,复杂的继承层次会导致代码难以维护。

反模式示例

假设我们需要在用户离开和返回界面时记录日志,并在某些Activity中处理新的Intent。常见的做法是创建一个父Activity,例如:

open class AnalyticsActivity : AppCompatActivity() {
    override fun onPause() {
        super.onPause()
        // Log user leaving
    }

    override fun onResume() {
        super.onResume()
        // Log user returning
    }
}

open class IntentHandlerActivity : AppCompatActivity() {
    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // Handle new intent
    }
}

当需要同时实现这两个功能时,很多开发者会创建一个“BaseActivity”来包含所有职责:

open class BaseActivity : AppCompatActivity() {
    override fun onPause() {
        super.onPause()
        // Log user leaving
    }

    override fun onResume() {
        super.onResume()
        // Log user returning
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // Handle new intent
    }
}

这种做法将不同的职责混杂在一起,导致代码难以维护。

Kotlin委托的解决方案

Kotlin提供了原生的委托支持,使我们可以通过委托模式来解决上述问题。委托模式允许我们将一个对象的功能委托给另一个对象,从而实现代码复用和灵活的对象组合。

委托日志功能

首先,我们需要定义一个接口和其实现,用于记录生命周期事件:

interface AnalyticsLogger {
    fun registerLifecycleOwner(owner: LifecycleOwner)
}

class AnalyticsLoggerImpl : AnalyticsLogger, LifecycleEventObserver {
    override fun registerLifecycleOwner(owner: LifecycleOwner) {
        owner.lifecycle.addObserver(this)
    }

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        when (event) {
            Lifecycle.Event.ON_START -> println("User opened the screen.")
            Lifecycle.Event.ON_PAUSE -> println("User left the screen.")
            else -> Unit
        }
    }
}

然后,我们可以在Activity中使用委托:

class MainActivity : ComponentActivity(), AnalyticsLogger by AnalyticsLoggerImpl() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        registerLifecycleOwner(this)
    }
}

在这里,我们没有继承任何父类,而是通过委托将日志功能委托给AnalyticsLoggerImpl。这样,任何实现LifecycleOwner的类都可以轻松地添加日志功能,而无需创建复杂的基类。

委托Intent处理功能

同样的,我们可以为处理Intent定义一个接口和实现:

interface DeepLinkHandler {
    fun handleDeepLink(activity: Activity, intent: Intent?)
}

class DeepLinkHandlerImpl : DeepLinkHandler {
    override fun handleDeepLink(activity: Activity, intent: Intent?) {
        // Handle the intent
    }
}

在Activity中使用委托:

class MainActivity : ComponentActivity(),
    AnalyticsLogger by AnalyticsLoggerImpl(),
    DeepLinkHandler by DeepLinkHandlerImpl() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        registerLifecycleOwner(this)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        handleDeepLink(this, intent)
    }
}

通过这种方式,我们可以轻松地在Activity中添加多个不同的功能,而无需创建一个包含所有职责的“BaseActivity”。

结论

使用Kotlin的委托模式,我们可以避免反模式“BaseActivity”的问题,实现职责单一、易于维护和扩展的代码结构。通过定义接口和其实现,并在需要的地方进行委托,我们可以灵活地组合对象功能,提升代码的可读性和可维护性。

希望本文能帮助你更好地理解和使用Kotlin委托,从而编写出更优雅和高效的Android代码。如果你有任何问题或建议,欢迎在评论区交流讨论。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SecureCRT使用SSH登录服务器报错:Key exchange failed

SecureCRT使用SSH登录Ubuntu服务器报错:Key exchange failed 原因: ssh客户端与服务器的公钥协商失败,SecureCRT客户端所指定的秘钥交换算法(KexAlgorithms ),不在服务端支持范围内。可能是服务端的sshd版…

预警与校准并行:可燃气体报警器在矿区井下甲烷泄露防控中的应用

在矿区井下作业中,甲烷泄露是一个严重威胁工人生命安全和矿区生产安全的隐患。因此,及时、准确地预警甲烷泄露并采取相应的处理措施显得尤为重要。 可燃气体报警器作为一种有效的监测工具,在预防甲烷泄露事故中发挥着不可替代的作用。 在这…

Linux通过expect实现免交互

免交互 Here Document 用于将多行字符串直接传递给命令的方式&#xff0c;不需要人为交互命令界面&#xff0c;实现免交互 当使用Here Document操作文件时&#xff0c;需要借助一个文件结束符 EOF&#xff1a;文件结束符 示例 在脚本文件中写入以下内容 <<&#x…

5. PyTorch+NCCL源码编译

系列文章 第1章 多机多卡运行nccl-tests 和channel获取第2章 多机多卡nccl-tests 对比分析第3章 使用tcpdump抓取rdma数据包第5章 PyTorchNCCL源码编译 目录 系列文章前言一、本地环境二、安装cudnn三、使用pytorch自带NCCL库进行编译安装1. 源码编译2. 查看版本和all_reduce测…

Nature推荐的三种ChatGPT论文写作指令(含PDF下载)

1. 润色学术论文 ChatGPT学术润色指令&#xff1a; “I’m writing a paper on [topic]for a leading [discipline] academic journal. WhatItried to say in the following section is [specific point]. Please rephrase itfor clarity, coherence and conciseness, ensuri…

电脑系统重装怎么操作?分享四个win10重装系统方法

“我遇到了一些笔记本电脑的问题&#xff0c;别人告诉我解决这个问题需要重新安装Win10电脑系统。但我不记得我把光盘放在哪里了&#xff0c;我能否在不丢失文件的情况下重新安装操作系统&#xff1f;电脑系统重装怎么操作&#xff1f;”虽然电脑自带系统中有多种方法可供选择&…

嵌入式工程师从0开始,到底该学什么,怎么学

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“666”之后私信回复“666”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;嵌入式是个大筐&#xff0…

C++之STL(十二)

1、容器适配器 #include <iostream> #include <stack> #include <list> #include <queue> #include <functional> #include <iterator>using namespace std;int main() {// 栈&#xff08;先进后出filo&#xff09;stack<int, list<…

boss直聘招聘数据爬取及可视化分析2.0

boss直聘招聘数据爬取及可视化分析2.0 一、需求介绍二、完整代码2.1 爬虫代码2.2 数据可视化模块一、需求介绍 笔者在前两篇介绍boss直聘招聘数据爬取和可视化分析的博客的基础上,对代码和功能进行了完善。在数据爬取的模块,代码更加简洁易懂,且性能更加稳定;在数据可视化…

【AI大模型】Transformers大模型库(十四):Datasets Viewer

目录 一、引言 二、Datasets Viewer数据查看器 2.1 概述 2.2 示例 三、总结 一、引言 这里的Transformers指的是huggingface开发的大模型库&#xff0c;为huggingface上数以万计的预训练大模型提供预测、训练等服务。 &#x1f917; Transformers 提供了数以千计的预训练…

linux的安全技术和防火墙

一、安全技术 1.入侵检测系统&#xff1a;特点式不阻断网络访问&#xff0c;主要式提供报警和事后监督&#xff0c;不主动介入&#xff0c;默默的看着你&#xff08;相当于360安全卫士&#xff09; 2.入侵防御系统&#xff1a;透明模式工作&#xff0c;对数据包&#xff0c;网…

音频——性能测试中的基本概念

文章目录 频率响应平均电平增益ADC 路径增益DAC 路径增益底噪信噪比总谐波失真+噪声(THD+N)延迟频率响应 对于音频设备,频率响应可以理解为音频设备对不同频率信号的处理或重现。对于音频信号频率,一般关注20Hz~20kHz范围。理想情况下,输入幅度相同的不同频率信号,过音频…

springboot社区维修平台

设计技术&#xff1a; springboot、mysql、maven、前端vue 主要功能&#xff1a; 住户管理、社区公告管理、维修工管理、维修订单管理、接单信息管理、订单信息管理、在线沟通管理、举报信息管理、留言板管理、系统管理等功能模块。 管理员功能模块 管理员通过后台登录页面…

sessionStorage 能在多个标签页之间共享数据吗?

&#x1f9d1;‍&#x1f4bb; 写在开头 点赞 收藏 学会&#x1f923;&#x1f923;&#x1f923; 最近&#xff0c;我的一个朋友在面试中被一个关于 sessionStorage 的问题难住了。我们来聊聊这个话题。 sessionStorage 能在多个标签页之间共享数据吗&#xff1f; 在回答…

vscode刷LeetCode算法题环境配置

首先&#xff0c;下载nodejs 在vscode中安装LeetCode插件 安装好进行配置 选择leetcode-cn 填上刚才下载node.exe的路径 完成之后重启一下vscode 重启之后登陆LeetCode 完成之后就可以看到题目了 点击 code now 就可以开始刷题了

计算机网络之数据通信原理(下)

上一讲内容&#xff1a;数据传输方式、数据传输形式、传输差错处理、常用差错检测方法 数据通信过程中&#xff0c;一个很重要的问题就是如何控制数据的传输&#xff0c;就涉及到了传输控制规程&#xff08;协议&#xff09; 下面介绍两种&#xff1a; ①BSC&#xff1a;面向…

反向代购是怎么火起来的?今后的发展趋势如何?

反向代购和反向海淘的兴起可以归因于多个因素&#xff0c;这些因素共同推动了海外消费者对中国商品的需求和购买热潮。以下是对其火起来的原因的详细分析&#xff1a; 海外华人华侨的需求增加&#xff1a; 随着中国国际移民群体的扩大&#xff0c;海外华人华侨数量不断增多。这…

基于哈尔小波基的一维密度估计(Python)

先说点其他的东西。 关于强非线性、强间断、多物理场强耦合或高度复杂几何形态问题能够得以有效求解的核心难题之一&#xff0c;是如何构建在多尺度情形、非线性作用下具有准确地识别、定位、捕获以及分离各个尺度特征尤其是小尺度局部特征能力的数值工具&#xff0c;这之中包…

上海晋名室外危化品暂存柜成都项目落地

近日又有一台SAVEST室外危化品暂存柜项目成功验收交付使用。 用户单位是一家专注于兽用消毒剂原料和表面活性剂研发、生产的高新技术企业。用户在日常工作运营中涉及到危化品的室外安全储存问题。 3月底用户在寻找解决方案的过程中搜索到上海晋名的室外暂存柜系列后挺感兴趣的…

【Java Web】Vite构建前端目录结构

目录 一、Vite概述 二、Vite构建Vue3工程化项目 三、ViteVue3项目目录结构 四、ViteVue3项目组件&#xff08;SFC入门&#xff09; 五、ViteVue3样式导入方式 六、ViteVue3响应式数据和setup语法糖 一、Vite概述 Vite是一种新型前端构建工具,能够显著提升前端开发体验;Vite结合…