Return to Home Page
      Blog     Consulting     Seminars     Calendar     Books     CD-ROMS     Newsletter     About     FAQ      Search
 

8-16-04 Process Patterns

Last week, Bill Venners and I gave the Designing Objects & Systems seminar. Each time we've given it, it has been unique, and one of the hard things about marketing the seminar is explaining just what kind of experience it is. This version was even more interesting than usual. Partway through the seminar, after we had been introducing and discussing any number of different ways that various people have invented to discover the objects and their structure when designing a system, a couple of people observed that all of these hand-waving descriptions of other people's design tools were not helping them with their team project. In storytelling parlance, we were "telling" rather than "showing." In order to "show don't tell," how about if Bill and I came up with a design for a problem that we had not seen before, live, in front of the class?

This turned out to be quite stimulating for us, and it seem to give everyone a boost. One of the important things that we had been discussing is the idea that there was "no right way," and sure enough, we both attacked the problem in different ways. Bill is prone to thinking in terms of Java interfaces, and the problem statement we were given did in fact request interfaces as the deliverable. However, it also gave a lot of detail about the model (which is what the students who created the spec were actually looking for, it turned out, despite their specification of interfaces), and I went in that direction, because that is my bent.

With all OO analysis techniques, the goal is to (at least) produce objects, their interfaces, and their relationships. Bill and I did that, in our different ways. All the different techniques that everyone else comes up with produces those three things (and sometimes a lot more). We both have different experiences and backgrounds and those have combined to influence the way we approach problems.

Switching to a different example, consider the discussion that I and others have been having about static vs. dynamic typing (see earlier weblogs). If we can smooth over some of the bumps and say that C++, Java, Python, Smalltalk, Lisp and similar languages are strongly typed (yes, I know it's possible to use casts to push both C++ and Java into runtime exceptions, but in the absence of such casts they tend to behave themselves), and that the issue at hand is when such typing occurs (static -> compile time, dynamic -> run time), then the arguments seem to come down into two distinctly different camps:

  1. I need every possible type check that I can get, imposed as early as possible. Even with all those type checks, problems slip through, so if it's possible to add even more compile-time checking, that would be better.


  2. The extra verbiage that must be added in order to make the compiler happy doesn't really accomplish that much and has a severe impact on both productivity and code maintenance. We have to write unit tests anyway, so the illusion of safety comes at far too high a cost. Ned Batchelder put it another way: "Static typing prevents certain kinds of failures. Unfortunately, it also prevents certain kinds of successes."

I started out in the first camp, seeing all the problems that C (especially pre-ANSI C) allowed, being firmly staunched by C++. I stayed in that mindset with Java, which seemed to do a better job than C++ (with things like checked exceptions). After a brief bout of Perl (great for quickly writing code, bad for scalability and maintainability) I moved to Python and began puzzling through both dynamic and latent typing (see previous weblogs), wondering why these things which went against my experience nonetheless seemed to work so well, eventually moving into camp #2 and finally understanding what the Smalltalk programmers had been saying all these years.

When I had the internship program a couple of years ago I moved back towards camp #1. The interns were generally inexperienced and they needed rules. Even then, they would sometimes actively circumvent the the rules. Only the rules that were built into the compiler couldn't be circumvented, and thus took on the nature of "received wisdom" to the interns who could then believe it. The additional rules that I either added as written guidelines or tried to impose via CVS checkin rules were sometimes seen as my arbitrary constraints and did not have the religious weight of being part of "the language," and so were sometimes ignored or disabled.

On web discussions, this is sometimes referred to as "having a bunch of programmers with a few weeks of Visual Basic training." BASIC was my first language and over the years I accomplished many things with it, so I don't think that this is saying VB is bad. (Indeed, I am far too experienced to imagine that I shall never be in a position where I must use it again). Instead, I think the phrase refers to programmers with very limited experience and world view. That is the big difference between the first and second camps -- they are dealing with different kinds of programmers.

My father was a building contractor until he retired. I saw many different kinds of subcontractors, all of whom would say that they "worked on houses." But when I worked for my father (an experience that not only motivated me to stay in college for a rather long time, but also to develop a different profession; the point of the exercise, his chief carpenter explained to me), I put up sheet rock (drywall) just like the sheetrock subcontractors would. I took apart old plumbing but I never put together new plumbing. I did a little bit of carpentry but never finish work. And yet I could say that I "worked on houses," much the same way that I could say that I "programmed computers" sometime after I began to do that. But for a long time I was more of a ditch-digging, sheetrock-hanging kind of a computer programmer, who needed a lot of direction. You wouldn't want me anywhere near a tool when the finish work was going on.

In Tom DeMarco's book Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency, he talks about the illusion of treating people as "fungible resources," where one person can easily be replaced with another. I suspect this idea is more predominant in programming, where the mystery of the craft prevents the average manager from having any concept of what programmers do. Programmers type code, and code looks like a bunch of words. Why can't one programmer be replaced with another?

But as in people who work on building houses, there are vast differences between programmers. I would say the main division is between those folks who treat programming as a saleable job skill (and who have other lives and interests, which is certainly admirable) and those for whom it is a profession, a craft, an interest, a pursuit on its own, and a passion.

This is only a rough distinction, of course. People who consider programming "just a job" may still dedicate themselves to doing the best they can while they are on the job, and people for whom it is a passion may still fritter away their time being passionate about their favorite language on the web, or playing games.

A second division is experience. The maturation of a programmer is almost certainly linked to their personal maturation. Life experience influences the way you think. Our ability to model, and to implement that model, is all about thinking, perception, and the ability to organize and manipulate thoughts and perceptions. And of course, to interact with other people. These lessons don't come easy.

A third important issue is the ability to understand that -- even though we ultimately work in a world of ones and zeroes -- things are often not what they seem, and that an open mind along with a well-developed sense of critical thinking are the most powerful tools you can have. I don't know if it's simply experience that teaches this, or if additional factors like training and mentoring are involved (although it is certainly tempting, given what I do, to assert the latter, but that would suggest that I myself have not yet risen above the one/zero mentality, and I like to think that I have).

Is there some way to manufacture experienced programmers more quickly? A group of folks who write, consult, and educate about programming met in Portland, Oregon January 15-17, 2003 for the "Writing Better Code" summit, where we tried to struggle with the issues of why programming continues to be practiced in a poor fashion, and ways that the situation might be improved. I think because the problem is more about psychology and individual growth than anything you can apply rules and guidelines to (as we digital types are wont to do) we didn't achieve much. The only resulting artifacts that I know of are an article on Artima and Chuck Allison's address to the computer science class at his college (which will appear on the upcoming "Thinking in Code" audio interview CD; subscribe to the newsletter to be notified when that becomes available).

What I want to explore here, however, is the corporate cultures that promote or demote good programming practice, and support or discourage learning. More specifically, not so much whether you are a "learning organization" (to use a business-fad word from some time in the past few years) but how you got the way you are ("One logical step at a time," according to Gerald Weinberg in Secrets of Consulting).

The question I'm asking is this: is it possible that the apparently endless variety of organizations that we see are based on permutations of a finite set of fundamental patterns, and that if we can discover these patterns we may be able to better understand and even improve these organizations?

Here's a candidate pattern partly based on the above static-vs-dynamic typing discussion. We can take a first shot at naming: "Programmers as Commodities" or possibly "Programmer Experience Clumping." A business begins and programming is some fundamental part of the products that they create. However, there is no programming experience in the "C" level of the corporation (CEO, CFO, CTO, etc.). Programmers are seen as a commodity, and with no other criterion to go on, cost becomes the primary decision point. Inexperienced programmers are willing to work for this company at low cost, in order to gain experience, while experienced craftsmen can see what is happening and thus go elsewhere, seeking a place where programming is better understood and appreciated. This produces a "clumping" effect, where inexperience is clumped together within the company, and the experienced craftsmen may or may not clump together elsewhere. With only the guidance of other inexperienced programmers to go by, a superstitious mob of programmers evolves, most likely just doing whatever the inexperienced programming manager tells them, which is likely to be the current fad. No one in this organization knows what a good programmer looks like except that such a person is likely to be too expensive, and so the hiring process is unlikely to produce any good programmers unless something changes.

Note the dependence on initial conditions, one of the big issues in complexity theory. The same equations produce radically different results given (sometimes very small) differences in initial conditions. In the above example, the company might introduce a CTO with software experience, or at least software awareness coupled with an open mind, and dramatically change the resulting software culture of the company. Even one or more timely visits from the appropriate consultant (yes, yes ... I do this but I'm being serious here, not just trying to market) could help establish conditions that grow a much better software culture.

Ultimately, I think it takes good programmers to recognize other good programmers, and also to recognize inexperienced programmers that have the potential of becoming good programmers, given guidance and a supportive environment.

A second pattern could be called "Faux Chief Architect," and it is one I have seen more than once. A company is aware that there are important differences between programmers. However, the idea of creating a corporate software culture sounds like too much effort and expense, and so instead they decide to find a really smart chief architect and let that person guide the process. The assumption is that the architect (A) knows what s/he is doing and (B) understands people and organizations, not just software. Because the "C" levels in the organization don't understand the issues themselves, but they think they do, they are impressed with a particular architect who interviews very convincingly. Alas, that architect is not truly experienced, and primarily wants the feeling of power. S/he assures the "C" levels that they no longer have to worry or pay attention to software, and then proceeds to make dramatic decisions which cannot be questioned by subordinates without being fired. All along, the "C" levels are assured that software issues are humming along, while the project becomes more and more topheavy with the decisions passed down by the architect/demigod, decisions which sound crazy to the people working on the project. Perhaps it should be called "mad emperor syndrome." By the time the "C" levels begin to realize that things have gone horribly wrong (often by calling in consultants to evaluate the situation), the project is a foundering shipwreck, and most or all of the time that went into it is lost.

Of course, I have no idea whether these two examples are really patterns, and I note that both of them are negative, so-called "antipatterns." The antipatterns seem to appear far more often than the positive patterns and so would fall under the category of problem discovery. But like Tolstoy's famous first sentence in Anna Karenina ("Happy families are all alike; every unhappy family is unhappy in its own way"), the likelihood of things going right is quite rare and the results would seem to be quite consistent, whereas there are myriad ways for things to go wrong.

A positive pattern might be "The Gelled Team." Someone in the company is able to hire an energetic, experienced programmer who enjoys interacting with people, and to give that person a key role in hiring other programmers for the team, and a reasonable budget to do so. This person is instrumental in hiring people that s/he wants to work with, and as a result a team is formed that really enjoys being together and working together. The team becomes remarkably productive and effective, and the company doesn't break up the team in a mistaken attempt to distribute the seeds of its success to other teams.

So, is there the kernel of an idea here? If you can think of other "Process Patterns," Suggest them here.

    Links I Read
Cafe Au Lait
Artima
Daily Python URL
Martin Fowler
Joel on Software
Paul Graham
Cringely
Search     Home     Web Log     Articles     Calendar     Books     CD-ROMS     Seminars     Services     Newsletter     About     Contact     Site Feedback     Site Design     Server Maintenance     Powered by Zope
©2003 MindView, Inc.