发布于2026-07-17 阅读(0)
扫一扫,手机访问
聊到策略模式,很多人第一反应就是拿一堆 if-else 配上接口硬凑,结果代码越写越臃肿。其实核心就一句话:让策略契约足够窄、足够具体。否则你很快就会陷入“这个策略要传 IDictionary,那个要 CancellationToken,第三个还得返回 Task”的泥潭——最后只能用泛型堆砌或 object 强转,反而更难维护。

IStrategy空接口最大的问题是没有任何行为约束——后续全靠注释和人肉约定。新加一个策略类时,没人知道它该接受什么输入、返回什么结果、是否异步、要不要重试。一上线就崩,太常见了。
IChargeProcessor,而不是笼统的 IPaymentStrategy。这样每个策略的职责一眼就能看清。Dictionary手动维护字典看似简单,但一接入多租户、插件热加载或需要生命周期管理(比如 Scoped 策略),立刻就出问题:服务没注册、Key 写错没提示、作用域错乱、重复注册——调试起来头大。
AddTransient() ,配合 [StrategyName("alipay")] 这类元数据标记,比字符串 Key 更安全,编译阶段就能发现问题。GetService() ,要用 GetServices() 拿全部,再按需筛选。这样扩展新策略时不用改任何注册代码。IServiceScope(比如要访问 Scoped 服务),确保调用方自己创建 scope,别在策略内部 new 一个 scope 出来——否则生命周期管理就失控了。InvalidOperationException: No service for type 'X' has been registered 怎么快速定位这个错误其实不是策略类写错了,而是 DI 配置断在某一层。要么策略本身没注册,要么它依赖的某个服务(比如 IHttpClientFactory 或 IOptions)漏注册,或者生命周期不匹配(比如 Transient 策略注入了 Singleton 服务,而该服务又依赖 Scoped 服务——这种连环坑很隐蔽)。
Program.cs 里显式注册过。别偷懒用隐式注册,显式注册一目了然。IOptions、IConfiguration 这类“看起来自带”的服务——很多人以为它们默认可用,其实必须显式调用 AddOptions() 或 Configure() 。ServiceProvider.GetService>() 打印所有已注册策略,检查有没有漏掉的实现类。这个方法比猜快得多。策略最难的从来不是写几个类,而是划清边界:哪些该进策略、哪些该由上下文传入、哪些该交给中间件兜底。一旦把“共享 HttpClient”“读配置”“记录耗时”全塞进策略执行方法里,策略就不再是策略,而是大杂烩——维护成本翻倍,谁也救不了。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8