Saturday, November 26, 2005
Shape Code After Language
Shape code after language, or Shal if you need an acronym to remember it.
The idea of deriving design concepts from user vocabulary is not a new one.
Needless to say, I drank too much coffee, I started wearing black turtlenecks and I didn't get much done at all.
I developed a bad case of writer's block. On one hand I couldn't go back to 'just coding'. On the other hand the design hyperuranium was so full of possibilities that I just didn't know where to start from without tying myself up in conceptual knots.
Anyway, while I was floating in Plato's hyperuranium, somehow it occured to me to read the missing chapter. It is there that I found a simple powerful technique.
1. Write down what you understand about the domain in plain English.
2. Nouns should be classes
3. Verbs should be methods
These days I try to evolve my code by the motto: "If it's easy to say, it should be easy to code".
Now, the thing is that 99% of user requests are very simple and reasonable requests within the users' own model. If you can distill that model, you will be able to make them feel understood. And it's true: you will genuinely understand them!
Your software will have become a true nooartefact - an artefact encoding business knowledge in executable form. Much more than what we think of as being an application.
Evans had some very profound insights, yet I see people that have read the book asking questions like "should a Repository be implemented as a Singleton?", as if DDD is dealing with fixed patterns. I believe that Evans has opened a door on fantastic new possibilities, but most of the community is still fixated on the door frame and doesn't see that there is something beyond the threshold.
Then the unthinkable happened. I gave in to Vb.
I stopped trying to write java code in Vb and I just tried to do the simplest thing within the Vb language.
That was when I discovered Shal - Shape (code) After Language
Shal is a principle that I discovered over the years, while playing with different formats of coding and modelling. Shal is about allowing user language to drive your code production, not only on a modelling level, but as much on the micro-level as possible.
The idea of deriving design concepts from user vocabulary is not a new one.
I believe I read about it for the first time in what we have always called The Booch Book, but that you can find in bookstores as Object Oriented Analysis and Design. This book is definitely a classic, a must read for any developer. It is by reading the booch book that I came to realized that whenever I was writing code I was actually modelling. It was this insight thet started me focusing more and more on the design aspects of what I was doing.
After a while spent thinking about design I felt into the trap that these days is known as BDUF (Big Design Up Front). I started feeling that I couldn't even touch the keyboard until all the design elements were clear in my head. I was coding less and less and I kept haunting coffee bars where I spent hours scribbling and leaving behind a trail of napkins covered in cloud-shaped diagrams.
I remember that modelling felt like planning a platonic ideal world, later to be incarnated in code. The clouds would have opened showing the shining design behind them, as a beam of pure rational light would have moulded the humble software clay into an earthly embodiment of my model. The code was a mere detail.
I remember that modelling felt like planning a platonic ideal world, later to be incarnated in code. The clouds would have opened showing the shining design behind them, as a beam of pure rational light would have moulded the humble software clay into an earthly embodiment of my model. The code was a mere detail.
Needless to say, I drank too much coffee, I started wearing black turtlenecks and I didn't get much done at all.
I developed a bad case of writer's block. On one hand I couldn't go back to 'just coding'. On the other hand the design hyperuranium was so full of possibilities that I just didn't know where to start from without tying myself up in conceptual knots.
The booch book had put me in this situation, but it also helped me to break through it. You see, while reading the book for the first time I had skipped the chapter on analysis. Analysis was for wimps! Wasn't it true that analysis was that thing that coders that couldn't program were doing? The fact that analysts were wearing suites while posing as wannabe white collars didn't really help their credibility at the time.
Anyway, while I was floating in Plato's hyperuranium, somehow it occured to me to read the missing chapter. It is there that I found a simple powerful technique.
1. Write down what you understand about the domain in plain English.
2. Nouns should be classes
3. Verbs should be methods
Amazingly it worked. It was as simple as it was effective: I could translate ideas to design and I could derive my code from it. Suddenly I was back in business.
There was just this nagging uneasy feeling about some mysterious subterranean link between words and design, between words and the world. However I wasn't paying it too much attention - it was just a cool trick that I could use to kickstart my design. After doing this verbs and nouns analysis thing I had some good raw platonic material that I could chop, stretch and abstract into orbit, away from its humble origins in the user language.
There is a subtle point here - at the time I felt that the analysis of user language was just helping me to look in the right direction where I would have eventually found some kind of perfect design. These days I tend to think that the design is already there, in implicit form, in the user's language, but I'll get to this point later.
The next big conceptual step in the direction of Shal came many years later, while reading the ground-breaking Domain Driven Design book by Eric Evans. I wasn't really looking for that kind of book. I was hunting for some Xp stuff. After all design was so passe!
Design was just the intellectual hubris of neo-platonic structured thinking and intelligent design theories. The stuff that worked evolved from the bottom. The intelligence was not in the coder and was not in the code, but somehow it was in the whole, it was emerging and unfolding as all the parts interacted, respectfully listening to each other and adapting around the problems.
Design was just the intellectual hubris of neo-platonic structured thinking and intelligent design theories. The stuff that worked evolved from the bottom. The intelligence was not in the coder and was not in the code, but somehow it was in the whole, it was emerging and unfolding as all the parts interacted, respectfully listening to each other and adapting around the problems.
Yet, there was 'Domain' in the title and I think I remembered that the xpers somewhere were saying you should listen to domain experts.. so I went for it. Plus the hard cover with the Kandinsky picture looked great.
The DDD book changed the way I think about software. While reading the book I had this continuous stream of epiphanies as I started re-interpreting a number of situations in a different light.
The users had the model. We were just trying to dig it out through careful questioning.
The users had the model. We were just trying to dig it out through careful questioning.
The users had the model but they didn't know it explicitly. We were going to unfold it, in a very xp kind of way, but we were going to create a model, a design that was going to map to user language. Often to the very words of the user language, as Booch suggested. Amazingly if code was aligned to the user language, then things that could be expressed in the user language could also be expressed into code.
This was an incredible eye opener. The user language was not just a starting point for design. The deep user language was the goal of design!
These days I try to evolve my code by the motto: "If it's easy to say, it should be easy to code".
If you can make code that behaves as the user language then you don't break user expectations. When your model is not isomorphic to the user model, the code will not be very reactive to new user requirements. Every time users will ask for a little change, it will take you a long time to express it in code, and this will leave the users frustrated. This happens because this change is totally simple within their implicit domain model, and they don't see or understand your software model.
If you write your code so that "If it's easy to say, it should be easy to code", then they will find acceptable if it will take you a long time to code something that they have trouble explaining in the first place. They will perceive it as a complex concept, and they will understand that it will be complex for you to produce as well.
Now, the thing is that 99% of user requests are very simple and reasonable requests within the users' own model. If you can distill that model, you will be able to make them feel understood. And it's true: you will genuinely understand them!
Your software will have become a true nooartefact - an artefact encoding business knowledge in executable form. Much more than what we think of as being an application.
I am amazed by the fact that Evans and DDD don't have a larger following. I have given the book to a few people to read, but they didn't seem over impressed. They seemed to feel that meddling with the domain was contrary to their domain-agnostic software engineering purity.
Evans had some very profound insights, yet I see people that have read the book asking questions like "should a Repository be implemented as a Singleton?", as if DDD is dealing with fixed patterns. I believe that Evans has opened a door on fantastic new possibilities, but most of the community is still fixated on the door frame and doesn't see that there is something beyond the threshold.
After having read about DDD I had another short milder case of BDUF. This time around I didn't start dressing in black, but I started using crayons to sketch domain models. I still drank lots of coffee. It must be one of those Hegelian thesis-antithesis struggle things. You believe one thing, then you convert to the opposite, then you abstract them together and move on to a new struggle on a higher level of knowledge.
At the time I was reading Evans' book, I also started working with Excel and VBA on a daily basis for my job. I had been programming in Java for many years by that point, and this turn of events seemed a bit of a step back. I didn't give up and I took it as a challenge - writing good code under extreme conditions.
The philosophy of DDD inexorably trickled down to the VBA code. My code started taking new shapes, struggling against the rigidity of the programming language. Then I started applying a few tricks that Evans suggested in the book. Things such as method chaining and object algebras.
The philosophy of DDD inexorably trickled down to the VBA code. My code started taking new shapes, struggling against the rigidity of the programming language. Then I started applying a few tricks that Evans suggested in the book. Things such as method chaining and object algebras.
My code started acquiring more character and usability, but it was still weighted down by an excess of pattern-like code and design habits. I had factories, repositories and configurators lying around, obscuring the domain model.
Then the unthinkable happened. I gave in to Vb.
I stopped trying to write java code in Vb and I just tried to do the simplest thing within the Vb language.
Then I stopped trying to write Vb code according to the classic Vb style. I started making heavy use of Variants, while trying to make clear the semantics of the arguments that I was passing, rather than focusing on the syntax and on the types. My methods could digest arrays, collections, dictionaries, excel ranges or strings, as long as the concept that I was passing to the method represented a "sequence of elements". The disambiguation was happening inside the method itself, where I handled the different types case by case.
This simplified the model enormously, cutting off a huge amount of fat. Then I started breaking all rules. I had functions and classes and methods with the same name. I played with syntactic ambiguity, while avoiding semantic ambiguity in the user domain model.
I had module constants without prefixes indicating which module they were from. I was accepting untyped parameters everywhere. I used singletons. I made heavy unnecessary use of named parameters. I abolished the use of 'New' and I had functions to build even the simplest objects. Except that sometimes the functions were building objects and sometimes they were not, and you had no way of knowing without looking at the code.
I had module constants without prefixes indicating which module they were from. I was accepting untyped parameters everywhere. I used singletons. I made heavy unnecessary use of named parameters. I abolished the use of 'New' and I had functions to build even the simplest objects. Except that sometimes the functions were building objects and sometimes they were not, and you had no way of knowing without looking at the code.
Eventually the surface layer of my code started resembling the user language very closely. Users were incredulous when looking at the code. They were understanding the meaning of what was written and they could even make simple changes without my help. The people that had more trouble were the other programmers and those users that were trying to apply plain vanilla OO to it. They were asking "Is that an object? does it accept collections or arrays?". I was just replying: "It doesn't matter if it is an object. Look at what it represents, read it out aloud, and see how it gets used."
That was when I discovered Shal - Shape (code) After Language