Saturday, December 23, 2006

Spaghetti Code

One always guesses every one knows what a Spaghetti code is - a code which is hard to understand and maintain, a code which everyone is so scared to touch that bug fixes are always quick and dirty, and which makes code further spaghettier.

I wonder has anyone thought about spagetti products. It may not consist of Spaghetti code, but uses myriad of technologies, frameworks, and solves variety of domain problems that its very difficult to add a new component in it. Hence, it becomes difficult to adding a new component in a consistent way, due to lack of consistent architecture and implementation.

Given a product which uses a range of technologies and has evolved over period of time, the team responsible for adding a new component has a wide variety of technological choices to make. And sometimes, team pick the technology which they are comfortable with.

And, we have something, what I would like to call, a Spaghetti product.

Add to this, the changes in team over period of time, transitioning of product from one team to another team, outsourcing to partners, the product also runs the risk of developing spaghetti code. Over a period of time, it not only becomes difficult to maintain the product, but it also becomes equally difficult to enhance the product features or to add new components.

Such products are typically a good candidate for re-architecture and re-design.

Re-architecture and re-design do not guarantee that new product wont evolve to become spaghetti product over a period of time. It just adds a new life to the product.

It seems that every code ultimately becomes spaghetti code at some point, and every product becomes spaghetti product.

I also wonder whether Frameworks too will become spaghetti framework one day. Take Spring for example. It started as IoC container and light weight alternative to EJBs, but it has now lot of extensions such as Web Flow, Acegi security, and others which make it more spaghettier. Even though I am yet to read the whole of Spring 2.0 documentation, I sometimes feel that there is just too much being offered in one place, and probably its the pressure to keep adding value to the framework which forces teams to extend it release after release. Extensions may make sense in some cases, and in some cases it may be just an overkill and something which is added to level with competing frameworks.

Sometimes, the technological advancements also forces extension. For instance, addition of annotations in Java 5.0 has pretty much lead to a wave of augmenting XML based configuration with annotation based configuration.

Monday, December 18, 2006

Testing your java code

It cannot be said enough that testing is the most important part of the development cycle. Even though I am not a tester (and not trying to push an agenda), I have seen that well written code without adequate test cases is not really something that any developer or team should strive for.

And in the J2EE world, the best way you could possibly test code is by using Junits.

Junit is simple testing framework designed around two key design patterns: the Command pattern and the Composite pattern. They are simple to write and check their own results and provide immediate feedback and they are relatively inexpensive to write (oh yeah - they are free in terms of cost).

A TestCase is a command object. Any class that contains test methods should subclass the TestCase class. A TestCase can define any number of public testXXX() methods. When you want to check the expected and actual test results, you invoke a variation of the assert() method.

TestCase subclasses that contain multiple testXXX() methods can use the setUp() and tearDown() methods to initialize and release any common objects under test, referred to as the test fixture. Each test runs in the context of its own fixture, calling setUp() before and tearDown() after each test method to ensure there can be no side effects among test runs.

TestCase instances can be composed into TestSuite hierarchies that automatically invoke all the testXXX() methods defined in each TestCase instance. A TestSuite is a composite of other tests, either TestCase instances or other TestSuite instances. The composite behavior exhibited by the TestSuite allows you to assemble test suites of test suites of tests, to an arbitrary depth, and run all the tests automatically and uniformly to yield a single pass or fail status.

Here is an FAQ on Junits:

and here is an excellent introduction to Junits