Not Rocket Science, I'd Think
Jun. 4th, 2010 06:43 pmSo over the years, I've written a really big in-memory object database in C++. It contains many different objects that you might want to work with.
And now it is time to write a Java API over the top of it. That doesn't seem so bad, does it?
Well, yes. Yes, it does.
If you have a C++ entity in memory (an "entity" is at the top level), I want a Java object that corresponds to that entity and provides some methods. Some of those methods allow you to create a new Java object that will provide access to additional methods related to an object that belongs to the entity -- say, for example, the metadata that describes the time periods in the model. If you wanted to change the time metadata, you'd get a copy of the time object, call the methods that the Java wrapper for the time object provides, then commit it back to the entity object so that the changes to metadata and the related data would be saved in the entity.
Fundamentally, this is a lot like a COM interface, in that you open an interface, then open other interfaces that the first interface gives you access to. It's a reasonably well-understood model.
The rest of the group doesn't want to do that. They want one big (and it will be big) interface that allows you to do anything that you might ever want to do to the entity. Aside from being, in my opinion, unmanageably large, it also seems to take all of the bookkeeping that Java would normally help you do and require that you code it by hand, because now the C++ layer has to keep track of the fact that you asked for a new copy of the time object and you'll have to ask the entity interface to have it destroyed, should you decide to abandon your changes instead of just destroying the Java wrapper object or letting it go out of scope.
I think the latter approach is a really bad idea.
Am I just wrong? Or is there something that I'm missing that will cause me to see the light?
*sigh*
And now it is time to write a Java API over the top of it. That doesn't seem so bad, does it?
Well, yes. Yes, it does.
If you have a C++ entity in memory (an "entity" is at the top level), I want a Java object that corresponds to that entity and provides some methods. Some of those methods allow you to create a new Java object that will provide access to additional methods related to an object that belongs to the entity -- say, for example, the metadata that describes the time periods in the model. If you wanted to change the time metadata, you'd get a copy of the time object, call the methods that the Java wrapper for the time object provides, then commit it back to the entity object so that the changes to metadata and the related data would be saved in the entity.
Fundamentally, this is a lot like a COM interface, in that you open an interface, then open other interfaces that the first interface gives you access to. It's a reasonably well-understood model.
The rest of the group doesn't want to do that. They want one big (and it will be big) interface that allows you to do anything that you might ever want to do to the entity. Aside from being, in my opinion, unmanageably large, it also seems to take all of the bookkeeping that Java would normally help you do and require that you code it by hand, because now the C++ layer has to keep track of the fact that you asked for a new copy of the time object and you'll have to ask the entity interface to have it destroyed, should you decide to abandon your changes instead of just destroying the Java wrapper object or letting it go out of scope.
I think the latter approach is a really bad idea.
Am I just wrong? Or is there something that I'm missing that will cause me to see the light?
*sigh*
no subject
Date: 2010-06-05 03:39 am (UTC)Nope, you aren't missing anything. I would argue against it too. ANd if I lost, I'd be sending an e-mail confirming that my advice was not taken so when the inevitable maintainability nightmare begins I can point and say I told you so before I roll up my sleeves and dig in :)
no subject
Date: 2010-06-05 07:44 am (UTC)That's not very useful, though.
Maybe this is - Coding the large, single interface is a maintenance nightmare. You cannot possibly anticipate everything you might want to do with the underlying code. When you add new functionality, you will not have any kind of conventional class structure to base your changes on - you will have a labyrinth of thousands of methods in one god class. (or god package - same problem.)
Alternatively - you used C++ for a reason. It is class-oriented, so presumably the C++ code has a class structure that makes sense.
Java is also class-oriented. Following the class structure of the C++ code is much less error prone than creating a huge menu of options in one Java class.
The big problem with their way - it seems easy at the start. And it is - it is just like writing a simple class that uses library methods - until the underlying complexity catches up to you. It takes longer to get things right the more you work on it, eventually every fix is a hack, because there is no way to fix the big problems without a complete re-write - and by now you have written a large outside code base that depends on the god class and all it's hacks.
That's my $0.02.
no subject
Date: 2010-06-05 10:52 am (UTC)no subject
Date: 2010-06-05 11:25 am (UTC)One question I would ask is, what happens if the Java API's functionality remains useful, but your C++ implementation needs to be replaced some day. It would be nice if changes on the Java side were minimal in that case. (I'm used to using Hibernate for Java persistence; changing storage with it is a configuration issue, not a programming one.)
Another idea that comes to mind is to have a look at the style of programming used in the presence of JPA/EJB (if you're not already familiar with it) to see what the Java world considers "normal" for persistence.
(I'm not sure if you were suggesting object destruction as a way of synching the layers, but just in case....) On the technical side, any dependence on object destruction in Java is prone to failure. You can write finalize() methods, but there's no guarantee they'll ever be called.
no subject
Date: 2010-06-05 09:42 pm (UTC)My objective here is to hide a lot of the C++ implementation from the Java layer, but I have no problem with exposing objects that represent things that the non-programmer user has to work with. So if they want to work with the Time dimension or the Scenario dimension, I'm happy to expose an object/interface for that.
no subject
Date: 2010-06-05 06:46 pm (UTC)