2013-11-13 3 views
2

Я создал библиотеку, которая простирается от другой библиотеки, написанной на C++, и теперь я переношу эту библиотеку на Java (исходная библиотека, которую C++ была написана поверх уже существующей в Ява). В коде C++ существует чисто виртуальный класс под названием Stallable, который предполагается использовать для того, чтобы добавить обнаружение сваливания на контроллер двигателя с учетом дельта входного напряжения. Класс содержит чисто виртуальный метод getVoltage(), который используется для подачи источника напряжения, поскольку он представляет собой несколько различных классов контроллеров двигателей, и некоторые виртуальные функции, чтобы определить, есть ли стойло.Портирование множественного наследования Код C++ для Java

Классы будут подклассифицировать этот класс, а также класс из исходной библиотеки (тот, который у меня не имеет доступа к коду, и для всех целей и задач иначе не может быть изменен) и будет реализовывать getVoltage() и переопределить любые другие методы, которые им могут понравиться. Тогда эти объекты можно просто спросить, есть ли стойло.

Когда я подхожу к этой проблеме со стороны Java, ситуация становится немного сложнее. Я до сих пор не могу коснуться оригинального класса, поэтому рефакторинг кода не является вариантом, и пользователям моей библиотеки все равно разрешено подклассы или реализовать Stallable, но они сочтут нужным.

В настоящее время перспективы, которые я вижу, следующие.

  1. Сделайте Stallable интерфейсом и воспользуйтесь логикой обнаружения останова, которую он использует. Чтобы создать исходную функциональность, которую имеет кодовая база C++, мне пришлось бы иметь подклассы классов исходной библиотеки и реализовать Stallable. Это сработает, но потребует повторной реализации логического элемента в чисто виртуальном C++ Stallable среди любых подклассов, которые я бы включил, и любых подклассов, которые будут писать конечные пользователи.
  2. Сделайте Stallable абстрактным классом, который содержит ссылку на объект класса контроллера двигателя из исходной библиотеки. Это сохраняет некоторые функциональные возможности кода C++, поэтому некоторые методы должны быть переопределены, а некоторые необязательно переопределены, однако прозрачность теряется между этим кодом и кодом C++. В C++, поскольку каждый подкласс был Stallable и выводом исходного контроллера двигателя, стало легко бросать указатели на объект, когда требуется контроллер двигателя, и когда нужен объект Stallable. В этом случае должен быть реализован некоторый тип функции доступа, который возвращает ссылку Java на исходный контроллер мотора, к которому будет принадлежать подкласс Stallable. Прозрачность будет потеряна, но обнаружение сваливания будет легко добавлено.

Очевидно, что если бы я мог модифицировать исходные классы для различных контроллеров двигателей, эта проблема может быть легко реорганизована на код C++.

После изучения несоответствий между подходами обоих языков к ООП, я склонен идти с вариантом 2, несмотря на трение, которое он добавляет для моих конечных пользователей, и реализованные в нем варианты Stallable, которые я планирую включить. Я спрашивал, есть ли какие-нибудь другие идеи или идеи, прежде чем я начну писать Stallable.java.

+0

Вы абсолютно правы в несоответствии между подходами ООП. Однако у Java есть статический импорт: это может быть использовано для уменьшения объема кода, который должны реализовать ваши клиенты, если вы решили использовать интерфейс. Если вы добавили класс декоратора над этим интерфейсом, вы могли бы реализовать свои чистые виртуальные функции. Кроме того, вы можете посмотреть Java Native Access (https://github.com/twall/jna). –

+1

вы можете сделать это в java8. Stallable - это интерфейс с одним абстрактным методом getVoltage() и другими методами «по умолчанию», которые содержат тела методов. – ZhongYu

+0

@ zhong.j.yu Я реализую решение таким образом. Я не знал об этой возможности, спасибо. –

ответ

1

Итак, в основном вы хотите, чтобы Java-пользователи вашей библиотеки могли реализовывать интерфейс и поведение с ним? Это звучит как работа для AOP (аспектно-ориентированное программирование). С AOP (например, AspectJ) вы можете вводить методы классам, которые соответствуют определенным критериям.

В вашем случае критерием является «реализация интерфейса Stallable». Проблема с АОП заключается в том, что она инвазивная. Ваши пользователи должны будут скомпилировать свои классы с помощью AOP или добавить AOP в их путь к классам, если вы захотите использовать плетение во время выполнения.

Другой вариант - попытаться сделать некоторые делегации с использованием динамических прокси.

Наконец, вы можете попробовать использовать обработку байт-кода http://asm.ow2.org/, чтобы генерировать классы во время выполнения.

Возможно, мой ответ может быть менее расплывчатым, если вы напишете образец того, как должен выглядеть код Java.

Смежные вопросы