如何在Dart/Flutter中结合GetIt包实现装饰器模式?
在Flutter中用get_it实现装饰器模式
一、Dart中装饰器模式的实现结构
Dart没有专门的interface关键字,但可以用**抽象类(abstract class)**定义核心契约,作用和C#的interface完全一致:
- 抽象组件:定义抽象类,声明业务核心方法
- 具体组件:继承抽象类,实现核心方法的基础逻辑
- 装饰器类:同样继承抽象类,内部持有抽象组件的实例,在调用核心方法的前后添加额外功能
举个日志服务的实现示例:
// 抽象组件(对应C#的interface) abstract class Logger { void log(String message); } // 具体组件:基础控制台日志实现 class ConsoleLogger implements Logger { @override void log(String message) { print('Console: $message'); } } // 装饰器1:给日志添加时间戳 class TimestampLoggerDecorator implements Logger { final Logger _logger; TimestampLoggerDecorator(this._logger); @override void log(String message) { final timestamp = DateTime.now().toIso8601String(); _logger.log('[$timestamp] $message'); } } // 装饰器2:给日志添加错误标记 class ErrorLoggerDecorator implements Logger { final Logger _logger; ErrorLoggerDecorator(this._logger); @override void log(String message) { _logger.log('[ERROR] $message'); } }
二、结合get_it实现服务的装饰注册
get_it没有像Scrutor那样的内置装饰注册方法,需要手动构建依赖链:
- 先注册原始的基础服务实例
- 注册装饰后的服务时,从get_it中获取原始服务,注入到装饰器中
基础注册示例
import 'package:get_it/get_it.dart'; final getIt = GetIt.instance; void setupLocator() { // 1. 注册基础服务 getIt.registerSingleton<Logger>(ConsoleLogger()); // 2. 注册带时间戳的装饰版服务(用实例名区分不同版本) getIt.registerSingleton<Logger>( TimestampLoggerDecorator(getIt<Logger>()), instanceName: 'timestampLogger', ); // 叠加多个装饰器:错误标记+时间戳 getIt.registerSingleton<Logger>( ErrorLoggerDecorator(TimestampLoggerDecorator(getIt<Logger>())), instanceName: 'errorTimestampLogger', ); } // 使用示例 void main() { setupLocator(); // 获取基础日志 final basicLogger = getIt<Logger>(); basicLogger.log('Hello'); // 输出: Console: Hello // 获取带时间戳的日志 final timestampLogger = getIt<Logger>(instanceName: 'timestampLogger'); timestampLogger.log('Hello'); // 输出: Console: [2024-05-20T12:34:56.789] Hello // 获取带错误标记+时间戳的日志 final errorLogger = getIt<Logger>(instanceName: 'errorTimestampLogger'); errorLogger.log('Something went wrong'); // 输出: Console: [2024-05-20T12:34:56.789] [ERROR] Something went wrong }
默认返回装饰后服务的方式
如果希望默认获取的Logger就是装饰后的版本,可以覆盖原始注册:
void setupLocator() { // 先注册基础服务(用lazySingleton延迟加载更高效) getIt.registerLazySingleton<Logger>(() => ConsoleLogger()); // 覆盖默认的Logger注册,返回装饰后的实例 getIt.registerSingleton<Logger>( TimestampLoggerDecorator(getIt<Logger>()), overrideExisting: true, ); }
内容的提问来源于stack exchange,提问作者Batesias
相关产品推荐
相关产品推荐

