当前位置: 首页 > news >正文

中介者模式 - Flutter中的通信指挥中心,告别组件间混乱对话!

痛点场景:订单页面的组件纠缠

假设你正在开发一个外卖订单页面,包含:

  • 地址选择器
  • 优惠券选择器
  • 支付方式选择
  • 商品列表
  • 提交按钮

这些组件需要相互通信:

  1. 选择地址 → 更新运费 → 刷新总价
  2. 选择优惠券 → 校验是否适用于当前商品 → 更新折扣 → 刷新总价
  3. 切换支付方式 → 检查是否支持优惠券 → 更新按钮状态
  4. 修改商品数量 → 检查库存 → 更新优惠券可用性

传统实现方式(直接引用地狱):

class AddressPicker {final CouponPicker couponPicker;final PaymentPicker paymentPicker;final ProductList productList;final SubmitButton submitButton;void onAddressSelected() {// 更新运费逻辑...productList.updateShippingFee();couponPicker.checkApplicability();paymentPicker.validate();submitButton.refresh();}
}
// 其他组件也有类似的交叉引用...

问题爆发点:

  • 🕸️ 组件间形成蜘蛛网般的耦合
  • 💥 修改一个组件会影响多个其他组件
  • 🔥 难以单独测试某个组件
  • 🌋 添加新组件需要修改大量现有代码

中介者模式解决方案

核心思想: 用一个中介对象封装一系列对象之间的交互,使各对象不需要显式相互引用,从而使其耦合松散。

四个关键角色:

  1. 中介者接口(Mediator): 定义通信接口
  2. 具体中介者(ConcreteMediator): 协调各组件交互
  3. 同事类(Colleague): 需要通信的组件
  4. 同事接口(Colleague): 定义组件通用接口(可选)

Flutter订单中介者实现

1. 定义中介者接口
abstract class OrderMediator {void addressChanged(Address newAddress);void couponSelected(Coupon? coupon);void paymentMethodChanged(PaymentMethod method);void productQuantityChanged(Product product, int quantity);
}
2. 实现具体中介者
class OrderController implements OrderMediator {final AddressPicker _addressPicker;final CouponPicker _couponPicker;final PaymentPicker _paymentPicker;final ProductList _productList;final SubmitButton _submitButton;OrderController({required AddressPicker addressPicker,required CouponPicker couponPicker,// 其他组件...}) : _addressPicker = addressPicker,_couponPicker = couponPicker,// 初始化其他组件...{// 设置组件的中介者引用_addressPicker.mediator = this;_couponPicker.mediator = this;// ...}void addressChanged(Address newAddress) {final shippingFee = _calculateShippingFee(newAddress);_productList.updateShippingFee(shippingFee);_couponPicker.checkApplicability();_submitButton.refresh();}void couponSelected(Coupon? coupon) {if (coupon != null && !_productList.isCouponApplicable(coupon)) {_couponPicker.showError('此优惠券不适用于当前商品');return;}_paymentPicker.validateCoupon(coupon);_productList.applyCoupon(coupon);_submitButton.refresh();}void paymentMethodChanged(PaymentMethod method) {if (!method.supportsCoupons && _couponPicker.selectedCoupon != null) {_couponPicker.clearSelection();_productList.removeCoupon();}_submitButton.refresh();}void productQuantityChanged(Product product, int quantity) {_couponPicker.checkApplicability();_paymentPicker.validate();_submitButton.refresh();}
}
3. 创建同事类(组件)
abstract class OrderComponent {OrderMediator? mediator;
}class AddressPicker extends StatefulWidget implements OrderComponent {OrderMediator? mediator;_AddressPickerState createState() => _AddressPickerState();
}class _AddressPickerState extends State<AddressPicker> {Address? _selectedAddress;void _handleAddressChange(Address newAddress) {setState(() => _selectedAddress = newAddress);widget.mediator?.addressChanged(newAddress);}Widget build(BuildContext context) {return DropdownButton<Address>(value: _selectedAddress,items: _buildAddressItems(),onChanged: _handleAddressChange,);}
}// 其他组件类似实现...
4. 在页面中组装
class OrderPage extends StatefulWidget {_OrderPageState createState() => _OrderPageState();
}class _OrderPageState extends State<OrderPage> {late final OrderMediator _mediator;void initState() {super.initState();final addressPicker = AddressPicker();final couponPicker = CouponPicker();// 初始化其他组件..._mediator = OrderController(addressPicker: addressPicker,couponPicker: couponPicker,// 注入其他组件...);}Widget build(BuildContext context) {return Scaffold(body: Column(children: [AddressPicker(mediator: _mediator),CouponPicker(mediator: _mediator),PaymentPicker(mediator: _mediator),ProductList(mediator: _mediator),SubmitButton(mediator: _mediator),],),);}
}

Flutter中的实际应用场景

场景1:聊天室系统
// 中介者
class ChatRoom implements ChatMediator {final List<User> _users = [];void register(User user) {_users.add(user);}void sendMessage(String message, User sender) {for (final user in _users) {if (user != sender) {user.receive(message);}}}
}// 同事类
class User {final String name;final ChatMediator mediator;User(this.name, this.mediator);void send(String message) {print('$name 发送: $message');mediator.sendMessage(message, this);}void receive(String message) {print('$name 收到: $message');}
}// 使用
final chatRoom = ChatRoom();
final john = User('John', chatRoom);
final jane = User('Jane', chatRoom);
chatRoom.register(john);
chatRoom.register(jane);john.send('Hi there!');  // Jane会收到
jane.send('Hello!');     // John会收到
场景2:表单验证系统
// 中介者
class FormValidator implements FormMediator {final List<FormField> _fields = [];void registerField(FormField field) {_fields.add(field);}void validateAll() {bool isValid = true;for (final field in _fields) {if (!field.validate()) {isValid = false;}}submitButton.setEnabled(isValid);}
}// 同事类
class EmailField extends StatefulWidget implements FormField {FormMediator? mediator;bool validate() {// 验证逻辑...mediator?.validateAll();}
}// 在表单中使用
final validator = FormValidator();
EmailField(mediator: validator),
PasswordField(mediator: validator),
SubmitButton(mediator: validator),
场景3:电商筛选系统
// 中介者
class FilterMediator {final List<FilterWidget> _filters = [];ProductList? _productList;void registerFilter(FilterWidget filter) {_filters.add(filter);}void registerProductList(ProductList list) {_productList = list;}void onFilterChanged() {final filters = _filters.map((f) => f.currentFilter).toList();_productList?.applyFilters(filters);}
}// 使用
final mediator = FilterMediator();
ColorFilter(mediator: mediator),
PriceFilter(mediator: mediator),
BrandFilter(mediator: mediator),
ProductList(mediator: mediator),

中介者模式与状态管理的结合

将中介者与Provider结合:

// 中介者提供者
class OrderMediatorProvider extends ChangeNotifier {final OrderMediator _mediator;OrderMediatorProvider(this._mediator);OrderMediator get mediator => _mediator;
}// 顶层注册
void main() {final addressPicker = AddressPicker();final mediator = OrderController(addressPicker: addressPicker);runApp(MultiProvider(providers: [ChangeNotifierProvider(create: (_) => OrderMediatorProvider(mediator)),],child: MyApp(),),);
}// 在组件中使用
Consumer<OrderMediatorProvider>(builder: (context, provider, child) {return AddressPicker(mediator: provider.mediator);}
)

中介者模式最佳实践

  1. 何时使用中介者模式:

    • 系统中有大量对象需要相互通信
    • 对象间引用关系复杂难以理解
    • 想定制分布在多个类中的行为又不想生成太多子类
    • 通信逻辑需要集中管理
  2. Flutter特化技巧:

    // 使用事件总线增强中介者
    class EventBusMediator implements OrderMediator {final EventBus _bus;EventBusMediator(this._bus);void addressChanged(Address newAddress) {_bus.fire(AddressChangedEvent(newAddress));}
    }// 组件监听事件
    _bus.on<AddressChangedEvent>().listen((e) {// 处理地址变更
    });
    
  3. 性能优化:

    // 懒加载中介者
    class LazyMediator implements OrderMediator {OrderController? _controller;void addressChanged(Address newAddress) {_controller ??= OrderController(...);_controller!.addressChanged(newAddress);}
    }
    
  4. 测试策略:

    test('地址变更应更新运费', () {final mediator = MockOrderMediator();final addressPicker = AddressPicker(mediator: mediator);addressPicker.selectAddress(testAddress);verify(mediator.addressChanged(testAddress));
    });
    

中介者模式 vs 观察者模式

特性中介者模式观察者模式
目的集中管理对象间通信一对多的依赖通知
耦合度同事类只认识中介者观察者直接订阅被观察者
通信方向可以是双向或多向通常是被观察者→观察者
典型应用复杂UI交互、表单系统状态管理、事件处理

中介者模式的高级变体

1. 分层中介者
class GlobalMediator {final List<DomainMediator> _domainMediators = [];void registerDomain(DomainMediator mediator) {_domainMediators.add(mediator);}void notifyAll(String globalEvent) {for (final mediator in _domainMediators) {mediator.handleGlobalEvent(globalEvent);}}
}class OrderMediator implements DomainMediator {void handleGlobalEvent(String event) {if (event == 'USER_LOGGED_OUT') {// 清理订单数据...}}
}
2. 中介者+命令模式
abstract class MediatorCommand {void execute(OrderMediator mediator);
}class AddressChangeCommand implements MediatorCommand {final Address newAddress;AddressChangeCommand(this.newAddress);void execute(OrderMediator mediator) {mediator.addressChanged(newAddress);}
}// 在组件中使用
void _handleAddressChange(Address newAddress) {final command = AddressChangeCommand(newAddress);command.execute(widget.mediator);
}

总结:中介者模式是你的通信枢纽

  • 核心价值: 将网状通信结构变为星型结构,降低系统复杂度
  • Flutter优势:
    • 解耦UI组件
    • 集中管理业务逻辑
    • 简化组件测试
    • 提高代码可维护性
  • 适用场景: 复杂表单、电商筛选、聊天系统、多步骤流程

🎛️ 设计启示: 当你发现Flutter组件间有复杂的交叉调用时,中介者模式能帮你理清通信脉络!

http://www.lryc.cn/news/577028.html

相关文章:

  • 怎样学习STM32
  • Springboot 集成 SpringBatch 批处理组件
  • 2.安装Docker
  • 力扣第87题-扰乱字符串
  • 如何通过自动化减少重复性工作
  • Vue中的v-if与emit事件传递:一个常见陷阱分析
  • 推荐几本关于网络安全的书
  • FastAPI+Sqlite+HTML的登录注册与文件上传系统:完整实现指南
  • 6月28日记
  • Re:从0开始的 空闲磁盘块管理(考研向)
  • H3C-路由器交换机-中继
  • 用户行为序列建模(篇六)-【阿里】DSIN
  • DeepSeek五子棋游戏与AI对战
  • 【unity游戏开发——网络】网络游戏通信方案——强联网游戏(Socket长连接)、 弱联网游戏(HTTP短连接)
  • WebRTC(十三):信令服务器
  • Qt Windows下编译动态库生成的.a文件是什么?
  • 新生代潜力股刘小北:演艺路上的璀璨新星
  • Function Calling与MCP的区别
  • Ubuntu开放mysql 3306端口
  • X-Search:Spring AI实现的AI智能搜索
  • SpringMVC实战:从配置到JSON处理全解析
  • AlphaFold3安装报错
  • SpringCloud系列(40)--SpringCloud Gateway的Filter的简介及使用
  • cron 表达式 0 10 0/2 * * ? 的含义
  • Linux基本命令篇 —— head命令
  • 5 c++核心——文件操作
  • Origin绘制复合子母饼状图—复合柱饼图、复合环饼图及复合饼图
  • [Linux] PXE
  • es6特性-第一部分
  • Tomcat 安装使用教程