Lately I've been working quite hard on mapping the relationships between tables.
It seems to be a lot harder than I first thought, both because of the complexity of the task in itself and because of another limitation of Java.
Mantaining the relationships is hard because an ORM must, for every change made to an object, change the table directly mapped by that object and all the related tables (updating foreign keys or deleting children rows in varoius tables). Furthermore, when linking mapping objects together, the ORM must take care to update the corresponding tables only when and if it is necesary. Finding out when and which updates must be performed in an intelligent way is not always so obvious.
Another unforeseen problem is Java's inability to dynamically create fields. To be fair, this is a problem most compiled (or byte-code compiled) languages have.
In a scripting language (think about JavaScript or Ruby), you can dinamically add a field (or a method) to a class at runtime. This possibility gives an ORM a great deal of freedom and greatly improves the simplicity and terseness of its interfaces.
In Rails if a table A has a relationship with table B, The class representing table A will have a field b corresponding to an object of type B (or vice versa, depending on the relationship between the tables). This field does not need to be hard-coded into the class, it is dinamically inferred and added to the class, and that field can be used directly (i.e. a.b = "something" if a is of type A).
In Java this is not possible. Java does not permit a field to be added dinamically and this forces the design of the classes to be awkward (lists of related objects, with methods to access them...) and hard to read.
I'm trying to find a workaround for these problems that permits a nice interface, but I'm also trying to have a first working version to release (even if it is buggy and not pretty).
Showing posts with label Java limitations. Show all posts
Showing posts with label Java limitations. Show all posts
Wednesday, 24 September 2008
Friday, 8 August 2008
Static methods
One of the first things I had to consider when designing SimpleRecords was which methods the main class should have and wheter they should be static or not.
I wanted to have a behaviour similar to ActiveRecord's one:
Come Java, and its implementation of inheritance. In Java static methods are not inherited. A derived class can use its superclass static methods, but these methods still reside in the superclass. The problem with this approach is that if you try to get the name of the current class or one of its fields, via reflection, inside a static method, you will always get the name or the field of the class which defined the static method and not the name of one of its derived class that is using said method.
This leads to an important decision about how to implement the Active Record pattern. Basically I had two possibilities:
On the other hand, the second approach keeps the Class logic intact, but needs an extra parameter, containing the actual class informations, for every static method inside the base class.
Instead of choosing one approach instead of the other, I decided to keep them both, and provide two superclasses from which to inherit: one providing static methods and one providing instance methods. If and when one approach becomes better than the other, I will ditch the inferior one.
I wanted to have a behaviour similar to ActiveRecord's one:
- You create a class, representing a database row, extending a base class
- The new class inherits from the superclass all its database mapping business logic
- The new class now has some instance methods to work with the row it represents (save, delete...) and some static methods to retrieve objects reading the DB table (find, create...)
Come Java, and its implementation of inheritance. In Java static methods are not inherited. A derived class can use its superclass static methods, but these methods still reside in the superclass. The problem with this approach is that if you try to get the name of the current class or one of its fields, via reflection, inside a static method, you will always get the name or the field of the class which defined the static method and not the name of one of its derived class that is using said method.
This leads to an important decision about how to implement the Active Record pattern. Basically I had two possibilities:
- Break the design pattern and any basic logic behind a class, having only instance methods
- Use static methods, passing them a parameter to be able to identify the actual class we are using.
On the other hand, the second approach keeps the Class logic intact, but needs an extra parameter, containing the actual class informations, for every static method inside the base class.
Instead of choosing one approach instead of the other, I decided to keep them both, and provide two superclasses from which to inherit: one providing static methods and one providing instance methods. If and when one approach becomes better than the other, I will ditch the inferior one.
Subscribe to:
Posts (Atom)
