Does anyone have any pointers on how to refactor Java abstract classes to be more Clojure friendly? Whenever I have to drop down to using proxy in Clojure, I find that Java API I am integrating with just isn't very amenable to being Lispified in a bunch of ways, like protected constructors, private fields, etc. If I could refactor the Java classes to use interfaces and default methods instead of abstract classes for extension, I think that would be easier to extend from Clojure. Are there any refactoring patterns out there which may help from the Java world turning abstract hierarchies into interface driven ones?
Agree that using certain Java from Clojure isnโt a great experience. Hate to admit it but I sometimes get ChatGPT to write me a quick Clojure abstraction on top of Java code. That might be an option for you too. Even for Java users they should very rarely be using inheritance or abstract classes (only to represent actual ironclad hierarchies not just for code reuse). They should nearly always be using interfaces rather than directly calling classes. An interface which only has one implementation is absolutely fine. Java and Clojure can use reflection to break into hidden/private fields/methods (so why bother making them private?!) but itโs best if the classes/interface just makes practically everything public by default (this is how Clojure namespaces work). They should also use the standard interfaces and types (eg Map, List, String, Double) as much as possible to increase compatibility and reduce endless conversions. Just like in Clojure things should be as immutable as possible - this means you are often retuning a new object not modifying the existing object in place. Yes this might feel like more boilerplate in Java but itโs worth it. Also it helps to avoid creating lots of classes that have to be each instantiated - as a Clojure user my heart sinks when I realize I need to instantiate 10 Java classes just so I can make a single method call.
@veckon As a refactoring pattern
take the abstract hierarchy and translate the public methods to a matching set of interfaces
have the abstract classes implement the interfaces
if you can now drop the abstract class from the public api do so
Thanks all! Great ideas.