Добавить конструктор в deftype созданный класс

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

deftype делает все, что я хочу, за исключением предоставления нулевого конструктора (так как я создаю класс с полями).

Мне не нужно, чтобы поля были общедоступными, поэтому я могу придумать 4 решения:

Используйте gen-класс; Я не хочу этого делать, если смогу избежать этого.
Каким-то образом кодировать закрытые переменные-члены вне знания deftype; Мне сказали, что это невозможно сделать.
Написание модифицированного deftype, который также создает нулевой конструктор; честно говоря, я не знаю достаточно хорошо clojure для этого.
Взять класс, созданный deftype, и каким-то образом добавить в него новый конструктор.

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

Являются ли какие-либо решения, которые я предложил (или те, о которых я не думал), кроме использования gen-class, жизнеспособными?

2 ответа

Решение

Там, где это уместно, нет ничего постыдного в написании черты Java, если ваши требования к взаимодействию Java одновременно специфичны и непоколебимы. Вы можете написать класс Java с помощью одного статического метода фабрики, который возвращает экземпляр deftype класс, и это делает любую инициализацию / настройку, что вам нужно.

В качестве альтернативы, вы можете написать нулевую фабричную функцию в Clojure и вызывать ее напрямую из Java весь день.

Ни в коем случае ни deftype ни defrecord предназначены для (или будут ли они) полнофункциональными средствами взаимодействия. gen-class конечно, ближе всего, поэтому это было рекомендовано.

Я бы предложил просто написать объект на Java - для Java-подобных объектов с изменяемыми полями это, вероятно, будет более элегантным, понятным и практичным.

У меня, как правило, были довольно хорошие результаты по смешиванию кода Java и Clojure в проектах. Это похоже на один из тех случаев, когда это может быть уместно. Функциональная совместимость настолько хороша, что у вас практически нет дополнительных сложностей.

Кстати, я предполагаю, что вам нужен нулевой конструктор, чтобы соответствовать требованиям некоторой персистентной библиотеки или чего-то подобного? В противном случае это кажется странным требованием. Если это так, то вы можете найти, что имеет смысл переосмыслить вашу стратегию персистентности... произвольные ограничения, подобные этому, всегда кажутся мне чем-то вроде запаха кода.

Другие вопросы по тегам