如何使用工厂方法消除FTP类型处理逻辑中的大量if else分支
重构思路
将不同ftpType对应的差异化处理逻辑封装为独立的处理器类,通过工厂类根据ftpType动态匹配对应的处理器实例,彻底消除if/else分支,新增平台时仅需新增处理器实现即可,完全符合开闭原则。
具体实现步骤
1. 定义公共处理器接口
抽象所有平台的公共处理动作:
public interface IFtpMetadataProcessor { void Process(string metadataJson, IFtpDeliveryQueue ftpDeliveryQueue); }
如果原项目中没有对ftpDeliveryQueue做接口抽象,也可以直接替换为实际的队列类型
2. 实现各平台独立处理器
每个平台单独维护自身的反序列化、请求构造逻辑,互不干扰:
YouTube平台处理器
public class YoutubeMetadataProcessor : IFtpMetadataProcessor { public void Process(string metadataJson, IFtpDeliveryQueue ftpDeliveryQueue) { var digitalServiceResponse = JsonConvert.DeserializeObject<YoutubeMetadataResponse>(metadataJson); var fileRequest = new AddDeliveryFileRequest { // 原YouTube业务对应的构造逻辑 }; ftpDeliveryQueue.AddFile(fileRequest); } }
Flashtalking平台处理器
public class FlashtalkingMetadataProcessor : IFtpMetadataProcessor { public void Process(string metadataJson, IFtpDeliveryQueue ftpDeliveryQueue) { var metadata = JsonConvert.DeserializeObject<FlashtalkingMetadataResponse>(metadataJson); foreach (var file in metadata.FileList) { var fileRequest = new AddDeliveryFileRequest { // 原Flashtalking业务对应的构造逻辑 }; ftpDeliveryQueue.AddFile(fileRequest); } } }
Innovid平台处理器
public class InnovidMetadataProcessor : IFtpMetadataProcessor { public void Process(string metadataJson, IFtpDeliveryQueue ftpDeliveryQueue) { var metadata = JsonConvert.DeserializeObject<InnovidMetadataResponse>(metadataJson); foreach (var file in metadata.FileList) { var fileRequest = new AddDeliveryFileRequest { // 原Innovid业务对应的构造逻辑 }; ftpDeliveryQueue.AddFile(fileRequest); } } }
Sizmek平台处理器
public class SizmekMetadataProcessor : IFtpMetadataProcessor { public void Process(string metadataJson, IFtpDeliveryQueue ftpDeliveryQueue) { var digitalServiceResponse = JsonConvert.DeserializeObject<SizmekMetadataResponse>(metadataJson); foreach (var file in digitalServiceResponse.Metadata.FileList) { var fileRequest = new AddDeliveryFileRequest { // 原Sizmek业务对应的构造逻辑 }; ftpDeliveryQueue.AddFile(fileRequest); } } }
3. 实现工厂类
通过字典维护ftpType与处理器的映射关系,实现动态匹配:
public static class FtpMetadataProcessorFactory { // 忽略大小写匹配,兼容不同格式的ftpType输入 private static readonly Dictionary<string, IFtpMetadataProcessor> _processorMap = new Dictionary<string, IFtpMetadataProcessor>(StringComparer.OrdinalIgnoreCase) { { "YouTube", new YoutubeMetadataProcessor() }, { "Flashtalking", new FlashtalkingMetadataProcessor() }, { "Innovid", new InnovidMetadataProcessor() }, { "Sizmek", new SizmekMetadataProcessor() } }; public static IFtpMetadataProcessor GetProcessor(string ftpType) { // 保留原逻辑默认走Sizmek的规则可替换为: // return _processorMap.TryGetValue(ftpType, out var processor) ? processor : _processorMap["Sizmek"]; if (_processorMap.TryGetValue(ftpType, out var processor)) { return processor; } throw new NotSupportedException($"不支持的ftp类型:{ftpType}"); } }
如果项目使用依赖注入框架,可将所有处理器注册到容器中,工厂类直接从容器获取实例即可,无需手动维护实例创建
4. 重构原业务代码
原来的多分支if/else逻辑直接简化为两行:
var processor = FtpMetadataProcessorFactory.GetProcessor(ftpType); processor.Process(metadataJson, ftpDeliveryQueue);
重构收益
- 彻底消除冗余分支,代码可读性大幅提升
- 新增平台仅需新增
IFtpMetadataProcessor实现类,在工厂映射字典中加一行注册即可,无需修改原有业务逻辑 - 各平台处理逻辑完全解耦,单个平台逻辑调整不会影响其他平台,也方便单独编写单元测试
内容的提问来源于stack exchange,提问作者Fakhar Ahmad Rasul
相关产品推荐
相关产品推荐

