mercoledì 25 novembre 2009

Compile time constraints and runtime constraints: WhiteCat merges both!

Due to the reviews on a WhiteCat paper I received, and the claims from a colleague of mine, I decided to write a little post about my way of thinking OOP and how I conceive it with WhiteCat.

I started developing serious applications using Java version 1. If you remember, at that time there were no fancy features, so the only thing you could have to do to decouple your code was to have a good OOP design. What is a good OOP design? It is a strictly typed system.
Am I a strictly-typed kind of developer? Yes.

In my early stage of software designer I was used to create classes and interfaces as it was raining cats and dogs! Then I read THE book about Perl (Programming Perl) and a statement by Larry Wall really impressed me: Larry wrote that there must a balance between programming-in-a-rush and programming-by-presumption. What does it mean? It means (to me) that if you are a pure OOP designer/developer you will start thinking that you are not developing only a piece of software to solve an assigned problem, but you are creating a creature that everybody could/would use. This leads to a class/interface storm, since you are taking into account every possible use of your piece of software. I was such a developer!
Now I've changed my mind, and I've found a good balance between rush and presumption.

How does my OOP mindset connect to the WhiteCat approach? Well, of course WhiteCat is a creature of mine, and therefore it has been developed following my ideas and design/developing habits. But this of course not the answer you want to read.

WhiteCat is a very dynamic system, and usually dynamism is at the opposite of strong typing (think to Python for instance). Since I am a strictly-typed designer/developer, how can I accept a very dynamic system like WhiteCat?

Short answer: Liskov substitution principle is guarantee to work, so the type system is ensured to work.

Do you need a more detailed answer?
When you compile an application you accept the compiler rules. A strict compiler leads to a typed system (secure), while a weak compiler leads to an untyped system (more dynamic, less secure).
WhiteCat agents, roles, and framework itself is compiled thru a standard Java compiler (well, to be onest thru an AspectJ one), so WhiteCat components obey the same compiler rule.
But WhiteCat allows developers to dynamically change the class definition at runtime; does it means that compile rules are overtaken? No, since WhiteCat guarantees the Liskov substitution principle to work. But this is not all folks: WhiteCat imposes compile-time constraints at runtime! This is the very soul of WhiteCat: being able to start from a strongly-typed system (your agents/role compiled thru a Java compiler) and to modify them at runtime as they were compiled in a different way (i.e., starting from modified sources).
So WhiteCat starts from a typed system and leads to a typed system, but in the middle it is able to change the types in order to improve your agents/roles.

Was this the same as RoleX (a.k.a. BlackCat) did? No, because BlackCat was changing dynamically the agent class making the Liskov substitution principle not applicable. In other words, BlackCat was very dynamic, but started from a typed system to get to an untyped (and unmanageable) system. This is the real difference between WhiteCat and BlackCat.

Nessun commento: