建造者模式 - Flutter中的樂高大師,優雅組裝復雜UI組件!

痛點場景:復雜的對話框配置

假設你需要創建一個多功能對話框:

CustomDialog(title: '警告',content: '確定要刪除嗎?',titleStyle: TextStyle(fontSize: 20, color: Colors.red),contentStyle: TextStyle(fontSize: 16),backgroundColor: Colors.grey[200],barrierDismissible: false,positiveButton: DialogButton(text: '確認',color: Colors.red,onPressed: () => print('Confirmed'),),negativeButton: DialogButton(text: '取消',color: Colors.grey,onPressed: () => print('Cancelled'),),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10),),// 還有10個參數...
)

問題爆發點:

  • 🚨 構造函數參數爆炸(難以維護和使用)
  • 💥 必須記住參數順序
  • 🔥 可選參數處理困難(需要傳入大量null)
  • 🌋 相似組件創建需要重復代碼

建造者模式解決方案

核心思想: 將復雜對象的構建與其表示分離,使同樣的構建過程可以創建不同的表示。

四個關鍵角色:

  1. 產品(Product): 最終要構建的復雜對象(如對話框)
  2. 抽象建造者(Builder): 定義構建步驟的接口
  3. 具體建造者(ConcreteBuilder): 實現構建步驟
  4. 指揮者(Director): 控制構建過程(Flutter中常可省略)

Flutter對話框建造者實現

1. 定義產品類
class DialogConfig {String? title;String? content;TextStyle? titleStyle;TextStyle? contentStyle;Color? backgroundColor;bool barrierDismissible = true;DialogButton? positiveButton;DialogButton? negativeButton;ShapeBorder? shape;// 其他配置項...
}class DialogButton {final String text;final Color color;final VoidCallback onPressed;DialogButton({required this.text,required this.color,required this.onPressed,});
}
2. 創建建造者類
class DialogBuilder {final DialogConfig _config = DialogConfig();// 設置標題DialogBuilder title(String title, {TextStyle? style}) {_config.title = title;_config.titleStyle = style;return this;}// 設置內容DialogBuilder content(String content, {TextStyle? style}) {_config.content = content;_config.contentStyle = style;return this;}// 設置背景DialogBuilder backgroundColor(Color color) {_config.backgroundColor = color;return this;}// 添加確認按鈕DialogBuilder withPositiveButton(String text, {required VoidCallback onPressed,Color color = Colors.blue,}) {_config.positiveButton = DialogButton(text: text,color: color,onPressed: onPressed,);return this;}// 構建最終產品Widget build() {return AlertDialog(title: _config.title != null ? Text(_config.title!, style: _config.titleStyle): null,content: _config.content != null? Text(_config.content!, style: _config.contentStyle): null,backgroundColor: _config.backgroundColor,actions: [if (_config.negativeButton != null)TextButton(style: TextButton.styleFrom(foregroundColor: _config.negativeButton!.color,),onPressed: _config.negativeButton!.onPressed,child: Text(_config.negativeButton!.text),),if (_config.positiveButton != null)TextButton(style: TextButton.styleFrom(foregroundColor: _config.positiveButton!.color,),onPressed: _config.positiveButton!.onPressed,child: Text(_config.positiveButton!.text),),],shape: _config.shape,);}
}
3. 在Flutter中使用
// 基礎用法
showDialog(context: context,builder: (_) => DialogBuilder().title('警告', style: TextStyle(color: Colors.red)).content('確定要刪除這個文件嗎?').withPositiveButton('刪除', onPressed: () => Navigator.pop(context)).build()
);// 復雜用法
final deleteDialog = DialogBuilder().title('永久刪除', style: TextStyle(fontWeight: FontWeight.bold)).content('此操作將永久刪除數據,不可恢復!').backgroundColor(Colors.grey[100]!).withPositiveButton('確認刪除', onPressed: () => _deleteItem(),color: Colors.red,).withNegativeButton('取消').build();showDialog(context: context, builder: (_) => deleteDialog);

Flutter框架中的建造者模式

實際上,Flutter自身大量使用了建造者模式的變體:

1. TextStyle 的copyWith方法
TextStyle style = TextStyle(fontSize: 16,color: Colors.black,
).copyWith(fontWeight: FontWeight.bold,decoration: TextDecoration.underline,
);
2. ThemeData 的構造方式
final theme = ThemeData.light().copyWith(primaryColor: Colors.blue,buttonTheme: ButtonThemeData(buttonColor: Colors.blue[700],),
);
3. BoxDecoration 的鏈式配置
BoxDecoration(color: Colors.blue,borderRadius: BorderRadius.circular(10),boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 6),],
)

高級應用:響應式布局建造者

創建一個能自動適應不同屏幕尺寸的布局建造者:

class ResponsiveBuilder {final List<Widget> _children = [];double _spacing = 16.0;Axis _direction = Axis.vertical;int _crossAxisCount = 2;ResponsiveBuilder addChild(Widget child) {_children.add(child);return this;}ResponsiveBuilder spacing(double value) {_spacing = value;return this;}ResponsiveBuilder horizontal() {_direction = Axis.horizontal;return this;}ResponsiveBuilder columns(int count) {_crossAxisCount = count;return this;}Widget build() {return LayoutBuilder(builder: (context, constraints) {if (constraints.maxWidth > 600) {return GridView.count(crossAxisCount: _crossAxisCount,childAspectRatio: 1.0,mainAxisSpacing: _spacing,crossAxisSpacing: _spacing,children: _children,);} else {return ListView.separated(scrollDirection: _direction,itemCount: _children.length,separatorBuilder: (_, __) => SizedBox(width: _direction == Axis.horizontal ? _spacing : 0,height: _direction == Axis.vertical ? _spacing : 0,),itemBuilder: (context, index) => _children[index],);}},);}
}// 使用示例
ResponsiveBuilder().addChild(ProductCard(product1)).addChild(ProductCard(product2)).spacing(20).columns(3).build()

建造者模式最佳實踐

  1. 何時使用建造者模式:

    • 對象需要多個步驟或復雜配置才能創建
    • 構造函數參數超過4個
    • 需要創建不可變對象但又要靈活配置
    • 相同構建過程需要創建不同表示
  2. Flutter特化技巧:

    // 使用可選命名參數簡化初始創建
    DialogBuilder({String? title, String? content}) {if (title != null) _config.title = title;if (content != null) _config.content = content;
    }// 添加預置配置
    DialogBuilder.error() {return DialogBuilder().titleColor(Colors.red).backgroundColor(Colors.red[50]!);
    }// 支持運算符重載
    DialogBuilder operator <<(Widget child) {addChild(child);return this;
    }
    
  3. 性能優化:

    // 使用memoization緩存常用配置
    class DialogBuilder {static final Map<String, DialogConfig> _presets = {};static DialogBuilder preset(String name) {if (!_presets.containsKey(name)) {_presets[name] = _createPreset(name);}return DialogBuilder.fromConfig(_presets[name]!);}
    }
    

建造者模式 vs 工廠模式

特性建造者模式工廠模式
主要目的分步構建復雜對象創建對象家族
構建過程顯式控制每個步驟隱藏創建細節
適用場景包含多個組件的對象不同系列的對象
Flutter應用復雜組件配置、響應式布局主題系統、平臺適配

建造者模式的強大變體

1. 階段式建造者
abstract class DialogBuilderPhase1 {DialogBuilderPhase2 setTitle(String title);
}abstract class DialogBuilderPhase2 {DialogBuilderPhase3 setContent(String content);
}class DialogBuilder implements DialogBuilderPhase1, DialogBuilderPhase2 {// 分階段實現...
}// 強制按順序調用:
DialogBuilder().setTitle('標題') // 必須第一步.setContent('內容') // 必須第二步.build();
2. 裝飾器增強建造者
class DialogDecorator implements DialogBuilder {final DialogBuilder _builder;DialogDecorator(this._builder);DialogBuilder title(String title) {_builder.title(title);return this;}// 添加額外功能DialogDecorator withAnimation(Duration duration) {// 添加動畫邏輯return this;}
}// 使用增強功能
DialogDecorator(CustomDialogBuilder()).title('動畫對話框').withAnimation(Duration(seconds: 1)).build();

總結:建造者模式是你的UI組裝線

  • 核心價值: 將復雜對象的構建過程分解為可管理的步驟
  • Flutter優勢:
    • 解決"參數爆炸"問題
    • 創建不可變對象的靈活方式
    • 提高大型組件配置的可讀性
    • 支持流暢的鏈式調用
  • 適用場景: 復雜對話框、表單構建、響應式布局、主題配置

🔧 設計啟示: 當組件參數超過5個或創建邏輯復雜時,建造者模式能顯著改善代碼質量!

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

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

相關文章

基于Java+Spring Boot的大學校園生活信息平臺

源碼編號&#xff1a;S559 源碼名稱&#xff1a;基于Spring Boot的大學校園生活信息平臺 用戶類型&#xff1a;雙角色&#xff0c;用戶、管理員 數據庫表數量&#xff1a;17 張表 主要技術&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven 運行環境&#xff1a;Wind…

C# .NET Framework 中的高效 MQTT 消息傳遞

介紹&#xff1a; 在當今互聯互通的世界里&#xff0c;設備之間高效可靠的通信至關重要。MQTT&#xff08;消息隊列遙測傳輸&#xff09;就是為此而設計的輕量級消息傳遞協議。本文將探討 MQTT 是什么、它的優勢以及如何在 .NET 框架中設置和實現它。最后&#xff0c;您將對 M…

nn.Embedding 和 word2vec 的區別

理解它們的關鍵在于??區分概念層級和職責??。 可以將它們類比為&#xff1a; ??word2vec&#xff1a;?? 一個??專門制作高質量詞向量模型的“工廠”??。??nn.Embedding&#xff1a;?? 一個??可存儲、查找并訓練詞向量的“智能儲物柜”??&#xff08;作為…

華為云Flexus+DeepSeek征文|??華為云ModelArts Studio大模型 + WPS:AI智能PPT生成解決方案?

引言&#xff1a;告別繁瑣PPT制作&#xff0c;AI賦能高效辦公 ?? 在商業匯報、學術研究、產品發布等場景中&#xff0c;制作專業PPT往往需要耗費大量時間進行內容整理、邏輯梳理和視覺美化。??華為云ModelArts Studio大模型??與??WPS??深度結合&#xff0c;推出AI-P…

【連接redis超時】

報錯 客戶端輸出緩沖區超限 Client … scheduled to be closed ASAP for overcoming of output buffer limits 表示這些客戶端&#xff08;通過 psubscribe 命令進行發布訂閱操作&#xff09;的輸出緩沖區超過了 Redis 配置的限制&#xff0c;Redis 會關閉這些客戶端連接來避免…

PHP「Not enough Memory」實戰排錯筆記

目錄 PHP「Not enough Memory」實戰排錯筆記 1. 背景 2. 快速定位 3. 為什么 5 MB 的圖片能耗盡 128 MB&#xff1f; 3.1 粗略估算公式&#xff08;GD&#xff09; 4. 實際峰值監控 5. 解決過程 6. 最佳實踐與防御措施 7. 總結 PHP「Not enough Memory」實戰排錯筆記 —…

Java垃圾回收機制和三色標記算法

一、對象內存回收 對于對象回收&#xff0c;需要先判斷垃圾對象&#xff0c;然后收集垃圾。 收集垃圾采用垃圾收集算法和垃圾收集器。 判斷垃圾對象&#xff0c;通常采用可達性分析算法。 引用計數法 每個對象設置一個引用計數器。每被引用一次&#xff0c;計數器就加1&am…

基于python網絡數據挖掘的二手房推薦系統

基于網絡數據挖掘的二手房推薦系統設計與實現 【摘要】 隨著互聯網技術在房地產行業的深入應用&#xff0c;線上房源信息呈爆炸式增長&#xff0c;給購房者帶來了信息過載的挑戰。為了提升二手房篩選的效率與精準度&#xff0c;本文設計并實現了一個基于網絡數據挖掘的二手房推…

Java + 阿里云 Gmsse 實現 SSL 國密通信

前言 解決接口或頁面僅密信瀏覽器&#xff08;或 360 國密瀏覽器&#xff09;能訪問的問題 測試頁面 測試網站-中國銀行&#xff1a;https://ebssec.boc.cn/boc15/help.html 使用其他瀏覽器&#xff08;google&#xff0c;edge等&#xff09;打開 使用密信瀏覽器打開 解決…

國產數據庫分類總結

文章目錄 一、華為系數據庫1. 華為 GaussDB 二、阿里系數據庫1. 阿里云 OceanBase2. PolarDB&#xff08;阿里云自研&#xff09; 三、騰訊系數據庫1. TDSQL&#xff08;騰訊云&#xff09;2. TBase&#xff08;PostgreSQL增強版&#xff09; 四、傳統國產數據庫1. 達夢數據庫&…

解密閉包:函數如何記住外部變量

&#x1f9e0; 什么是閉包&#xff1f; 閉包是一個函數對象&#xff0c;它不僅記住它的代碼邏輯&#xff0c;還記住了定義它時的自由變量&#xff08;即非全局也非局部&#xff0c;但被內部函數引用的變量&#xff09;。即使外部函數已經執行完畢&#xff0c;這些自由變量的值…

I2C協議詳解及STM32 HAL庫硬件I2C卡死問題分析

一、I2C協議詳解 1. I2C協議概述 Inter-Integrated Circuit (I2C) 是由 Philips 半導體&#xff08;現 NXP 半導體&#xff09;于 1980 年代設計的一種同步串行通信總線協議。該協議采用半雙工通信模式&#xff0c;支持多主從架構&#xff0c;專為短距離、低速率的芯片間通信…

HTTP協議-后端接收請求

起因就是不知道post這個請求體中這些格式有什么區別&#xff0c;后端又怎么去接收這些不同格式的內容 Get請求 get請求是比較簡單的一類 正常的直接用參數接收&#xff08;不寫的話名字要匹配&#xff09;或者RequestParam都可以接收&#xff0c;用對象綁定也可以 resultful…

HTML5 實現的圣誕主題網站源碼,使用了 HTML5 和 CSS3 技術,界面美觀、節日氛圍濃厚。

以下是一個 HTML5 實現的圣誕主題網站源碼&#xff0c;使用了 HTML5 和 CSS3 技術&#xff0c;界面美觀、節日氛圍濃厚。它包括&#xff1a; 圣誕樹動畫 &#x1f384;雪花飄落特效 ??圣誕祝福語 &#x1f381;響應式布局&#xff0c;適配移動端 你可以將代碼保存為 index.…

Spring Cloud Bus 和 Spring Cloud Stream

Spring Cloud Bus 和 Spring Cloud Stream 都是 Spring Cloud 生態中的消息通信組件&#xff0c;但它們的定位和使用場景有顯著區別&#xff1a; 1. Spring Cloud Bus 核心定位&#xff1a;分布式系統的消息廣播&#xff08;配置刷新、事件傳播&#xff09;。 典型場景&#x…

磁懸浮軸承位移信號的高精度估計:卡爾曼濾波算法深度解析

無需位移傳感器,濾波算法如何實現微米級精度? 磁懸浮軸承作為革命性的非接觸式支承技術,憑借無磨損、無需潤滑、高轉速等優勢,在飛輪儲能、高速電機、人工心臟泵和航空航天領域獲得了廣泛應用。其核心控制依賴于對轉子位移信號的高精度實時檢測,傳統電渦流傳感器雖能提供位…

DAY 43 預訓練模型

目錄 一、預訓練的概念 二、 經典的預訓練模型 2.1 CNN架構預訓練模型 2.2 Transformer類預訓練模型 2.3 自監督預訓練模型 三、常見的分類預訓練模型介紹 3.1 預訓練模型的發展史 3.2 預訓練模型的訓練策略 知識點回顧&#xff1a; 預訓練的概念常見的分類預訓練模型圖像…

Redis:事物

&#x1f308; 個人主頁&#xff1a;Zfox_ &#x1f525; 系列專欄&#xff1a;Redis &#x1f525; 什么是事務 Redis的事務和MySQL的事務概念上是類似的.都是把?系列操作綁定成?組.讓這?組能夠批量執?. 但是注意體會Redis的事務和MySQL事務的區別: 弱化的原?性:redi…

CppCon 2018 學習:An allocator is a handle to a heap Lessons learned from std::pmr

“An allocator is a handle to a heap — Lessons learned from std::pmr” 翻譯過來就是&#xff1a;“分配器&#xff08;allocator&#xff09;是對堆&#xff08;heap&#xff09;的一種句柄&#xff08;handle&#xff09;——從 std::pmr 中學到的經驗”。 基礎概念 分…

設備健康實時監測方法演進:從傳感網絡到AI決策樹的工業智能實踐

引言&#xff1a;當設備運維遇上AIoT革命 在工業4.0進程中&#xff0c;?毫秒級設備狀態捕獲能力正成為智能工廠的核心競爭力。傳統監測方法因數據滯后、診斷粗放被詬病&#xff0c;本文將深入探討三大前沿實時監測技術路徑&#xff0c;并揭秘中訊燭龍系統如何通過深度強化學習…