装饰器模式知识分享:Android (Kotlin) 与 iOS (Swift) 实现

装饰器模式(Decorator Pattern)是一种非常重要的设计模式,它允许我们在不修改已有对象的情况下,动态地为其添加新的行为和功能。

这种模式广泛用于 Android 和 iOS 的开发中,特别是在我们想要扩展现有功能,而不破坏已有代码时。让我们从 Android 和 iOS 两个角度,详细了解一下如何使用装饰器模式。

什么是装饰器模式?🤔

装饰器模式的核心思想是将一个对象"包裹"起来,动态地给它添加新的行为,而不是直接修改或继承该对象的类。

换句话说,我们用"装饰器"来增强现有对象的功能,而无需改变它的源代码。

  • 装饰器模式的好处:
    1. 遵循开闭原则:对扩展开放,对修改封闭。
    2. 动态地扩展对象的功能,而不修改已有代码。
    3. 灵活性高,可以组合多个装饰器来增强对象。

Android (Kotlin) 实现装饰器模式 🧩📱

在 Android 开发中,装饰器模式常用于扩展 WebViewClientRecyclerView.Adapter 等类,来为现有功能增加新功能。

假设场景:

我们有一个 WebViewClient,已经实现了基本的功能。现在,我们想在页面加载完成时,打印出当前页面的 HTML 内容,而不影响原有功能。

实现步骤:

  1. 获取或创建原有的 WebViewClient 对象。
  2. 用一个新的 WebViewClient 包装原有对象,并在页面加载完成时,添加新的行为。
  3. 调用原有对象的方法,保留原有功能。

Kotlin 实现代码:

kotlin 复制代码
// 假设我们已经有一个 WebViewClient 实例
val originalWebViewClient = webView.webViewClient ?: WebViewClient()

// 创建新的 WebViewClient,扩展其功能
webView.webViewClient = object : WebViewClient() {
    override fun onPageFinished(view: WebView?, url: String?) {
        // 调用原有的 onPageFinished 方法,保留现有功能
        originalWebViewClient.onPageFinished(view, url)

        // 添加新的功能:打印页面 HTML
        view?.evaluateJavascript(
            """
            (function() {
                return document.documentElement.outerHTML;
            })();
            """.trimIndent()
        ) { html ->
            Log.d("WebViewHTML", "HTML content: $html")
        }
    }
}

解释:

  • originalWebViewClient: 复用已有的 WebViewClient,避免功能丢失。
  • onPageFinished: 在页面加载完成后,我们调用原有的逻辑,并添加打印 HTML 的功能。

这种做法的好处:

  • 你无需修改已有的 WebViewClient 实现,只需包裹并扩展它。
  • 保证了原有功能的完整性,还能动态地添加新的行为。

iOS (Swift) 实现装饰器模式 🧩🍏

在 iOS 开发中,装饰器模式同样可以用来扩展对象的功能,常用于扩展 UIViewControllerUITableViewDelegate 等。Swift 的扩展性很强,我们可以利用协议、类扩展等手段来实现装饰器模式。

假设场景:

我们有一个 WKNavigationDelegate,它负责处理网页的加载。现在,我们想在页面加载完成时,获取页面的 HTML 内容,并打印出来。

实现步骤:

  1. 创建一个原有的 WKNavigationDelegate 实例。
  2. 使用装饰器模式,通过扩展 WKWebView,为页面加载完成后添加新的行为。
  3. 保留原有 WKNavigationDelegate 的行为,同时扩展新功能。

Swift 实现代码:

swift 复制代码
// 原有的 WKNavigationDelegate 实现
class OriginalNavigationDelegate: NSObject, WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        // 原有的页面加载完成处理
        print("Original page finished loading.")
    }
}

// 扩展 WKWebView,添加打印 HTML 功能
extension WKWebView {
    func printHTMLContent() {
        self.evaluateJavaScript("document.documentElement.outerHTML.toString()") { result, error in
            if let html = result as? String {
                print("HTML content: \(html)")
            }
        }
    }
}

// 创建新的装饰器类,包裹原有的 WKNavigationDelegate
class NavigationDelegateDecorator: NSObject, WKNavigationDelegate {
    private let wrapped: WKNavigationDelegate

    init(wrapped: WKNavigationDelegate) {
        self.wrapped = wrapped
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        // 调用原有的行为
        wrapped.webView?(webView, didFinish: navigation)

        // 添加新的功能:打印页面 HTML
        webView.printHTMLContent()
    }
}

// 使用装饰器模式
let originalDelegate = OriginalNavigationDelegate()
let decoratedDelegate = NavigationDelegateDecorator(wrapped: originalDelegate)

// 将装饰后的 delegate 设置给 WKWebView
webView.navigationDelegate = decoratedDelegate

解释:

  • OriginalNavigationDelegate: 原有的委托实现。
  • NavigationDelegateDecorator: 这是装饰器类,扩展了原有的委托功能。
  • printHTMLContent: 扩展了 WKWebView,在页面加载完成时打印 HTML。

这种做法的好处:

  • 你无需修改原有的 WKNavigationDelegate 逻辑。
  • 新增的功能和原有功能完全解耦,代码清晰且易于维护。

总结 ✨

装饰器模式是一种强大的设计模式,能够让我们在不修改已有代码的情况下,为对象动态地添加新功能。在 Android 和 iOS 开发中,装饰器模式尤其适用于扩展那些无法直接修改的类或对象,比如 WebViewClientWKNavigationDelegate 等。

  • Android (Kotlin) :通过复用现有的 WebViewClient,并在其基础上添加新的行为,比如打印页面 HTML。
  • iOS (Swift) :使用类扩展和委托装饰,动态为 WKNavigationDelegate 添加新功能,比如打印页面 HTML。

装饰器模式的优势在于其灵活性和可组合性。无论是 Android 还是 iOS,都可以利用这种模式,让代码更加模块化,维护更加容易。🎉

感谢阅读!

相关推荐
菜鸟国国1 小时前
一步到位学 Compose + Paging3:从 0 到 1 实现分页加载(超详细新手教程)
android
TO_ZRG1 小时前
Android Service基础
android
ECT-OS-JiuHuaShan2 小时前
功夫不负匠心人,渡劫代谢舞沧桑
android·开发语言·人工智能·算法·机器学习·kotlin·拓扑学
ZC跨境爬虫3 小时前
移动端爬虫工具Fiddler完整配置流程:PC+安卓模拟器全覆盖,零基础一次配置成功
android·前端·爬虫·测试工具·fiddler
巴德鸟4 小时前
DaVinci 常用技巧 关键帧 自动字幕 追踪 音频 冻结帧 快捷键 多轨道字幕 扩充边缘
android·编辑器·音视频·视频·davinci·davin
学习使我健康4 小时前
Android 广播介绍详情
android·开发语言·kotlin
dalancon5 小时前
AudioTrack Start 执行流程分析
android
众少成多积小致巨5 小时前
Android 初始化语言入门
android·linux·c++
Carson带你学Android5 小时前
谁才是地表最强 Android Agent 大模型?Google官方测评来了!
android·openai