代理模式 - Flutter中的智能替身,掌控對象訪問的每一道關卡!

痛點場景:直接加載高清大圖

假設你的應用需要顯示用戶相冊:

NetworkImage('https://example.com/high-res-photo.jpg')

面臨的問題:

  • 📶 網絡差時長時間白屏
  • 💾 重復下載相同圖片浪費流量
  • 🔒 敏感圖片無權限驗證
  • 📱 內存占用過高導致崩潰

代理模式解決方案

核心思想: 為其他對象提供一種代理以控制對這個對象的訪問。

三種常見代理類型:

  1. 虛擬代理: 延遲加載大資源(如占位圖→高清圖)
  2. 保護代理: 控制訪問權限
  3. 緩存代理: 存儲請求結果避免重復計算/下載

Flutter圖片加載代理實現

1. 定義圖片加載接口
abstract class ImageLoader {Future<ImageProvider> load(String url);
}
2. 實現真實圖片加載器
class RealImageLoader implements ImageLoader {Future<ImageProvider> load(String url) async {print('真實加載器:從網絡加載高清圖片');return NetworkImage(url);}
}
3. 創建智能代理
class SmartImageLoader implements ImageLoader {final RealImageLoader _realLoader = RealImageLoader();final Map<String, ImageProvider> _cache = {};Future<ImageProvider> load(String url) async {// 1. 檢查緩存if (_cache.containsKey(url)) {print('代理:從緩存返回圖片');return _cache[url]!;}// 2. 顯示占位圖print('代理:先返回低分辨率占位圖');final placeholder = ResizeImage(NetworkImage('$url?thumb=true'),width: 100,height: 100,);// 3. 后臺加載高清圖_realLoader.load(url).then((highResImage) {print('代理:高清圖加載完成,更新緩存');_cache[url] = highResImage;// 通知UI更新(可通過ChangeNotifier或Stream)});return placeholder;}
}
4. 在Flutter中使用
class PhotoViewer extends StatelessWidget {final ImageLoader loader = SmartImageLoader(); // 使用代理Widget build(BuildContext context) {return FutureBuilder<ImageProvider>(future: loader.load('https://example.com/photo1.jpg'),builder: (ctx, snapshot) {if (snapshot.hasData) {return Image(image: snapshot.data!);}return CircularProgressIndicator();},);}
}

Flutter中的實際應用場景

場景1:權限控制代理
class AuthImageLoader implements ImageLoader {final UserService _userService;final RealImageLoader _realLoader;Future<ImageProvider> load(String url) async {if (!await _userService.checkPhotoPermission(url)) {return AssetImage('assets/locked.png');}return _realLoader.load(url);}
}// 使用
ImageLoader loader = AuthImageLoader(userService, realLoader);
場景2:API請求緩存代理
class CachedApiClient implements ApiClient {final ApiClient _realClient;final Map<String, dynamic> _cache = {};Future<dynamic> fetchData(String endpoint) async {if (_cache.containsKey(endpoint)) {return _cache[endpoint];}final data = await _realClient.fetchData(endpoint);_cache[endpoint] = data;return data;}
}// 使用
final apiClient = CachedApiClient(RealApiClient());
final product = await apiClient.fetchData('/products/123');
場景3:敏感操作延遲代理
class ExpenseReportGeneratorProxy implements ReportGenerator {RealReportGenerator? _realGenerator;Future<Report> generate() async {if (!await _checkPermission()) throw UnauthorizedException();_realGenerator ??= RealReportGenerator(); // 按需創建return _realGenerator!.generate();}
}

代理模式與Flutter狀態管理結合

將圖片代理與Provider結合:

class ImageLoaderProvider extends ChangeNotifier {final ImageLoader _loader;ImageProvider? _currentImage;ImageLoaderProvider(this._loader);Future<void> loadImage(String url) async {_currentImage = await _loader.load(url);notifyListeners();}
}// 使用
context.read<ImageLoaderProvider>().loadImage('photo.jpg');Consumer<ImageLoaderProvider>(builder: (context, provider, child) {return provider.currentImage != null? Image(image: provider.currentImage!): Placeholder();}
)

代理模式最佳實踐

  1. 何時使用代理模式:

    • 需要延遲加載大資源時(虛擬代理)
    • 需要控制原始對象訪問權限時(保護代理)
    • 需要緩存請求結果時(緩存代理)
    • 需要記錄日志或監控對象訪問時
  2. Flutter特化技巧:

    // 組合多種代理
    ImageLoader loader = LoggingImageLoader(CacheImageLoader(AuthImageLoader(RealImageLoader()))
    );// 使用Futures組合
    Future<ImageProvider> load(String url) async {final lowRes = await _loadLowRes(url);final highRes = _loadHighRes(url); // 不awaitreturn ProxyImage(lowRes, highRes);
    }
  3. 性能優化:

    // 預加載代理
    class PrefetchImageLoader implements ImageLoader {final List<String> _prefetchUrls;void prefetchAll() {for (final url in _prefetchUrls) {_realLoader.load(url); // 不await,后臺加載}}
    }
  4. 測試策略:

    test('緩存代理測試', () async {final mockLoader = MockImageLoader();final proxy = CachedImageLoader(mockLoader);when(mockLoader.load('test.jpg')).thenAnswer((_) async => FakeImage());// 第一次調用真實對象await proxy.load('test.jpg');// 第二次應從緩存返回await proxy.load('test.jpg');verify(mockLoader.load('test.jpg')).called(1); // 僅調用一次
    });

代理模式 vs 裝飾器模式

特性代理模式裝飾器模式
目的控制訪問增強功能
關系代理與真實對象關系固定裝飾器可遞歸嵌套
創建時機通常提前知道真實對象運行時動態組合
典型應用懶加載、權限控制、緩存流式處理、動態擴展

代理模式的高級變體

1. 遠程代理(跨進程通信)
// 本地代理
class LocalImageProxy implements ImageLoader {Future<ImageProvider> load(String url) async {// 通過平臺通道調用原生代碼final result = await MethodChannel('image_loader').invokeMethod('loadImage', {'url': url});return MemoryImage(base64Decode(result));}
}
2. 智能引用代理
class ImageRefProxy implements ImageLoader {int _refCount = 0;ImageProvider? _cachedImage;Future<ImageProvider> load(String url) async {_refCount++;if (_cachedImage == null) {_cachedImage = await _realLoader.load(url);}return _cachedImage!;}void release() {_refCount--;if (_refCount == 0) {_cachedImage?.evict(); // 釋放內存_cachedImage = null;}}
}
3. 日志監控代理
class AnalyticsImageLoader implements ImageLoader {final AnalyticsService _analytics;final ImageLoader _realLoader;Future<ImageProvider> load(String url) async {_analytics.logEvent('image_load_start', {'url': url});final stopwatch = Stopwatch()..start();try {final image = await _realLoader.load(url);_analytics.logEvent('image_load_success', {'url': url,'duration': stopwatch.elapsedMilliseconds,});return image;} catch (e) {_analytics.logError('image_load_failed', {'url': url});rethrow;}}
}

總結:代理模式是你的訪問管家

  • 核心價值: 在訪問真實對象前后插入額外邏輯
  • Flutter優勢:
    • 實現圖片懶加載和緩存
    • 控制敏感資源訪問
    • 減少網絡請求和計算開銷
    • 添加監控和日志記錄
  • 適用場景: 圖片加載、API調用、權限管理、性能優化

🕶? 設計啟示: 當你需要在訪問對象時加入"中間層"控制時,代理模式就是你的"隱形眼鏡",既能看清需求,又能保護眼睛!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86999.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86999.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86999.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python集合的創建

一、前言 在 Python 編程中&#xff0c;集合&#xff08;set&#xff09;是一種非常實用的數據結構&#xff0c;它能夠存儲一組無序且不重復的元素。集合廣泛應用于數據去重、交并差運算等場景。 本文將重點講解 Python 中集合的創建方式&#xff0c;包括使用大括號 {}、set(…

作物生長模型Oryza V3實戰15:AutoCalibration程序詳解

ORYZA 模型中的 AutoCalibration (v2.1).exe 是用于 ORYZA 模型參數自動校準的可執行程序,在優化 ORYZA 模型參數、提高模型模擬準確性方面具有重要作用。程序能夠通過特定算法,在給定的參數取值范圍內,自動搜索出一組最優的參數組合,使得模型模擬結果與實際觀測數據(如作…

算法-每日一題(DAY12)最長和諧子序列

1.題目鏈接&#xff1a; 594. 最長和諧子序列 - 力扣&#xff08;LeetCode&#xff09; 2.題目描述&#xff1a; 和諧數組是指一個數組里元素的最大值和最小值之間的差別 正好是 1 。 給你一個整數數組 nums &#xff0c;請你在所有可能的 子序列 中找到最長的和諧子序列的…

阿里云-云效自動部署spring boot項目

1.使用云效通過docker自動部署spring boot項目 1.1 spring boot項目配置 # 阿里云的jdk17鏡像 FROM registry.cn-zhangjiakou.aliyuncs.com/publicci/openjdk:17-jdk-alpineENV APP_HOME /home/admin/app/# 將target/arms-application.jar 復制到容器中 /home/admin/app/app.…

SQL篇 添加約束、刪除約束

SQL篇 添加約束、刪除約束 1、相關鏈接2、約束的增刪找查2.1 查看約束&#xff08;主鍵、外鍵、唯一性、檢查約束&#xff09;2.2 查看默認約束2.3 修改約束&#xff08;添加/編輯/修改&#xff09;2.3.1 添加主鍵約束2.3.2 添加外鍵約束2.3.3 添加唯一性約束2.3.4 添加檢查約束…

Python PyTorch 深度學習庫 包 timm

文章目錄 &#x1f4e6; 主要特點&#x1f680; 安裝方式&#x1f9ea; 使用示例示例1&#xff1a;加載一個預訓練模型進行圖像分類示例2&#xff1a;獲取模型結構信息 &#x1f310; 官方資源&#x1f50d; 常見用途? 優勢總結 Timm 是一個非常流行且功能強大的 Python 深度學…

tree 命令集成到 Git Bash:可視化目錄結構的指南

目錄 1. 下載與準備 tree 工具 ??2. 集成 tree 到 Git Bash 環境 ??3. tree 命令基礎用法詳解 ??4. 使用示例 在軟件開發和文件管理中&#xff0c;清晰的目錄結構可視化是提高效率的重要手段。tree命令作為 UNIX/Linux 系統的標準工具&#xff0c;能以樹形結構遞歸展…

如何搭建基于RK3588的邊緣服務器集群?支持12個RK3588云手機

以下是基于RK3588搭建邊緣服務器集群的完整實施方案&#xff0c;涵蓋硬件選型、集群架構、軟件部署及優化要點&#xff1a; &#x1f5a5;? ?一、硬件集群架構設計? ?節點基礎配置? ?核心單元?&#xff1a;單節點采用RK3588核心板&#xff08;4A762.4GHz 4A551.8GHz&am…

飛算 JavaAI:我的編程強力助推引擎

文章目錄 引言&#xff1a;當Java開發遇上AI助手初識飛算JavaAI&#xff1a;專為Java而生的智能伴侶安裝與配置&#xff1a;輕松上手的開始核心功能體驗&#xff1a;從需求到代碼的全流程革命1. 智能需求分析與拆解2. 智能接口設計3. 表結構智能生成4. 處理邏輯自動梳理5. 高質…

飛算JavaAI—AI編程助手 | 編程領域的‘高科技指南針’,精準導航開發!

目錄 一、引言 1.1 什么是飛算JavaAI&#xff1f; 1.2 告別"996的孤獨感"&#xff1a;AI成為你的編碼搭子 1.3 成就感加速器&#xff1a;從"能運行"到"優雅實現" 1.4 極簡下載體驗&#xff1a;3步開啟"開掛"模式 二、深入體驗飛…

NPM組件 betsson 等竊取主機敏感信息

【高危】NPM組件 betsson 等竊取主機敏感信息 漏洞描述 當用戶安裝受影響版本的 betsson 組件包時會竊取用戶的主機名、用戶名、工作目錄、IP地址等信息并發送到攻擊者可控的服務器地址。 MPS編號MPS-2nrw-lifd處置建議強烈建議修復發現時間2025-06-30投毒倉庫npm投毒類型主…

Apipost 與 Apifox:API 開發管理中的 AI 能力對比

在當今競爭激烈的 API 開發與測試領域&#xff0c;效率與質量是衡量工具優劣的關鍵指標。Apipost 憑借其強大的 AI 功能&#xff0c;為開發者和測試人員帶來了前所未有的便利&#xff0c;而 Apifox 作為該領域的重要參與者&#xff0c;二者在實際應用中究竟有何差異&#xff1f…

Electron 菜單欄深度定制指南:從基礎到高級實踐

在現代桌面應用開發中&#xff0c;菜單欄作為用戶界面的重要組成部分&#xff0c;不僅提供了應用功能的快速訪問途徑&#xff0c;還直接影響著用戶的操作體驗。Electron 作為跨平臺桌面應用開發框架&#xff0c;為開發者提供了強大而靈活的菜單系統定制能力。本文將全面介紹 El…

QML通過XMLHttpRequest實現HTTP通信

轉自個人博客 由于 QML 的 JavaScript 兼容性&#xff0c;我們可以直接使用 JavaScript 的 XMLHttpRequest 對象進行 HTTP 請求。QML 的 XMLHttpRequest 實現與標準瀏覽器的實現非常相似&#xff0c;但有一些限制和特殊行為需要注意。 而QML實現TCP等其他通信一般就需要借助Qt與…

Spring Boot 內置反向代理(Undertow Proxy)高可用配置

引言 在微服務架構中&#xff0c;反向代理是一個不可或缺的組件&#xff0c;它負責請求轉發、負載均衡、安全過濾等關鍵功能。 通常我們會選擇 Nginx、HAProxy 等專業反向代理組件&#xff0c;但在某些場景下&#xff0c;使用 Spring Boot 內置的反向代理功能可以簡化架構&am…

ClickHouse 部署

Docker 部署 1、拉取鏡像 docker pull clickhouse/clickhouse-server:latest單機版本部署 編寫docker-compose.yml version: 3services:clickhouse-server:image: clickhouse/clickhouse-server:22.12container_name: clickhouse-serverports:- "8123:8123"ulimit…

Fiddler中文版抓包工具如何幫助前端開發者高效調試

前端開發早已不再是“寫好頁面就完事”的工作。隨著業務復雜度提升&#xff0c;前端開發者需要直面接口聯調、性能優化、跨域排查、HTTPS調試等一系列和網絡請求緊密相關的任務。抓包工具成為這些環節中不可替代的得力助手&#xff0c;而 Fiddler抓包工具 因其全面的功能和靈活…

WTL 之trunk技術學習

相比于MFC的消息機制&#xff0c;WTL/ATL的實現更加優雅。后者將win32 API與面向對象技術完美地結合起來&#xff0c;去掉了龐雜的MFC依賴&#xff0c;生成的軟件體積更小&#xff0c;運行速度更快。在其中&#xff0c;如何將窗口函數轉變為對窗口對象成員函數的調用&#xff0…

Linux——11.軟件安裝與包管理

Linux 與 Windows 系統在軟件安裝方式上的差異 Linux: Linux 通過 包管理系統(如 Debian 的 apt、Red Hat 的 yum/dnf)將軟件打包為二進制安裝包(如 .deb、.rpm),每個包包含程序文件、依賴關系和元數據。包管理系統負責統一管理軟件的安裝、更新、卸載,并自動處理依賴關…

無人機用shell遠程登錄機載電腦,每次需要環境配置原因

原因&#xff1a; 終端分為“登錄 shell”和“非登錄 shell”&#xff1a; - 登錄 shell&#xff08;如開機登錄、遠程 SSH 連接&#xff09;會加載 .profile 或 .bash_profile 。 - 非登錄 shell&#xff08;如打開新終端窗口&#xff09;會加載 .bashrc 。 - 如果環境變量…