I learned recently that the word "kung-fu" refers to "an art which requires practice for perfection" rather than any particular practice. So that means you can have kung-fu tea brewing. I'm awfully fond of the coding-as-martial-art metaphor, so you can imagine that this discovery pleased me greatly.
It led me to another comparison too. I took grade-school Tae Kwon Do like every other kid who was my age when he saw The Karate Kid, and I come back to the idea of forms: sequences of moves that are practiced the same way every time. At the higher levels these forms involve such simple acts as taking a deep breath. I didn't connect this at the time, but I realize now that the Tae Kwon Do forms are about details. About practicing until you are familiar with the details of the skill. Where you put your index finger. When you breathe in; breathe out. The idea is that in actual combat, you execute these moves perfectly and put them together without even thinking.
For software developers, the early Forms take the shape of correctly writing a loop iterator that removes items from a list or implementing a simple recursive routine to descend a tree. The later forms start to look more like design patterns, but I think the two are different, though related.
I've been doing a lot with patterns lately, as Laszlo's Webtop product implements and elaborates on a number of well-known software design patterns to move them into the realm of the AJAX client/server infrastructure. Some of these patterns are the most well-trod ground in the dark arts of framework writing: Object/Relational Mapping. Windowing. And of course the most abused and misunderstood: Model-View-Controller.
Now, it's frowned upon to even embark on such a project. What about the miracle of open-source? Why reinvent what's already been created? I've been thinking a lot about this, especially about it in terms of practice and mastery.
What's interesting about all of this is that of course there are many implementations of these things that we could have leveraged. We've looked at tons of these, but none quite fits the bill. In JavaLand, the game plan is to take a bunch of big pieces that don't quite fit together and then encase them in molded Styrofoam so that they do. This works ok when you can add computing power as your needs grow, and also when you are the end user of whatever utilities and classes you are writing. But of course, our client has real performance constraints, and we want people to use our SDK, so after looking carefully at the options, it did seem to make sense to introduce yet-another ORM system; yet another XML protocol, and yet another client MVC system.
What I didn't expect when embarking on this, but what's clear to me now, is that even though these forms have been handed down through computer science history, there's still work to be done: work to both adapt them to today's infrastructure and to clarify and beautify their underlying abstractions.
Let me take the example of the Model-View-Controller pattern in Webtop, though any major piece of the Webtop framework would make a good example. In writing this part (actually writing and rewriting — you simply don't get things like this right on the first try no matter how carefully you design them) I had a deep insight into the real motivation for this pattern that I couldn't have guessed at from the perspective of a UML diagram.
In general, the literature on MVC tends to emphasize the separation of concerns aspect of MVC, and (I think) muddles the explicit relationships among the various players. Consider this diagram from the MVC article on Wikipedia:
Sure, I suppose it's nice to have an explicit domain object (model) that is different from the code that decides what to do with it (controller), but if this diagram is to be believed, then each of the players in the pattern is coupled to the other.
Part of the confusion here comes from Sun's co-option of the phrase "Model-View-Controller" (or "Model 2") into a specific usage within the context of server-generated web pages. In fact, the Struts-style controller and its associated views are pretty different from the original Smalltalk notion of the same. This is especially true since in a real client, unlike a web-based application, it's hard, if not impossible, to centralize the flow of application control in one place.
This is not to suggest some sort of primacy of the framer's intent when applying a pattern. In fact, even the original literature on the subject is fairly confused, with different authors assigning different roles and meanings to each of the terms. So when we adopt a framework and its pattern without practicing its underlying form, we're not aware of the broad spectrum of possibility around how to think about the problems we're solving. It's really only by practicing one of these forms that we can see the trade-offs and possibilities in the underlying abstractions.
To bring this back to the insight I had while working on the Webtop MVC framework, I began to think of MVC like this:
If we say that the view forwards all state change to the controller, and that the controller is solely responsible for updating the model, then we end up with the following lovely invariant: the view only has respond to changes in the model to present itself correctly. This means that we can write a view which is stateless; given a model it can always know how to display itself, no matter what the user or the underlying data model is doing. Now in a web server, this isn't terribly important: the state of a model is pretty much static while it is being rendered. In an AJAX app, however, this is critical, since updates may come from the user or the server at any time.
Despite this insight, we didn't put fully realized controllers into Webtop in
the end. Instead, we split the controller function between our views and our
models and introduced a separate "process" element to coordinate asynchronous
processes. Views manipulate and represent models; models enforce domain
invariants. Nevertheless, practicing the MVC form lead to some clean
abstractions that make it easier for Webtop users to deal with abstract data
The conventional wisdom says that the best programmers never rewrite code when there is a useful framework that can be integrated. That's only part of the story. I think that the very best programmers have a secret weapon: badass kung fu.