What do the Macarena and the GoF's Design Patterns have in common? They all became wildly popular in 1995 but in the following years experienced a large backlash from overexposure. There have been many arguments against Design Patterns as practiced in software development, chiefly that they promote over complicated code and that they really just paper over what should be seen as core deficiencies in mainstream object oriented languages.
The original inspiration for the design patterns movement in software was Christopher Alexander's The Timeless Way of Building. Somewhere from Christopher Alexander's original text to the software industries adoption of design patterns, the very soul of his meaning was left behind. Envision for a moment the stereotype of a hard core believer in software design patterns. Their code is designed all up front using UML and every class is named after one design pattern or another. Often times even multiple of them, such as the FooBarStrategyAbstractFactorySingleton. They create big inorganic design, suitable to distinct job roles where one can be an architect that doesn't design, a designer who doesn't code and a coder who does as they are told.
The spirit of the timeless way of building is to evoke that quality without a name. Some buildings are just lifeless, cold and somehow wrong. Others have a cozy liveliness that just feels comfortable and right. To obtain the quality without a name, one has to look at how such designs organically arose and the micro principles and patterns they applied. The centrally planned cities, strip malls and cookie cutter suburban homes all lack this organically grown life.
This is the central problem with how design patterns are applied. They are used to dictate design as if it is something that can be rigorously planned rather than something that is adapted to. This is why so much enterprise code feels so bloated and lifeless, it lacks the natural flow and elegance of code that is designed to fit a specific problem rather than trying to fit into a wholly consistent uber architecture.
How does a developer achieve that quality without a name though? No one intends to write bad lifeless code and please don't tell me this is just a problem for bad programmers. I'd like to know what people think. Have you ever written code that was great and had that quality without a name, not only at initial conception, but actually got better and more elegant over time? How did you do it? What about code that you thought was great at first, but quickly showed its age as the requirements shifted? What went wrong?
Ah, how silent this train has been.
My favorite example of an organic code was the UI at BookSurge. I recall discussing their UI vs our BookAdmin, and it was obvious that the page had been tweaked and prodded until it was just what they wanted - all the important stuff in plain sight.
As for the unweildly, scary beasts...
I vividly remember Josh defending the Workflow code used by the TSW as the best solution to the problem; and that the workflow section itself was so handy he wanted it for other projects. But I don't think anyone else uses it, and most of the staff thinks the TSW works on magic pixie dust.
When I first wrote the old disc accounting it had alot of design aspects that were later discarded (and trampled on for good measure). Pricers were meant to be immutable objects to make sure nobody was ever charged a different amount than they saw. It just didn't hold up to the use cases after it's conception.
Posted by: Pete | February 27, 2009 at 10:31 AM
I think pixie dust is a design pattern. In defense of the TSW it is also used for that Cart thing, though at times that feels forced.
There are a few aspects to reusable software I have observed.
1) Distance from lowest common denominator
2) Illustration and example of implementation
3) Advertisement of availability and benefit
The components come together to form a path of least resistance.
Libraries are inherently reusable. They have all these aspects. Take struts, a MVC promoter, for example:
1) Achieves the lowest common denominator by providing the common actions required to present a web page allowing a standard formula.
2) Tons of documentation and usage.
3) How did we end up with it?
Now let’s look at something like the TSW, assuming it could be wrapped up in a jar and shipped.
1) Domain specific to wizard solutions, actual reusable component much smaller than presented product which is integrated with a web framework.
2) One primary example, no good illustration of a generic usage.
3) Not really pushed as a reusable component when thinking about future projects… found a way to use in Cart.
TSW is primarily not reused, because there isn’t a huge demand for wizards, the pattern does not promise performance or a great benefit. The amount of reuse is minimal compared to the individual implementations. It is not necessarily state of the art.
Would we ever make a csp-tsw module?
Now let’s look at the idea of a design pattern.
1) Always attempt to solve a problem on the lowest abstract level, with awareness of implementation, but no detail.
2) Are UML’d up the waZoo, always presented with examples.
3) We read books on them in school, we write blogs about them, we gain comfort from common abstraction.
Number 1) has an important point: “awareness of implementation.”
The idea of a design pattern is inherently reusable, developers flock, hoping to make things easier, to makes things easier. We choose others’ patterns, looking for a correlation of implementation, or bending our implementation to match the pattern.
It should be the other way around. We should look at the problem, deeply think about a lowest common denominator design pattern, compare that solution with other existing patterns, determine if any can be used or learned from, and then solve the problem in a reusable fashion. Writing your code like it would be a library; meeting the common need, providing the basic example, providing the possibility, and pushing it up to the PMs.
Posted by: daZip | February 28, 2009 at 11:48 PM