Encapsulate the Database

Picking up the ‘schema as 3rd party code’ idea, I want my database access to be encapsulated behind an insulation layer that decouples the business logic from the table schema.

This is the primary reason I have mostly lost interest in tools such as Hibernate and Neo. Where the documentation says things like ‘Autogenerate your mapping layer and persist your domain objects’, I see ‘Tightly couple your code to your database’.

Relational databases are hard to change. Especially once they’ve gone live. They very quickly foster an ecosystem of reports and queries, and almost always become an ad-hoc integration point for several applications, making schema changes very difficult.

For this reason alone, any tool which works by coupling business logic to to the database causes me concern. On almost every project I’ve seen that had an OO application and a relational DB, the persistence mechanism became a point of pain. Code becomes really hard to change because its constrained by the database schema and there’s usually an additional maintenance burden of keeping an XML configuration file in sync.

Code Insulation

Or, ‘Just because its open source I don’t want to have to compile it every time’.

Dee mentioned using vendor branches to manage 3rd party source.

I choose to avoid them. If I’m using a 3rd party library, I want a released binary. Recompiling someone else’s source as well as my own seems like a waste of time.

With respect to ‘fixing in place’, sure, if I know a solution I’ll submit a patch, but fixing in place means forking the 3rd party codebase, which (depending on the license) might oblige me to release it back to the community (which means time spent not getting work done), and opens a real potential for causing merge hell when I want to use a new version of the library. This happened to me a few weeks ago. Had the project done either of encapsulating access to the 3rd party code, or stuck with a binary version, the upgrade would have been far easier.

Inversion of inversion of control

Followup to Sam’s post, Sam’s other post and Liz’s post about Sam’s posts.

The contextual IOC pattern looks to me like a solution to the ‘problem’ of Dependency Injection based IOC, namely that all an object’s dependencies are explicitly named. But wait a minute, IOC was a solution to the problem of having objects whose dependencies weren’t clear in the first place.

Dependency injection bothers me because it encourages an object to have too much control. To shamelessly steal Liz’s example code:

new GameFactory(UserPreference preference, GuiComponentFactory factory, Scorer scorer, RulesEngine rulesEngine, Timer timer)

The reason GameFactory needs all that stuff is because it is presumably going to pass it down to the Game objects it creates. That is fine, and 5 parameters in a constructor isn’t setting off any code-smell alarms for me. I wouldn’t do it that way however. For a start, I question the need for a factory. Presumably somewhere there is a UI showing a list of possible games waiting for the player to choose one. I see no benefit in having an abstract factory when what I want to do in response to a user clicking ‘Tetris’ is a new TetrisGame(). The indirection of the factory is just getting in the way.

I could see how you might want a more configurable list of games, in which case possibly a GameCollection containing a TetrisFactory, a PacmanFactory etc. might work, if the game objects were too heavyweight to simply pre-instantiate at startup.

That’s not really where I want to go with this post though. The thing that really caught my eye was the Timer parameter. I’m being a bit mean picking on this one as its easy target, and design is subjective, but it demonstrates one of my concerns with IOC quite nicely. Clearly a Game object requires some notion of the passage of time, as many games are based on things happening periodically. In the Tetris example, it has to move a block down the screen and check to see if it’s landed on the pile. However, injecting a Timer is not what I would do. What the game object really wants is for something else to tell it when time has passed. Something external. The code might look like this:

public abstract class Game implements TimeDependent {
}

public interface TimeDependent {
void clockTick(long millisSinceLastTick);
// or possibly, for more OO flexibility
void clockTick(TimeInstant aFrozenMomentInTime);
}

This style satisfies all the requirements of testability, with the added simplification of removing one of the dependencies from the constructor.

You could do the same with Scorer. The game could expose a public TetrisScore basicScore() method, that a collaborator can call, and do its own post-processing on before showing it to the user.

UserPreferences is tougher. I’d agree that the game wants to ask a number of questions of the preferences object, so it should probably be given it.

To conclude, we build object-oriented systems. Its ok for an object to need help from collaborating objects, without having to own them all, or even know who is helping it.

The XP definition of 3rd party code

Continuing along the train of thought from my previous post, I came up with this rather extreme definition of 3rd party code:

3rd party code is any code on a different release cycle to the system under development.

This definition covers everything from 3rd party binaries, code developed by other in-house teams, the operating system, and your database schema.

Third party code considered harmful

Most systems are not built from scratch. Most will use third party libraries, either commercial products or open source utilities.

A good example of this in the Java world is log4J – many projects use it for their logging requirements, and its a good tool. However what most projects will do is use it directly, which means that virtually every class in the system will have a dependency on log4J. If a need arises that log4J can’t handle, or a new version is released that changes some behaviour your project depends on, it can be a huge job to go through all your code making changes.

A useful approach is to wrap all access to 3rd party code yourself, thus giving you a single point of contact between your system’s code and the external library. This wrapper is also a useful place to put any extension functionality that your system needs.

Webtrends

Seeing lots of signs that dotcom bubble 2.0 might be on the way. Lots of people putting together ruby on rails based sites that all seem to be dedicated to finding new ways of helping people publicise things we used to write in private diaries.

Me. I’m going straight to the front of the curve, stepping right past ruby on rails, to seaside on smalltalk.

Registry Rant

The Windows Registry.

Lets make a giant file that every application dumps all its data into!
Lets make the operating system use it as well so a misbehaving application can wreck your whole system!
Lets key everything with a GUID so nobody has a damn clue what anything is!
And lets categorize it so that every application has to sprinkle its data into 10 different places!

Windows Registry, I want the last 3 hours of my life back.