Saturday, September 23, 2006

The Flawed Interface Principle - Part 2


After re-reading my last post, I felt quite disappointed: the main point could have been squeezed up in
  1. the more you add stuff to a system, the more you’re likely to bring mess

  2. if you do things by yourself you’re probably getting a better result (but in more time)

  3. interfaces are dangerous.
Ok, point number one, is right, but really sounds too obvious to deserve a post (I'll never win a Nobel with that...). We’ll get on it later.

Point number two is simply dangerous: you simply don’t start a project developing everything from scratch, but start choosing the available components on the market (let’s say… JBoss, Hibernate, Log4J etc.) No way I am telling that you should re-invent everything from scratch! If time is a constraint (and in software development always is) then the better trade off is somewhere else, remember that we moved from a two-minutes micro waved junk food to an 6/8 hours preparation delicacy. Moreover, there is normally no reuse purpose in cooking. While reusable components are the keys to successful projects.

Point three. The real meaning is that interfaces are tricky. In OOP theory, an interface is just a substitution point. As a client class, I declare the need of an object instance able to perform certain operations, namely the public methods of the interface. I can’t make no assumptions about the implementing class, I just expect that somebody (a factory method or the classloader) will provide the needed runtime implementation. What I don’t know is just what’s behind the interface. Which is both powerful and dangerous.

What lies behind
In complex systems, the value of interfaces is their ability to simplify the overall picture. A complex subsystem can be masked by an elegant Façade allowing designers to ignore implementation details. I’ll make another example with a pretty simple interface: the electricity plug on your wall. It’s a pretty simple interface: 3 holes, 220V, 50Hz. Every electronic device can work everywhere (at least in one single country). The plug mask the whole complexity that lies behind so you can happily ignore about tri-phase cables, power plants, and so on. Unless they start building a nuclear power plant near your home, or stocking plutonium in your garden…
We got closer to the point. Complexity is still there. Interfaces make it more manageable, by allowing us to ignore details, not to delete them.

Crossing competence boundaries
While developing complex J2EE applications, a common problem to face is a version clash between (indirectly) required libraries. Xerces is a common suspect in such circumstances, cause it’s often referenced by the application server, the application itself and one or more used libraries often use it as well. Normally the solution is nontrivial and has to do with fine tuning of the application server classloading mechanism. Still you need an expert J2EE architect to drill and solve the problem. Sometimes is not so easy to find a good one, but it’s a well defined professional profile.

Things are not that easy when you start crossing competence boundaries. One of the first borders is the Java-SQL. How many applications have you seen that could be told to be optimized both on DB and Java performances?

If you start adding more layers, like running on a virtual environment instead of a real one, such as VMWare. How many details are you missing in the meanwhile?

Problem determination in Babylon
Here we go. We built our beautiful tower, by putting freely available components together. The tower is high and majestic. Then we have a problem. If the problem is in the glue we used to put the things together, it’s an easy task. After all gluing is all we did. If the problem is in one brick, we have to determine where the problem is (which can start to be a nontrivial task), and update, refactor or substitute the faulty component.
If the problem is in the interaction between two or more components, or in what happens behind the scenes (or the public interfaces) then you’re in deeper trouble: cause you need cross concerns competence and you probably won’t have it. And it’s not easy to be found as well.

Tags: , ,

Saturday, September 16, 2006

Food processing chain and The Flawed Interface Principle


While I was discussing with a friend, preparing a speech about complex system management, I realized that there is a close analogy between food processing industry (and its worst effects) and what usually happens on large complex systems.

Grandma’s good old taste
Suppose you want to make some pasta, tagliatelle Bolognese for example, that you used to like in your childhood (ok, it’s getting pretty clear that this post it’s gonna get targeted to Italian geeks that like to cook… a pretty narrow audience niche…).
You can go to the supermarket and buy the ingredients you need, but then you have to make a choice
  1. buy the “all-in-one” package that you just have to warm up (microwave or frying pan)

  2. buy the pasta and buy the sauce, cook the pasta and then mix it by yourself

  • buy the eggs, the floor, the meat and the vegetables and actually make the pasta and the sauce
If you are a good enough cooker, you’ll notice that there’s a close connection between how much time you spend in cooking, and the final result.

Still, even if good, the result still doesn’t taste as good as your grandma’s. Next step is forgetting about the supermarket and buy the staff straight from the farmer. Suddenly eggs start to taste differently and so do the vegetables.

Ok, in the end you have to surrender: you can’t beat your grandma in cooking. It’s just an axiom. But sometimes you can get close. The interesting thing is that once you managed to get that close to the taste of your childhood you can’t even think about eating option number one at the top of page. And even if the label (and the pictures) tries to tell you that it’s the same thing, you just know it’s a completely different stuff from what you really want.

Question is: “How could it get that far?”
The answer is pretty simple: by systematically doing a substitution of the original ingredient with its industrial equivalent. And here is where we get back to software.

The Flawed Interface Principle
The keyword is “substitution”, how could you possibly do that (remember the oop substitution principle…)? Because every ingredient’s decoy looks or smells (almost) like the original, and if you change only one ingredient the difference could be small enough to go unnoticed.
Put in another way, food decoys implement just part of the original ingredients’ interface, generally the look (maybe with the help of some good photographer), but not others, less documented or testable, such as smell, for example.


If you start reading labels of pre-prepared foods, you realize also that they have more than twice the ingredients needed of the original recipe. Stabilizers, preservatives, enhances, colourings (whose role is just to satisfy the visual interface), and so on.

The point is that nontrivial interfaces are seldom complete. Even if they can be thoroughly documented, there is probably nobody checking if the whole system can fit together (at least I’ve never seen it happening in the software development industry). Every component you add in a system has a burden of internal complexity (libraries, for example, but not only) that can’t be completely masked by encapsulation, but only 99%.
The net result in complex software systems is that if you consider that every implemented interface between components has a certain probability to be flawed, you come to the conclusion that every time you add (or more fashionably plug-in) some component in a complex system, you are getting one step closer to the whole system collapse.


Tags: ,

Friday, August 18, 2006

Keeping technology standing still


Recalling projects I’ve seen, I realized that there was a strong correlation between the technological landscape of the project and the actual number of developers leaving the project (and the company). The more the technology was fixed, the more it became boring and frustrating for developers. Software developers are not normal workers, but strange animals that actually
like coding, and they can do a hell of a job as long as they have some fun out of it. Tom deMarco’s Peopleware makes a perfect portrait of the software developer and of his peculiar needs.

Trading fun for productivity?
Still, it looked like sort of a bargain: one can choose to keep the technology fixed, to pay less in training and refactoring while increasing the risk of an early departure from the project. Unfortunately, as long as the project continues, the chances of this event steadily increase so you must carefully consider this option. What is somehow hidden is that developers are not at all the same, and the one who is more prone to get bored might be just the most curious one, the most brilliant or the most passionate. So if you’re assuming that one over five of your developers might be leaving, chances are high that you’re losing 30% of the workforce instead.

The other hidden part of the bargain is that if somebody leaves in the middle, you have to pay a productivity price in training time as well. If the base technology is outdated, or – worse – proprietary, learning cost for newcomers will increase over time.

Updating the landscape
Ok, not all projects are intended to be “eternally open” (so this thought can’t be applied everywhere), but if you have a long living project and you’re trying to save money by stopping the evolution you are actually creating a huge cost area in the future that will materialize in the form of “the big refactoring mayhem” or of “the application that can’t be changed”. Maybe it won’t be your personal problem as a PM but in both ways you end up wasting money in the long term.

Tags: ,

Tuesday, August 08, 2006

RAD development and domain modeling


Java web programming suffered bad development performances in the last years, mainly related to the complexity of the presentation layer. As a coordinator for J2EE learning classes, I found often embarrassing to define a competence stack for the web programmers which included Java, J2EE concepts such as Servlets and JSPs, a bit of XML and HTML (and HTTP of course) some JavaScript and a MVC (so some Design Pattern concepts got in as well) framework, normally Struts. Given that in another language, such as Delphi or Visual Basic, programming for the presentation layer is made ultra-simple, this pile of necessary knowledge really looked scary.

Moving from Struts to JSF

Although the JSF approach is far from being perfect, it’s just a great leap forward compared to the old mainstream Struts:

- at the architectural level, JSF removed the need for a layer, making it possible for the presentation layer to manage model objects instead of dealing with extra-flat ActionForm classes. In many cases, inability to handle data which was not a String led to an extra layer of DTOs to simply handle transportation and type translation between the web layer and the business layer (pretty boring stuff indeed)

- in the IDE, designing a web user interface has become simpler and more productive since JSF support is built-in and not only an a not-so-well-designed-plugin. Many components are designed on top of basic layers (Servlets and JSPs), so you normally shouldn’t bother about them.

Data Aware components

JSF toolkits offer also the possibility to use data-aware components in a web oriented paradigm. This way you can expose a RowSet directly on the web page and rely on the data-aware component for synchronizing page data with the underlying database. It’s definitely not OOP but it might come in handy in many cases.

The main message is probably intended for the average orphan Delphi programmer: “your paradigm works in java as well, and on the web too!”.

Everybody happy?

So, looks like the Java web developer is now given two tools when constructing a simple web application. Anyway my feeling is that data-aware components are just a bad idea for a developer with a J2EE background.

1) data-aware component are popular in not-so-OOP languages (ok, languages jave OO capabilities, but I’ve never seen a VB programmer define a domain model), in such a scenario your application is just a collection of CRUDs (create-read-update-delete) and this is not exactly a great idea.

2) You have to define a place to put your business logic anyway, and since JSF allows you to use POJOs …why not use the POJOs? If you prefer to put all of your domain logic in the presentation layer you’re free to do it, but I have to warn… you’re probably going to hurt yourself.

3) Data-aware components fits well in closed client-server architectures. Here the architecture is not so close, we’re already on the web, so the chances for exposing a service on another channel (be it a web service, or a palm interface) are far higher than before.

4) Tools like Hibernate, or Spring really make data-aware component less interesting. Off-the-shelf ORM tools weren’t that popular in the client-server days, but now they really are part of the scenario. It was different were EJBs were hype, cause “domain modelling” really sounded like “business layer”, and this sounded like “EJB” (or worse: “entity beans”) meaning finally “heavyweight mess”.

So, even if some debate is still going on, I really think that data-aware component aren’t that interesting for somebody with a java background. They might come in handy for newcomers to the java platform that can postpone learning some heavy topic in the J2EE landscape for a while, but it really sounds like a short-term choice.


Tags: , ,

Sunday, July 30, 2006

Why CRUD use cases are intrinsically evil


When performing analysis for a new system, many people find useful to shrink several use cases in a single one, and tagging it with the CRUD stereotype. This choice has a clear advantage in terms of readability of the use case diagram, while the stereotype (often associated with a different color) just triggers a multiplication factor when defining estimates for development time.

Readability and estimates are just a small part of the game when it comes to actually design the overall system. A Use Case is intended not only to be a measurement of the overall complexity of the system, but also a useful tool to capture the real goal (for a good exploration on the matter, please read Alistair Cockburn’s Writing Effective Use Cases) of the different parties involved in the use case. Just a simple order-invoice combination cannot be well represented by two CRUDs due to the many interactions possible between the two data types.

A system made up by a pile of CRUD usually ends up in a data-centric application, where part of the complexity of the interaction between different data types becomes a burden on the user, instead of a system’s responsibility. A user-focused use case (or an XP-like user story) should instead capture the flow of the interactions between different data types. If you’re not modeling what lies beneath a CRUD and another one, you’ll simply have to face it later on in terms of cluttered implementation or a not-so-usable application.

Separating use cases concerns
In nontrivial systems I found useful to separate the different concerns by defining two layers of use cases:
  • Business Level use cases focus on the user interaction with the system, they provide a detailed description of the user’s goal as well as other party’s, and span across multiple data types;

  • Implementation Level use cases focus instead on the artifacts needed to realize the use case, such as web pages, persistence methods, complex data manipulation and so on, generally tied to one or few data types.
The first layer depends on the second one for the implementation, and in trivial cases there is no need to separate them.

Testing the resulting system
A not-so-small difference in the two styles is that we can choose which use case layer is best suited to provide the specifications for building our test suite: at the business case level we can probably test more with less effort, and catch some awkward combination of data that tests based on the implementation level couldn’t catch. Of course the better combination is to define (unit) tests for the implementation level to be used as bricks for the business level tests.

If acceptance test are to be run by a real user, they’ll probably follow some path defined in business level use cases, instead of merely trying to add or modify some data and see what happens.

Enter the domain model
Such a modeling style, prepares the background for a domain model type of system (as opposed to the data-centric one). If we are to model something which lies in the correlation between two or more different data types, the best place to define it is in the domain model, be it in the component behavior or in the use case controller class. The default choice for data centric systems I’ve seen so far, has always been presentation layer… :-(

A significant exception
Apart from very simple systems, data centric applications (and thus CRUD-like use case modeling) are the best choice when the overall business processes aren’t completely defined, so instead of having a complex, but incomplete, system driving the user (possibly to a dead end) it’s probably better to have the expert users in control, and let them the possibility to tweak the system as they need (a possibility greatly appreciated in call centers, for example). However, this situation it’s not a great symptom of the whole organization’s health (but might be the driving force in a startup, for example), more often it is a sign of a poorly done analysis.


Tags: , ,

Saturday, July 29, 2006

Java Conference presentation available

SUN has published the presentation we gave at the last Italian Java Conference. The downloadable material is here.

Tags: ,

Monday, July 10, 2006

FIFA World Championship 2006


Campioni del mondo!!!

Campioni del mondo!!!
Campioni del mondo!!!
Campioni del mondo!!!
Campioni del mondo!!!
Campioni del mondo!!!
(Who cares about J2EE....)