假设你正在开发一个电商App,需要支持多种支付方式:
void processPayment(String method, double amount) {
if (method == 'alipay') {
print('调用支付宝SDK,支付¥$amount');
// 支付宝特定逻辑...
} else if (method == 'wechat') {
print('调用微信支付SDK,支付¥$amount');
// 微信特定逻辑...
} else if (method == 'creditCard') {
print('调用银联接口,支付¥$amount');
// 信用卡验证逻辑...
} else if (method == 'applePay') {
print('调用Apple Pay API,支付¥$amount');
// Apple Pay特定配置...
}
// 未来新增支付方式还要修改这里...
}
问题爆发点:
核心思想: 定义一系列算法,将每个算法封装起来,并使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户端。
三个关键角色:
abstract class PaymentStrategy {
Future<bool> pay(double amount);
String get name;
Widget get icon;
}
// 支付宝策略
class AlipayStrategy implements PaymentStrategy {
String get name => '支付宝';
Widget get icon => Icon(Icons.payment, color: Colors.blue);
Future<bool> pay(double amount) async {
print('调用支付宝SDK,支付¥$amount');
// 实际调用支付宝插件...
await Future.delayed(Duration(seconds: 1));
return true; // 模拟支付成功
}
}
// 微信支付策略
class WechatPayStrategy implements PaymentStrategy {
String get name => '微信支付';
Widget get icon => Icon(Icons.wechat, color: Colors.green);
Future<bool> pay(double amount) async {
print('调用微信支付SDK,支付¥$amount');
// 实际调用微信插件...
await Future.delayed(Duration(seconds: 1));
return true;
}
}
// 信用卡策略
class CreditCardStrategy implements PaymentStrategy {
final String cardNumber;
final String cvv;
CreditCardStrategy(this.cardNumber, this.cvv);
String get name => '信用卡';
Widget get icon => Icon(Icons.credit_card, color: Colors.indigo);
Future<bool> pay(double amount) async {
print('验证信用卡$cardNumber,支付¥$amount');
// 验证逻辑...
if (cardNumber.isEmpty || cvv.isEmpty) return false;
await Future.delayed(Duration(seconds: 2));
return true;
}
}
class PaymentContext {
PaymentStrategy? _strategy;
void setStrategy(PaymentStrategy strategy) {
_strategy = strategy;
}
Future<bool> executePayment(double amount) async {
if (_strategy == null) throw Exception('请先设置支付策略');
return await _strategy!.pay(amount);
}
Widget? get strategyIcon => _strategy?.icon;
String? get strategyName => _strategy?.name;
}
class PaymentPage extends StatefulWidget {
_PaymentPageState createState() => _PaymentPageState();
}
class _PaymentPageState extends State<PaymentPage> {
final PaymentContext _paymentContext = PaymentContext();
double _amount = 99.99;
PaymentStrategy? _selectedStrategy;
final List<PaymentStrategy> _strategies = [
AlipayStrategy(),
WechatPayStrategy(),
CreditCardStrategy('4111111111111111', '123'),
];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('选择支付方式')),
body: Column(
children: [
// 金额显示
Text('¥$_amount', style: TextStyle(fontSize: 24)),
// 策略选择列表
..._strategies.map((strategy) => RadioListTile<PaymentStrategy>(
title: Row(children: [
strategy.icon,
SizedBox(width: 10),
Text(strategy.name),
]),
value: strategy,
groupValue: _selectedStrategy,
onChanged: (value) => setState(() {
_selectedStrategy = value;
_paymentContext.setStrategy(value!);
}),
)),
// 支付按钮
ElevatedButton(
onPressed: _selectedStrategy == null ? null : _handlePayment,
child: Text('立即支付'),
),
],
),
);
}
Future<void> _handlePayment() async {
final success = await _paymentContext.executePayment(_amount);
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text(success ? '支付成功' : '支付失败'),
content: Text('${_paymentContext.strategyName} ¥$_amount'),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx),
child: Text('确定'),
),
],
),
);
}
}
// 排序策略接口
abstract class SortStrategy {
List<Product> sort(List<Product> items);
}
// 价格升序策略
class PriceAscSort implements SortStrategy {
List<Product> sort(List<Product> items) {
return List.from(items)..sort((a, b) => a.price.compareTo(b.price));
}
}
// 销量降序策略
class SalesDescSort implements SortStrategy {
List<Product> sort(List<Product> items) {
return List.from(items)..sort((a, b) => b.sales.compareTo(a.sales));
}
}
// 在商品列表中使用
class ProductList extends StatelessWidget {
final SortStrategy sortStrategy;
final List<Product> products;
ProductList({required this.sortStrategy, required this.products});
Widget build(BuildContext context) {
final sortedProducts = sortStrategy.sort(products);
return ListView.builder(
itemCount: sortedProducts.length,
itemBuilder: (ctx, i) => ProductItem(sortedProducts[i]),
);
}
}
// 切换排序方式
ProductList(
sortStrategy: _isPriceSort ? PriceAscSort() : SalesDescSort(),
products: _products,
)
// 导航策略接口
abstract class NavigationStrategy {
Route planRoute(Location start, Location end);
}
// 驾车策略
class DrivingStrategy implements NavigationStrategy {
Route planRoute(Location start, Location end) {
print('计算驾车路线:$start -> $end');
// 调用驾车路线API...
return Route(/*...*/);
}
}
// 步行策略
class WalkingStrategy implements NavigationStrategy {
Route planRoute(Location start, Location end) {
print('计算步行路线:$start -> $end');
// 调用步行路线API...
return Route(/*...*/);
}
}
// 导航上下文
class NavigatorContext {
NavigationStrategy _strategy = DrivingStrategy(); // 默认驾车
void setStrategy(NavigationStrategy strategy) {
_strategy = strategy;
}
void navigate(Location start, Location end) {
final route = _strategy.planRoute(start, end);
_displayRoute(route);
}
}
// 缓存策略接口
abstract class CacheStrategy {
Future<String?> get(String key);
Future<void> set(String key, String value);
}
// 内存缓存
class MemoryCache implements CacheStrategy {
final Map<String, String> _cache = {};
Future<String?> get(String key) async => _cache[key];
Future<void> set(String key, String value) async {
_cache[key] = value;
}
}
// 本地存储缓存
class LocalStorageCache implements CacheStrategy {
Future<String?> get(String key) async {
return await SharedPreferences.getInstance()
.then((prefs) => prefs.getString(key));
}
Future<void> set(String key, String value) async {
await SharedPreferences.getInstance()
.then((prefs) => prefs.setString(key, value));
}
}
// 在数据仓库中使用
class UserRepository {
final CacheStrategy _cacheStrategy;
UserRepository({CacheStrategy? cache})
: _cacheStrategy = cache ?? MemoryCache();
Future<User> fetchUser(String id) async {
final cached = await _cacheStrategy.get('user_$id');
if (cached != null) return User.fromJson(cached);
// 从网络获取...
final user = await api.getUser(id);
await _cacheStrategy.set('user_$id', user.toJson());
return user;
}
}
将策略模式与Provider结合实现动态主题切换:
// 主题策略接口
abstract class ThemeStrategy {
ThemeData get themeData;
Color get primaryColor;
}
// 明亮主题策略
class LightThemeStrategy implements ThemeStrategy {
ThemeData get themeData => ThemeData.light();
Color get primaryColor => Colors.blue;
}
// 暗黑主题策略
class DarkThemeStrategy implements ThemeStrategy {
ThemeData get themeData => ThemeData.dark();
Color get primaryColor => Colors.blueGrey;
}
// 主题策略提供者
class ThemeProvider extends ChangeNotifier {
ThemeStrategy _currentStrategy = LightThemeStrategy();
ThemeStrategy get currentStrategy => _currentStrategy;
void toggleTheme() {
_currentStrategy = _currentStrategy is LightThemeStrategy
? DarkThemeStrategy()
: LightThemeStrategy();
notifyListeners();
}
}
// 在MaterialApp中使用
MaterialApp(
theme: context.watch<ThemeProvider>().currentStrategy.themeData,
// ...
)
// 切换主题
context.read<ThemeProvider>().toggleTheme();
何时使用策略模式:
Flutter特化技巧:
// 使用策略工厂简化创建
class StrategyFactory {
static PaymentStrategy create(String type) {
switch(type) {
case 'alipay': return AlipayStrategy();
case 'wechat': return WechatPayStrategy();
default: throw Exception('未知策略类型');
}
}
}
// 策略组合
class CompositeStrategy implements PaymentStrategy {
final List<PaymentStrategy> _strategies;
CompositeStrategy(this._strategies);
Future<bool> pay(double amount) async {
for (final strategy in _strategies) {
final success = await strategy.pay(amount);
if (!success) return false;
}
return true;
}
}
性能优化:
// 缓存策略实例
class StrategyCache {
static final Map<Type, PaymentStrategy> _cache = {};
static T getStrategy<T extends PaymentStrategy>(T Function() create) {
if (!_cache.containsKey(T)) {
_cache[T] = create();
}
return _cache[T] as T;
}
}
// 使用缓存策略
final strategy = StrategyCache.getStrategy(() => AlipayStrategy());
测试策略:
void main() {
test('Alipay策略测试', () async {
final strategy = AlipayStrategy();
final result = await strategy.pay(100);
expect(result, isTrue);
});
test('信用卡策略验证失败测试', () async {
final strategy = CreditCardStrategy('', ''); // 无效卡号
final result = await strategy.pay(100);
expect(result, isFalse);
});
}
特性 | 策略模式 | 状态模式 |
---|---|---|
目的 | 封装可互换的算法 | 管理状态相关行为 |
知晓性 | 策略相互独立 | 状态知道其他状态 |
变化触发 | 客户端主动设置策略 | 状态自动转换 |
典型应用 | 支付方式、排序算法 | 订单状态、播放器控制 |
abstract class Strategy {
Widget buildButton(VoidCallback onPressed);
}
class PrimaryStrategy implements Strategy {
Widget buildButton(VoidCallback onPressed) {
return ElevatedButton(onPressed: onPressed, child: Text('Primary'));
}
}
class StrategyFactory {
static Strategy create(String type) {
switch(type) {
case 'primary': return PrimaryStrategy();
case 'outlined': return OutlinedStrategy();
default: throw Exception('未知策略');
}
}
}
// 使用
StrategyFactory.create('primary').buildButton(() {});
abstract class TextDecoratorStrategy {
String decorate(String text);
}
class BoldDecorator implements TextDecoratorStrategy {
String decorate(String text) => '**$text**';
}
class ItalicDecorator implements TextDecoratorStrategy {
String decorate(String text) => '*$text*';
}
class TextEditor {
final List<TextDecoratorStrategy> _strategies = [];
void addStrategy(TextDecoratorStrategy strategy) {
_strategies.add(strategy);
}
String process(String text) {
return _strategies.fold(text, (result, strategy) => strategy.decorate(result));
}
}
// 使用
final editor = TextEditor()
..addStrategy(BoldDecorator())
..addStrategy(ItalicDecorator());
print(editor.process('Hello')); // 输出:**_*Hello*_**
总结:策略模式是你的算法工具箱
� 设计启示: 当你在Flutter中发现需要根据不同条件执行相似但不同的操作时,策略模式能让你的代码更优雅!