2

我创建了一个库,该库扩展了另一个用 C++ 编写的库,现在我将这个库移植到 Java(在 Java 中编写 C++ 的原始库已经存在)。在 C++ 代码中,有一个名为的纯虚拟类Stallable应该用于在给定电压输入增量的情况下将失速检测添加到电机控制器。该类包含一个纯虚方法getVoltage(),用于提供电压源,因为它们是几个不同的电机控制器类,以及一些用于确定是否存在失速的虚函数。

类将继承这个类,以及原始库中的一个类(我无权访问代码并且出于所有意图和目的,否则无法修改),并将实现getVoltage()并覆盖它们的任何其他方法可能会喜欢。那么这些对象就可以直接询问是否有档位。

当我从 Java 方面处理这个问题时,我的情况变得有点棘手。我仍然无法触及原始类,因此重构代码不是一种选择,我的库的用户仍然应该被允许继承或实现Stallable他们认为合适的子类。

目前,我看到的前景如下。

  1. 制作Stallable一个接口并重新实现它使用的停顿检测逻辑。为了创建 C++ 代码库具有的原始功能,我必须让类子类化原始库并实现Stallable. 这会起作用,但需要在Stallable我将包含的任何子类以及最终用户将编写的任何子类中重新实现原始纯虚拟 C++ 中的逻辑。
  2. 创建一个抽象类,Stallable其中包含对原始库中电机控制器类的对象引用。这保留了 C++ 代码中的一些功能,因此某些方法必须被覆盖,而一些方法可以被选择性地覆盖,但是在此代码和 C++ 代码之间失去了透明度。在 C++ 中,由于每个子类都是Stallable原始电机控制器的派生类,因此在需要电机控制器和需要对象时,很容易将指针扔向Stallable对象。在这种情况下,必须实现某种类型的访问器函数,它返回对每个Stallable子类将保留的原始电机控制器的 Java 引用。透明度会丢失,但很容易添加失速检测。

显然,如果我可以修改各种电机控制器的原始类,那么这个问题很容易成为重构 C++ 代码的问题。

在研究了两种语言的 OOP 方法之间的差异之后,我倾向于选择选项 2,尽管它为我的最终用户和Stallable我计划包含的实现增加了摩擦。在我开始编写 Stallable.java 之前,我一直在询问是否还有其他更好的想法或见解。

4

1 回答 1

1

所以基本上你想要的是你的lib的Java用户能够实现一个接口和行为将被它携带?这听起来像是 AOP(面向方面​​编程)的工作。使用 AOP(例如 AspectJ),您可以将方法注入到符合特定条件的类中。

在您的情况下,标准是“实现 Stallable 接口”。AOP 的问题在于它是侵入性的。如果您选择运行时编织,您的用户将需要使用 AOP 编译他们的类或将 AOP 添加到他们的类路径中。

另一种选择是尝试使用动态代理进行一些委托。

最后,您可以尝试使用字节码操作http://asm.ow2.org/以便在运行时生成类。

如果您编写一个 Java 代码应该是什么样子的示例,我的答案可能会不那么含糊。

于 2013-11-13T01:27:21.997 回答