Java开发PLC软件时,如何不实例化跨类调用方法,拆分第三方生成的混杂IO代码
针对PLC IO代码拆分的可落地实现方案
你之前尝试用接口拆分走不通的核心原因很直接:Java 接口的默认方法无法持有实例状态,也不能直接继承BComponent的实例字段与方法,一旦IO逻辑涉及Property的状态存储,接口根本没法承载这些值,自然达不到拆分效果。
下面的方案完全匹配你的诉求:不用手动实例化IO类、调用IO方法无冗余前缀、两个类双向可访问、不改动第三方自动生成的核心IO逻辑。
具体实现步骤
1. 独立IO类的结构设计
把所有第三方自动生成的IO代码全部迁移到IoInterface类中,仅保留必要的BComponent继承,去掉冗余的Runnable实现——IO类不需要承载业务线程逻辑。
只需要在类里额外加一个业务上下文的持有逻辑,实现IO类反向访问业务类的能力:
public class IoInterface extends BComponent { // 持有业务类的引用,用于IoInterface内部调用TestClass的方法/字段 private TestClass bizContext; // 类加载时初始化全局唯一的IO实例,避免每次用到都新建对象 private static final IoInterface INSTANCE = new IoInterface(); public static IoInterface getInstance() { return INSTANCE; } // 提供方法给外部注入当前业务类实例 public void bindBizContext(TestClass context) { this.bizContext = context; } // 以下为第三方自动生成的原始代码,完全不需要修改 /**AUTO GENERATED IO's*/ public static final Property bBool_1 = newProperty(/*settings*/); public boolean Get_bool_1(){/*return value */} public boolean Set_bool_1(){/*set value*/} public static final Property bBool_2 = newProperty(/*settings*/) public boolean Get_bool_2(){/*return value */} public boolean Set_bool_2(){/*set value*/} /**END OF AUTO GENERATED CODE*/ }
2. 业务类的调用适配
要达到“像类内方法一样直接调用IO、不需要写ioInstance.xxx前缀”的效果,有两种适配方式:
- 方式一:在
TestClass里加一层和自动生成代码签名完全一致的薄委托方法,这些方法可以用IDE的自动生成功能批量生成,10秒就能搞定几百个方法:public class TestClass extends BComponent implements Runnable{ // 委托方法:方法名、返回值、参数完全和IoInterface里的方法保持一致 public boolean Get_bool_1() { return IoInterface.getInstance().Get_bool_1(); } public boolean Set_bool_1() { return IoInterface.getInstance().Set_bool_1(); } @Override public void run(){ // 启动时绑定业务类引用,打通双向访问 IoInterface.getInstance().bindBizContext(this); // 业务逻辑和原来完全一致,直接调用IO方法,不需要任何前缀 if (Get_bool_1()) { // 业务处理逻辑 } } } - 方式二:如果不想写批量委托方法,可以把
IoInterface里的实例getter/setter改成静态方法(这些方法本来就操作静态的Property字段,改动不会破坏原有功能),之后在TestClass开头用静态导入把所有IO方法引入,连委托代码都不需要写:// 在TestClass.java开头加静态导入 import static com.xxx.IoInterface.*; // 之后run方法里的调用和原来完全一致 if (Get_bool_1()) { ... }
方案优势
- 自动生成的IO代码全部独立在单独类文件里,结构清晰,不会和业务逻辑混在同一个几百上千行的类里
- 业务类里调用IO方法的写法和原来单类实现完全没有区别,不需要修改已有业务逻辑的调用代码
- 双向访问逻辑打通:
IoInterface内部可以直接通过持有的bizContext引用,调用TestClass的公共方法、访问公共字段 - 运行时无额外性能损耗:薄委托方法会被JVM的JIT编译直接内联,执行效率和原来的单类代码没有区别
- 兼容第三方代码生成工具:自动生成的IO逻辑完全不做修改,后续工具重新生成代码时,不会覆盖我们自己写的类结构逻辑
注意事项
- 不要给
IoInterface加冗余的Runnable实现,这个类只负责IO的读写配置,不需要承载线程调度逻辑 - 持有
TestClass引用时,尽量用弱引用替代强引用,避免组件销毁时出现内存泄漏 - 委托方法只做透传逻辑,不要加额外业务判断,后续新增IO点位时只要批量更新委托方法即可,不要在委托层写业务代码
内容的提问来源于stack exchange,提问作者mittens13
相关产品推荐
相关产品推荐

