如何根据参数返回对应类型对象?优化可扩展的对象创建逻辑
解决车辆处理器工厂的if语句冗余与自动扩展问题
可以通过自定义特性+反射缓存的方式实现,完全摆脱大量if/switch判断,同时满足新增类型时仅需添加枚举值和对应处理器类的需求,还能解决你提到的接口无法强制静态属性的问题。
实现步骤
1. 定义自定义特性,标记处理器对应车辆类型
用特性绑定处理器类与VehicleType枚举,替代静态属性方案,既能明确映射关系,又能在扫描时强制约束每个处理器必须声明对应类型:
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] public class VehicleProcessorAttribute : Attribute { public VehicleType VehicleType { get; } public VehicleProcessorAttribute(VehicleType vehicleType) { VehicleType = vehicleType; } }
2. 给每个处理器类添加特性标记
所有实现IVehicleProcessor的类都必须加上该特性,明确对应的车辆类型:
[VehicleProcessor(VehicleType.Car)] public class CarProcessor : IVehicleProcessor { public CarProcessor(string regNo) { // 构造逻辑 } } [VehicleProcessor(VehicleType.Van)] public class VanProcessor : IVehicleProcessor { public VanProcessor(string regNo) { // 构造逻辑 } }
3. 构建工厂类,通过反射缓存映射关系
在工厂类的静态构造函数中,扫描所有IVehicleProcessor实现类,建立VehicleType到处理器类型的缓存映射,后续直接从缓存获取实例:
public static class VehicleProcessorFactory { private static readonly Dictionary<VehicleType, Type> _processorMap; static VehicleProcessorFactory() { _processorMap = new Dictionary<VehicleType, Type>(); // 扫描当前程序集中所有IVehicleProcessor的实现类(若处理器在其他项目,需替换为对应程序集) var processorTypes = typeof(IVehicleProcessor).Assembly.GetTypes() .Where(t => typeof(IVehicleProcessor).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract); foreach (var type in processorTypes) { var attr = type.GetCustomAttribute<VehicleProcessorAttribute>(); if (attr == null) { throw new InvalidOperationException($"处理器类 {type.Name} 未标记VehicleProcessorAttribute"); } if (_processorMap.ContainsKey(attr.VehicleType)) { throw new InvalidOperationException($"已存在对应 {attr.VehicleType} 的处理器类"); } _processorMap[attr.VehicleType] = type; } } public static IVehicleProcessor GetVehicle(VehicleType vehicleType, string regNo) { if (_processorMap.TryGetValue(vehicleType, out var processorType)) { // 通过反射调用带regNo参数的构造函数实例化 return (IVehicleProcessor)Activator.CreateInstance(processorType, regNo); } // 可根据业务需求返回null或抛出异常 throw new ArgumentOutOfRangeException(nameof(vehicleType), $"未找到对应 {vehicleType} 的处理器"); } }
解决你的核心疑问
你之前考虑用接口属性但无法在实例化前访问,静态属性又不能被接口强制约束的问题,用自定义特性完美解决:
- 特性是类的元数据,无需实例化就能通过反射获取,满足工厂在创建实例前的映射需求;
- 在扫描时可以检查每个处理器类是否标记了特性,相当于强制约束所有处理器必须声明对应车辆类型,比静态属性更可靠。
扩展支持
新增Bus类型时,只需两步:
- 在
VehicleType枚举中添加Bus; - 创建
BusProcessor : IVehicleProcessor并标记[VehicleProcessor(VehicleType.Bus)]。
工厂类会自动扫描到新的处理器,无需修改GetVehicle方法。
如果项目使用依赖注入框架(如Autofac、Microsoft DI),还可以进一步优化:将处理器注册到容器时附带VehicleType元数据,工厂从容器中解析实例,支持构造函数注入其他依赖,替代Activator.CreateInstance的方式。
内容的提问来源于stack exchange,提问作者komodosp
相关产品推荐
相关产品推荐

