装饰器模式知识分享: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,都可以利用这种模式,让代码更加模块化,维护更加容易。🎉

感谢阅读!

相关推荐
Kapaseker1 天前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴1 天前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭1 天前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab2 天前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe2 天前
Now in Android 架构模式全面分析
android·android jetpack
ssshooter2 天前
Tauri 踩坑 appLink 修改后闪退
前端·ios·rust
二流小码农2 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少2 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker2 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋2 天前
Android 协程时代,Handler 应该退休了吗?
android