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

感谢阅读!

相关推荐
深海呐31 分钟前
Android 从本地选择视频,用APP播放或进行其他处理
android·音视频·从本地选择视频,用app播放·从本地选择视频,并拿到信息·跳转到本地视频列表
深海呐32 分钟前
Android Google登录接入
android·google登录接入·android 谷歌登录接入·google登录·android google
ZVAyIVqt0UFji44 分钟前
iOS屏幕共享技术实践
macos·ios·objective-c·cocoa
daiyang123...1 小时前
MySQL【知识改变命运】11
android·数据库·mysql
8931519601 小时前
Android开发教程案例源码分享-匹配动画多个头像飘动效果
android·android开发·android教程·kotlin教程·android头像飘动动画·android匹配动画·android多个头像飘动动画
hfxns_2 小时前
iOS 18.2 Beta 4开发者预览版发布,相机新增辅助功能
ios
老码沉思录2 小时前
Android开发实战班 - 网络编程 - WebSocket 实时通信
android·网络·websocket
江上清风山间明月2 小时前
Android 14 screenrecord录制视频失败的原因分析
android·视频·大小·失败·录制·screenrecord·0kb
keeng20082 小时前
Compose学习记录(3): ViewModel数据驱动更新组件
android
唐诺3 小时前
android MQTT使用示例
android·mqtt