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

感谢阅读!

相关推荐
千里马学框架14 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台14 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone14 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc15 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo16 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun00770017 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼18 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
茶底世界之下18 小时前
为什么预览、录制、离线导出不能共享同一个背压策略?
ios·swift
AFinalStone19 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen19 小时前
属性动画原理与高级动画实现
android·kotlin·canvas