Sunday, September 16, 2007

Objects have identity, components don't

A couple of rules:
  • Objects have identity, components don't.
  • Components have an emphasis on behavior, objects on state.
  • Object can expose methods to expose state and validate state.
  • Components with state are considered harmful - but sometimes inevitable
  • Events in components should always make it explicit if they are before or after the fact occurred. To make it explicit in which state the component is and not in some kind of transition
  • Services are components designed for remote access. (coarse granular)
To me, a service is instantiated and accessible at a certain physical location, however this does not match with the situation where a service is deployed in an embedded way. Mmmm.

Data Duplication - Source of all Evil

Several disciplines in the software world have their means to deal with data duplication; database guys use normalization, programmers use refactorings like extract-method. The goal is to have the definition/specification in one place to reduce the maintenance burden.

Other disciplines like data warehousing don't care about the data duplication because they do not have to update the data, only to add.

The problem in programming is that it is hard to detect duplication. (especially when we span the dimensions; large & multiple teams + time). There are known algorithms to detect duplication (eg IntelliJ provides something like this). However I question; do we want to remove all duplication? If there is a single implementation in a large system; won't it become impossible to change the implementation just because doing the impact analysis will take a very long time?

In this case of components it will be hard to prevent duplication. Take for example a simple method that replaces all double quotes with single quotes (one Java 1.5 call). This method occurs in two different components. The cost of extracting this (and thus introducing a new shared component) does not weigh up against living with the duplication.

Another killer is of course 'semantics'; although the implementation is identical; are the semantics identical? Determining this won't be always easy - especially when another guy wrote the other component.

Fact; we have to live with code duplication. It is inevitable.

Friday, September 14, 2007

Programming languages with build-in support for unit testing

How many times have you made a private method package local just for unit testing? Each time you have to add some comment 'package local for testing'. Annoyance!

Java's successor must have some kind of access descriptor dedicated for unit testing.

Wednesday, September 12, 2007

'Class names in Plural' smell

Just ran into a piece of code where somebody was using a class that was in plural, like for example Computers. Well, that smells. If you have a collection/list/bag/set/whatever of computers, then use the appropriate collection class. Since this was not the case probably more is going on. This is a collection of items with a certain characteristic that they share. Probably a bunch of computers forming a domain with additional properties that rise above the collection level. I'm arguing that you should use a class name that reflects the item(s) in common - most likely in singular.

Thursday, September 6, 2007

svn ignore for multiple folder / directories

I was struggling with the svn:ignore property to specify multiple folders. This is how I solved it:

set the environment variable EDITOR. I'm using ultra edit:
>set EDITOR="C:\Program Files\UltraEdit\uedit32.exe" (note the quotes)

Type in (note the period at the end, indicating the current folder is the target)
>svn propedit svn:ignore .

This will open the editor, UltraEdit in my case.
Enter the folder names separated on each line
Save and exit the editor.

That's it. Use svn status to see if indeed the folders are ignored.

Wednesday, September 5, 2007

Import / Export Database from / to XML

I'm using Hibernate to manage my database persistency and I wanted to add export/import to/from XML capabilities. Hibernate does support XML but the documentation is very limited. Next, it is not capable of generating a schema (xsd). XStream has the same problem. So that left only JAXB. Issue with JAXB is that it is very document (web service) oriented. The HyperJAXB - project uses the web services xml as a starting point. I want it the other way; my domain classes are the source of truth; they form the basis from which I want to persist and export/import.

Since i'm neither a JAXB nor a Hibernate expert it has proven to be quite an exercise. Especially Hibernate's merge operation in combination with Spring's IdTransferringMergeEventListener caused a lot of headache. I did not fix this properly, but replaced the merge() with saveOrUpdate().

Anyway the basic steps to export/import a database (aka repository) are as follows:

  • Create a container class that contains collections of the top-level domain classes. My sample is based on two domain classes Person and FiledCase. The class Repository contains two collections of these classes. The collections are extensions of a special HibernateCollectionAdapter class. This class takes care of loading from and persisting to the database for a domain class. The container class is passed to JAXB for import or export
  • Annotate the database id field in each domain class with @XmlTransient, we do not use this field since it is not guaranteed to be unique across all classes. (if it would be you could use this field as xml id)
  • Add an xml id field to the domain classes that can be referred to. Annotate the get method with @XmlID. The get method should return the fully quantified classname appended with the database id. (to make the ID unique across all classes)
  • Annotate the classes that needs to be exported with @XmlRootElement
  • Mark the get methods that refer to other objects that are not aggregated, but have an association type of relationship with @XmlIDREF
  • Make sure that the classes are exported in the order of least referenced, use the annotation @XmlType with field proporder to specify the order of the properties. This is very important during import. JAXB will patch references of objects afterwards when they cannot be resolved immediately (because the object is not yet imported). However when the object is already persisted it will not reflect the updated references.
  • The HibernateCollectionAdapter class implements the Collection interface. In the add() method it will store() an object and in the contains() it delegates to a find() method. The store and find methods are overridden in the descended classes. There are a couple of other methods that should also be overriden.
Sample is uploaded, see comment below