This blog is no longer being maintained, please go to The missing link of Agile instead

Wednesday, April 29, 2009

It's not about how fast you code the requirements but how soon you get them right

The actual software is just a byproduct of the process of building an understanding of a given domain.
Jonas Bandi

The misconception behind the RAD tools comes from the desire to implement the software (ie. do the coding) as quickly as possible. People believe that producing software is hard - and they're correct, it really is! The problem is that it is not the implementation that is tough. Meeting blurry, vague wishes of your client - sometimes erroneously called requirements - is the hardest part in software development. And unless you work on really dumb system for feeding the data using few hundreds of forms (which most probably means you do software for govmt) you really need to get the domain right.

On all projects with non-trivial business domain you spend most of the time analyzing clients requirements, evolving (expanding and refactoring) the domain model to meet your clients demands. You spend hours in front of the whiteboard with the marker in your hand talking about the domain. You do Proof-of-Concept, you revert, do it again, revert.. And then if you're totally, 100% sure what's really going on in this damn business domain (and BTW most probably you're still wrong about it ;)) you go to do some front-end, mailing, logging and all that supportive stuff.

In my first job I had a teammate who was a decent programmer but he shone big time. I spent a gigantic amount of time on learning every detail in technology we used and I knew the class model very good. He knew just enough about it but still when it came to talking about the project he always knew better. The thing was it that he focused on and understanding specifics of business domain what almost always gave him massive advantage.

Most of the time you do the knowledge crunching.

Tuesday, April 28, 2009

OO design, reuse and serendipity

Steve Vinoski said pretty wise stuff about reusability of REST-based systems. He said that powerful stuff as Unix small languages was probably incidental just because the design (unix pipe) was based on modularity and simplicity.

It is entirely the same for Object Oriented design. Keep your interfaces simple (ie. make them have clear boundaries [PDF warning!]) and your abstractions simple (ie. having clear and sharp definitions [PDF warning!]* - and modularity comes for free. Simplicity enables modularity!

The important part is that, what is easily forgotten, reuse is not only about using parts of the code on different projects - this should actually be quite rare - I mean most of the time you use external frameworks to do generic stuff.. don't you?. But you should constantly reuse domain classes by using them second, third and nth time in different contexts. And by different contexts I mean implementation of the most exotic requirements of your clients. It's definitely not a good sign if you catch yourself saying "naahh.. we can't use that method for the new requirement, 'cause it's doing this thing and the other thing to do that stuff here.. here.. and over theeeere.. we gotta write a new one".

What you might rather try is:
- refactor (decouple),
- test,
- reuse.

Do it KISS, don't strive for too much generality, but do it right! After the umpteen requirement (and refactoring) you'll be amazed that you have evolved a very sharp abstraction with clear boundaries. Moreover you gained a fair amount of domain knowledge because you kept on building larger coherent structure and not only solving single problems. Always remember about GPS** (Gain Perspective Stupid).

"Serendipitous reuse" is definitely a good sign and if you do OO right it'll come for free.

* The rule of a thumb is that if you have to use two metaphors (or more, sic!) to explain a role of an abstraction to the person from outside the project it means that your domain model stinks in that particular area.
** Coined by my good colleague and great software developer Piotr Wójcicki.

Wednesday, April 22, 2009

My view on different level of abstractions in OO

Lately I've been trying to invent my very own classification of classes of abstractions you come across when creating object-oriented software. As every more-or-less formal classification it should give me (at least that's what I hope for) a possibility to infer various qualities and evaluate use-cases for each of the class of abstraction. It also gives you quite a nice foundation to introduce heuristics and conception of refactorings from/to certain class of abstraction.

I've come up with the idea of 3 categories which I call "nth class citizens":
- 1st class citizens - (abstract) domain classes,
- 2nd class citizens - (abstract) classes included in general purpose libraries - various data structures (eg. Collection, Set, Date, etc.),
- 3rd class citizens - primitive types and classes (eg. int, Long, BigDecimal).

In case of 1st class citizens the main problem is the metaphor. Every abstraction is described by either an abstract or real entity constituting its role. It is not always possible to model a goal and responsiblities of an entity in a programming language of your choice. It may happen that an object lose some meaning or demonstrates additional features. The first issue is easy to resolve as it requires us only to judge whether the lost qualities were necessary to fully express the intent of object existence. As for the latter:
- demonstrated features (qualities) may be the actual functions of the modeled abstraction - in this case by incident we get the useful extra "feedback of the metaphor",
- the new features have nothing in common with the modeled abstraction - the domain model is contaminated with false information. These features cause unnecessary confusion and draw away the attention of developers from the actual intent of choosing certain abstraction.

2nd class citizens use a general interface to communicate (this interface have a precise definition in the domain of computer science). Incidentally it matches the one of a modeled business domain. In most of cases (as in 80/20 rule) there is no need to hide the information they share with the external world - you should just use the standard "wide" general purpose interface. There is however a danger that:
- there are in fact 1st class citizens in disguise (eg. Set<Map<Account, Order>>),
- they either share too much information or their messages are too generic and hard too understand by their collaborators. In both situations they should be rather represented by 1st class citizens (implemented with encapsulation).

3rd class citizens, well... they just exist :). In most cases you just push them around - and in 99,999% of situations you should not use them to perform any business operation (eg. DON'T DO chargeClient(BigDecimal price)). They should always be "represented" by 1st class citizens (encapsulation).

This article is one of the first drafts and I hope I'll come back to this topic. There is never enough of polishing object oriented modelling, design and implementation skills! :)