工厂模式 - Flutter中的UI组件工厂,按需生产各种“产品

发布于:2025-07-01 ⋅ 阅读:(23) ⋅ 点赞:(0)

想要动态创建不同风格的按钮?想一键切换整个主题?工厂模式就是你的"生产流水线"!


想象一下这个场景:

你决定扩大奶茶店业务,推出两个品牌系列:

  1. 经典系列:传统珍珠奶茶,红白配色
  2. 清新系列:水果茶,蓝绿配色

每个系列都有自己风格的:

  • 杯子设计
  • 吸管样式
  • 包装袋
  • 会员卡

问题来了: 当顾客点单时,你如何确保:

  1. 经典系列的奶茶配经典杯+经典吸管+经典包装?
  2. 清新系列的水果茶配清新杯+清新吸管+清新包装?
  3. 避免经典杯配清新吸管这种"混搭事故"?

解决方案:建立两个专属工厂:

  • 经典工厂:专门生产经典杯、经典吸管、经典包装
  • 清新工厂:专门生产清新杯、清新吸管、清新包装

当顾客选择系列后,你只需告诉对应的工厂:"给我一套装备!"工厂就会返回风格一致的全套产品

在Flutter中,这就是"抽象工厂模式"!而"工厂方法模式"则是它的灵活简化版。


先理解基础:工厂方法模式 (Factory Method)

核心思想: 定义一个创建对象的接口,但让子类决定实例化哪个类。

Flutter场景: 根据条件创建不同类型的按钮

// 按钮产品接口
abstract class AppButton {
  Widget render(String text, VoidCallback onPressed);
}

// 具体产品1:圆角按钮
class RoundedButton implements AppButton {
  
  Widget render(String text, VoidCallback onPressed) {
    return ElevatedButton(
      style: ElevatedButton.styleFrom(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20),
      ),
      onPressed: onPressed,
      child: Text(text),
    );
  }
}

// 具体产品2:方形按钮
class SquareButton implements AppButton {
  
  Widget render(String text, VoidCallback onPressed) {
    return ElevatedButton(
      style: ElevatedButton.styleFrom(
        shape: const RoundedRectangleBorder(),
      ),
      onPressed: onPressed,
      child: Text(text),
    );
  }
}

// 工厂方法 - 根据主题创建按钮
class ButtonFactory {
  static AppButton createButton(ThemeType theme) {
    switch (theme) {
      case ThemeType.rounded:
        return RoundedButton();
      case ThemeType.square:
        return SquareButton();
      default:
        return RoundedButton();
    }
  }
}

// 使用示例:
final button = ButtonFactory.createButton(currentTheme);
button.render('确认', () => print('Clicked'));

优势:

  • 将对象创建和使用分离
  • 新增按钮类型时只需扩展工厂,不修改客户端代码
  • 统一创建接口

进阶:抽象工厂模式 (Abstract Factory)

核心思想: 提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。

Flutter场景: 创建整套UI主题组件

// 抽象工厂 - 能生产全套UI组件
abstract class ThemeFactory {
  AppButton createButton();
  AppCard createCard();
  AppTextField createTextField();
}

// 具体工厂1:生产经典主题组件
class ClassicThemeFactory implements ThemeFactory {
  
  AppButton createButton() => ClassicButton();
  
  
  AppCard createCard() => ClassicCard();
  
  
  AppTextField createTextField() => ClassicTextField();
}

// 具体工厂2:生产清新主题组件
class FreshThemeFactory implements ThemeFactory {
  
  AppButton createButton() => FreshButton();
  
  
  AppCard createCard() => FreshCard();
  
  
  AppTextField createTextField() => FreshTextField();
}

// 组件产品接口
abstract class AppButton {
  Widget render(String text);
}

abstract class AppCard {
  Widget render(Widget child);
}

abstract class AppTextField {
  Widget render(String hint);
}

// 具体产品实现(以经典系列为例)
class ClassicButton implements AppButton {
  
  Widget render(String text) => ElevatedButton(
    style: ElevatedButton.styleFrom(primary: Colors.red),
    onPressed: () {},
    child: Text(text),
  );
}

class ClassicCard implements AppCard {
  
  Widget render(Widget child) => Card(
    color: Colors.red[100],
    child: child,
  );
}

class ClassicTextField implements AppTextField {
  
  Widget render(String hint) => TextField(
    decoration: InputDecoration(
      hintText: hint,
      border: const OutlineInputBorder(),
    ),
  );
}

// 清新系列产品实现类似...

使用抽象工厂:

class ThemeSwitcher extends StatelessWidget {
  final ThemeFactory factory;
  
  const ThemeSwitcher({required this.factory});
  
  
  Widget build(BuildContext context) {
    return Column(
      children: [
        factory.createButton().render('提交'),
        const SizedBox(height: 20),
        factory.createCard().render(
          factory.createTextField().render('请输入')
        ),
      ],
    );
  }
}

// 在应用中使用
ThemeSwitcher(factory: ClassicThemeFactory()), // 经典主题
// 或
ThemeSwitcher(factory: FreshThemeFactory()),  // 清新主题

优势:

  1. 确保组件风格一致性(所有组件来自同一工厂)
  2. 切换主题只需更换工厂对象
  3. 新增主题系列不影响现有代码
  4. 产品创建细节对客户端隐藏

Flutter中的实际应用

  1. 主题管理系统
// 创建主题工厂
final factory = isDarkMode ? DarkThemeFactory() : LightThemeFactory();

// 使用主题组件
return factory.createCard().render(
  Column(
    children: [
      factory.createTextField().render('用户名'),
      factory.createButton().render('登录'),
    ],
  )
);
  1. 平台适配组件
abstract class PlatformWidgetsFactory {
  AppBar createAppBar(String title);
  Button createButton(String text);
}

class MaterialWidgetsFactory implements PlatformWidgetsFactory {
  
  AppBar createAppBar(String title) => AppBar(title: Text(title));
  
  
  Button createButton(String text) => ElevatedButton(...);
}

class CupertinoWidgetsFactory implements PlatformWidgetsFactory {
  
  AppBar createAppBar(String title) => CupertinoNavigationBar(middle: Text(title));
  
  
  Button createButton(String text) => CupertinoButton(...);
}

// 使用时
final factory = Platform.isIOS 
    ? CupertinoWidgetsFactory() 
    : MaterialWidgetsFactory();
    
return Scaffold(
  appBar: factory.createAppBar('首页'),
  body: factory.createButton('点击我'),
);
  1. 复杂对话框构建
abstract class DialogFactory {
  Widget createTitle(String text);
  Widget createContent(String text);
  Widget createActions(List<ActionItem> items);
}

class AlertDialogFactory implements DialogFactory { ... }
class BottomSheetDialogFactory implements DialogFactory { ... }
class FullscreenDialogFactory implements DialogFactory { ... }

工厂模式 vs 抽象工厂模式

特性 工厂方法模式 抽象工厂模式
创建对象 单个产品 产品家族
主要目的 类延迟实例化到子类 创建相关对象组
扩展性 添加新产品需修改工厂 添加新系列只需新工厂
Flutter典型应用 条件创建单一组件 主题系统/平台适配

最佳实践指南

  1. 何时使用工厂方法:

    • 需要创建单一类型对象
    • 创建过程需要封装
    • 需要运行时决定对象类型
    • 示例:根据用户类型创建不同的个人主页
  2. 何时使用抽象工厂:

    • 需要创建多个相关对象
    • 需要确保产品兼容性
    • 需要支持多套产品系列
    • 示例:主题系统、平台适配、A/B测试UI方案
  3. 工厂模式优势:

    • ✅ 解耦创建和使用
    • ✅ 符合开闭原则(扩展开放,修改关闭)
    • ✅ 简化复杂对象创建
    • ✅ 提高代码可测试性
  4. 需要注意:

    • 避免过度设计简单场景
    • 工厂类可能成为"上帝对象"
    • 新增产品类型可能需修改工厂接口

总结:工厂模式是你的UI流水线

  • 工厂方法:你的"专属定制工坊" - 根据需求生产特定类型产品
  • 抽象工厂:你的"主题生产线" - 一键产出风格一致的全套产品
  • 核心价值:创建逻辑和使用解耦,支持灵活扩展
  • Flutter应用:主题系统、平台适配、动态UI生成

💡 设计启示: 当你发现代码中有大量条件判断创建不同对象时,就是工厂模式的用武之地!


网站公告

今日签到

点亮在社区的每一天
去签到