多态正确运用与代码重构:PLC服务适配多机型需求
解决方案:用抽象基类+工厂模式替代静态类
静态类的核心问题是无法借助继承和多态实现代码复用与差异化逻辑分离,针对你的场景,抽象基类(或接口)+工厂模式是最优解——既能保留公共逻辑复用,又能优雅处理机型差异,具体步骤如下:
1. 定义抽象基类,拆分公共与可变逻辑
把原PLCService的所有操作方法抽象出来,将通用逻辑直接实现,需要按机型调整的方法标记为virtual(允许子类重写)或abstract(强制子类适配):
public abstract class BasePLCService { // 公共方法:所有机型通用的逻辑,直接实现 public bool Connect(string ip) { // 通用连接逻辑:建立TCP会话、初始化参数等 return true; } // 可变方法:Machine A和B有差异,默认用Machine A的实现 public virtual int ReadIntVariable(string address) { // Machine A的默认读取逻辑 return 0; } // 新增专属方法:仅Machine B需要,默认抛出异常提示 public virtual void SpecialBOnlyOperation() { throw new NotImplementedException("该操作仅支持Machine B"); } }
2. 为各机型实现子类
子类仅需重写有差异的方法,其余逻辑直接复用基类:
Machine A的实现(完全复用基类逻辑)
public class MachineAPLCService : BasePLCService { // 因所有方法与基类一致,无需额外重写 }
Machine B的实现(仅修改差异部分)
public class MachineBPLCService : BasePLCService { // 重写有差异的读取方法 public override int ReadIntVariable(string address) { // Machine B特有的读取逻辑:比如地址偏移、格式转换等 return 1; } // 实现Machine B专属操作 public override void SpecialBOnlyOperation() { // Machine B专属业务逻辑 } }
3. 用工厂类根据机型创建实例
创建工厂类,负责读取INI的机型配置,实例化对应的PLC服务:
public static class PLCServiceFactory { public static BasePLCService CreatePLCService() { // 替换为你的INI读取逻辑 string machineType = ReadMachineTypeFromIni(); return machineType switch { "MachineA" => new MachineAPLCService(), "MachineB" => new MachineBPLCService(), _ => throw new ArgumentException("不支持的机型") }; } private static string ReadMachineTypeFromIni() { // 实际INI读取代码:比如用IniFile类读取配置项 return "MachineA"; // 示例值 } }
4. 应用中用实例替代静态类调用
启动时获取实例,后续所有PLC操作都通过该实例完成:
// 应用初始化时获取适配机型的服务实例 var plcService = PLCServiceFactory.CreatePLCService(); // 调用通用连接方法 plcService.Connect("192.168.1.100"); // 读取变量:自动适配当前机型逻辑 int value = plcService.ReadIntVariable("DB1.DBW0"); // 若为Machine B,调用专属方法 if (plcService is MachineBPLCService bService) { bService.SpecialBOnlyOperation(); }
方案优势
- 无冗余代码:仅差异逻辑需要重写,公共逻辑完全复用
- 扩展性强:新增机型时只需添加子类和工厂分支,无需修改原有代码
- 逻辑清晰:各机型实现分离,便于维护和调试
内容的提问来源于stack exchange,提问作者Luca Pannozzo
相关产品推荐
相关产品推荐

