我创建了一个扩展了另一个用C ++编写的库的库,现在我将这个库移植到Java(C ++编写的原始库已经存在于Java中)。在C ++代码中,有一个名为Stallable
的纯虚拟类,它应该用于在给定电压输入增量的情况下向电机控制器添加失速检测。该类包含一个纯虚方法getVoltage()
,用于提供电压源,因为它们是几个不同的电机控制器类,还有一些虚函数用于确定是否存在失速。
类会子类化这个类,以及原始库中的一个类(我无法访问代码,并且无法修改所有意图和目的),并实现getVoltage()
,并覆盖他们可能喜欢的任何其他方法。然后可以询问这些物体是否存在失速。
当我从Java方面解决这个问题时,我的情况变得有点棘手。我仍然无法触及原始类,因此重构代码不是一个选项,我的库的用户仍应被允许继承或实现Stallable
但他们认为合适。
目前,我看到的预期如下:
Stallable
成为一个接口并重新实现它使用的失速检测逻辑。为了创建C ++代码库所具有的原始功能,我必须将类子类化为原始库并实现Stallable
。这可以工作,但需要在我包含的任何子类中重新实现原始纯虚拟C ++ Stallable
中的逻辑,以及最终用户将编写的任何子类。Stallable
成为一个抽象类,它包含来自原始库的电机控制器类的对象引用。这保留了C ++代码中的一些功能,因此必须重写某些方法,并且可以选择覆盖某些方法,但是在此代码和C ++代码之间会丢失透明度。在C ++中,由于每个子类都是Stallable
并且是原始电机控制器的推导,因此当需要电机控制器时,当一个Stallable
对象出现时,很容易将指针扔到对象周围。需要。在这种情况下,必须实现某种类型的访问器函数,该函数返回对每个Stallable
子类将保留的原始电机控制器的Java引用。透明度会丢失,但很容易添加失速检测。显然,如果我可以修改各种电机控制器的原始类,这个问题很容易就是重构C ++代码的问题。
在研究了两种语言的OOP方法之间的差异之后,我倾向于使用选项2,尽管它为我的最终用户和我计划的Stallable
实现添加了摩擦。在开始编写Stallable.java之前,我在问是否还有其他更好的想法或见解。
答案 0 :(得分:1)
所以基本上你想要的是你的lib的Java用户能够实现一个接口和行为吗?这听起来像是AOP(面向方面编程)的工作。使用AOP(例如AspectJ),您可以将方法注入符合特定条件的类。
在您的情况下,标准是“实施Stallable接口”。 AOP的问题在于它是侵入性的。如果您选择运行时编织,您的用户将需要使用AOP编译他们的类或将AOP添加到他们的类路径。
另一种选择是尝试使用动态代理进行一些授权。
最后,您可以尝试使用字节码操作http://asm.ow2.org/,以便在运行时生成类。
如果您编写一个Java代码应该如何的样本,也许我的答案可能不那么模糊。