Note: This was originally chapter 13 of my book, UML Applied: A .NET Perspective from Apress. My editor and my tech reviewer read it; and both said, “We like it; but what does it have to do with UML?” So I came up with a more on-topic closing chapter. But I still like it. It sums up my view of the software development profession quite nicely. So I thought I would share it here.
Somewhere, deep in our prehistory…
A man tells a story, a story of a hunt. Perhaps it’s a hunt he’s planning. Or perhaps it’s a hunt that just took place, and he’s telling the tale. In telling his story, he draws Figure 13-1:
Figure 13-1: The first recorded UML diagram?
Regardless of whether he’s telling the past or planning the future, he has built a model of “How we kill the prey.”
From these simple pictorial models, we moved to pictograms… and cuneiform… and eventually to alphabets and written words. With words, we can model much more abstract concepts than our hunter ancestor could — such as “abstract concepts”.
Elsewhere in our prehistory…
A man looks at a set of things that are important to him — perhaps it’s livestock, perhaps it’s weapons — and can see at a glance that all the elements of the set are there.
But soon, the man grows more fortunate. He gains more livestock, and more weapons. And as he gains more, at some point he can’t tell at a glance that all the items are there. Remember our 7+/-2 rule: past a certain point, the elements of the set blur together.
So the man finds a way to keep track of the items. He recognizes that he can associate the individual fingers of his hands with the individual animals or weapons. And he knows his fingers, and how many he should have, and which finger corresponds to the last item; and so he knows how many items he should have. He can match the fingers to the items; and when the match is correct, he knows all the items are there; and when the match is incorrect, he knows there are missing items (or extra fingers).
And thus, with his fingers he has built a model, a symbolic representation of the items that concerned him. And when he grew wealthier yet, and the number of items grew beyond the limits of his fingers, he and his intellectual heirs invented new models: counting sticks… and tally marks… and Roman numerals… and Arabic numerals…
And all of these counting methods were models or symbols of things in the physical world. But along the way, we developed more abstract concepts: operations that could be performed on the numbers. We can add to or subtract from a number, without adding to or subtracting from the items themselves. And thus, we can have numbers that don’t represent any physical items, but simply represent the abstract concept of “count” itself. And along the way, we invented arithmetic… and zero, which represents an absence of things… and rational numbers that don’t represent any count of things, but rather the ratio between things… and mathematics… and negative numbers, which represent a dearth of things… and irrational numbers, which represent the numbers between ratios, numbers which cannot be associated with a physical count of things at all, yet which often represent underlying aspects of physical reality (π, e)… and algebra… and imaginary and complex numbers, which represent vector quantities which cannot be graphed on a number line without extending that line into a new dimension… and varying numerical bases… and mathematical logic… and accounting… and trigonometry… and statistics… and probability… and higher mathematics, where we question or even dispense with the matter of number itself…
And all of these advances in mathematics are powerful models, letting us express concepts only distantly related to “How many goats do I have?” — concepts that underlie everything around us, from our understanding of the laws of physics and chemistry, to our understanding of rhythm and meter and tone in music, to our engineering skills that produced the laptop on which I type this sentence.
Somewhere inside my laptop…
There is a tiny zone of silicon, with a tiny doping of impurities which render that zone a semiconductor. And at any given moment, that zone is in a charged state or an uncharged state, depending on the flow of electricity through my laptop and through components of the system and through paths shaped by wires and by billions of other tiny zones of semiconducting silicon. And we look upon the charged state and the uncharged state, and we choose to call the charged state “1” and the uncharged state “0”. This is simply an arbitrary choice, not a physical reality. It’s a symbol we could define any way we chose.
And thus, the state of that tiny zone of doped silicon is a model of a model: a physical representation of the concepts of “0” or “1”. The tables are turned: instead of our symbols representing reality, we manipulate reality to represent our symbols. And then, our technology lets us string these physical symbols into sets to represent larger and larger numbers — and with IEEE floating point format, numbers beyond simple counting. Yet despite the size and power of these number formats, they are still at base models of models: physical symbols to represent the abstract concepts of numbers. They are silicon “fingers” (and we even call them “digits”, just as we do fingers).
Somewhere in the field of psychology…
Psychologists study how our brains work, how we think and how we communicate what we think. And one underlying mechanism stands out: creating and manipulating symbols and models.[1] We have symbols and models in our heads that represent to us concepts in the real world and concepts in the abstract (such as “concepts in the abstract”). And we manipulate these symbols, and we create new symbols for new concepts. And in fact, if we do not have symbols for something, we cannot think about that something. These symbols, these concepts, form our mental models of the real world, and of ideas. From these, we can build larger, more useful models, such as theories and skills and bodies of knowledge. Armed with these larger models, we can understand and manipulate the world around us. And however imprecisely, we can communicate and share these symbols.
Elsewhere inside my laptop…
As I sit with this laptop in my lap, and I press this key — this very key, “q” — a contact closes under the keyboard, and a gate opens, switching from a “0” state to a “1” state. This allows a signal to be sent to the CPU, and from there to be routed to a particular chunk of software. That software looks at the signal, and translates it to a specific numerical code — 112 — that we have chosen to associate with the letter “q”. Like our physical symbols for “0” and “1”, this is an arbitrary symbol we have chosen to have the precise meaning, “q”. This doesn’t mean that 112 “is” the letter “q”. It means that 112 represents the letter “q”, and we have agreed to this precise representation, so that when I press this key, you see something that represents to you, “q”. Ultimately, we have manipulated physical things that are symbols and representations — models — and by sharing these models, we can exchange ideas. The models have become so powerful and so precise and so flexible that we no longer see the models at work. We see the thoughts themselves.
Somewhere inside my head…
I have a set of symbols inside my head: a set of thoughts, a set of ideas, a set of concepts that collectively can be called a model. This model represents to me a set of equations and mechanisms by which one can simulate a spacecraft and control that simulation on a voyage from the Earth to the Moon. I can enjoy the beauty of these symbols, and I can enjoy the concepts, and I can play with them, and I can write them out. And I can see that these symbols do truly represent (to the accuracy that I care, since I’m not a rocket scientist) the process of traveling to the Moon and back.
Somewhere inside your head…
And if I teach you the same symbols, and if we share enough common symbols and models, you can do the same thing. This is the purpose of the tools we call “language”: to allow me to convey the things that I know in such a way that you know them as well, and can apply them, and can build upon them and communicate your new ideas back to me and to others. As I quoted him in Chapter 3, Stephen King is right: writing is telepathy.
Once more inside my laptop…
But now, with software, we have a new construct, a new kind of tool. It has a character like traditional machines: regular, precise application and replication of mechanical and physical laws toward a particular purpose. But it has a character like language. Being made entirely of malleable physical symbols which can represent whatever we want them to represent, it is more than a traditional machine: it is an Idea Machine, a Concept Machine, a Symbol Machine. And since those are the building blocks of how we know and how we think, it is a Knowledge Machine and a Skill Machine. I can take the “Lunar travel” symbols from my head, and I can express them not to you, but to software that resides on your computer. And if I express them sufficiently thoroughly and correctly and precisely, you too can go from the Earth to the Moon, but without having to learn the symbols and models that I know. Instead, you need only learn a much smaller set of symbols for telling the software to do what I know how to do.
The Point (At Last!)
As software developers, our job has never been about technology. Our job has always been about expressing symbols and ideas and knowledge and methods in precise physical symbols so that other users can reuse and apply those symbols and ideas and knowledge and methods without having to master them themselves — or if they do master the symbols, without having to go through all the rigor and discipline and effort of applying them for themselves. All they have to master is the effort of telling the software to do what we have already mastered.
And the other side of our job has been to master that which we don’t know. We may be skilled at precise expression of ideas in physical symbols, but that doesn’t make us skilled at Lunar launches and color science and financial forecasting and the myriad other symbols and ideas which users want expressed in software. So we have to learn how to elicit those symbols and models from those who have them, but who lack our skills in precise expression through software. In a sense, we’re translators between mental symbols and physical symbols, adding in our own mental symbols to provide an intermediary layer to allow users to make use of the physical symbols.
In other words — and you had to know that this was coming — it’s all about communication.
And there’s a bit of irony for you. Our field — where our entire job is precise communications — is infamous for practitioners who are perceived to be short on communications skills. And in fact, nothing could be farther from the truth: to have any success in software at all, you must be very, very good at precise communication, at taking an abstract set of symbols in your head and precisely communicating them to the software in such a way that the software “understands” what you understand.
So if software is all about communication, how has it come to be seen solely as a technology job? Indeed, how has it come to be dominated by technology fanatics who (in many cases) do have something of a problem with unstructured, imprecise communications? Why do some developers have such trouble with the nuance and the double meanings and the give-and-take and the vagaries of human communications?
Well, one reason is that for most of the history of software development, communicating with the technology has been hard. Very hard (though getting easier). It requires an exceptional degree of precision, and therefore it requires specialized skills not found in the general populace. As I mentioned in Chapter 2, you’re weird: you handle precise communications in ways that most other people do not. This tends to set us apart. And perhaps that setting apart attracts people who are better at technology than at communications. Perhaps the time spent with precise technological tasks even causes atrophy in our other communications skills, since people usually do better at that which they practice a lot, and worse at that which they neglect.
Another reason is that in the past, limitations of the hardware strictly constrained what we could and couldn’t communicate and also put a premium on mastering obscure technical tricks and creating new technical tricks to live within the limitations of the technology. The software developer culture evolved in circumstances where technological prowess was essential in order to communicate at all.
And yet another reason: the small size of projects that could fit within those limited environments was often a small size which could be mastered by someone who could communicate his or her ideas well without needing recourse to communication with others. A large number of projects were small enough and simple enough to resolve primarily through technological prowess.
Well, as I tell my students, there are no simple problems left. Yes, this is a bit of an exaggeration; but as a practical matter, the simple problems have been solved. Hardware today has grown so powerful as to have no meaningful comparison to the hardware of a generation ago; and yet the software problems of today strain that hardware to its limits, and there’s always a backlog of problems we’d like to solve as soon as the hardware catches up. Today, no one hires a software developer to solve simple problems. They hire us for the hard problems… the really complicated problems… the problems they don’t entirely understand themselves… the problems for which requirements are hazy, and success cannot be clearly defined. And they’re counting on us to clear away that confusion, to help them define what their needs are and what success means. They’re counting on us to communicate with them because they don’t know how to communicate with us. We must communicate with them and for them, leading them through the communications process to lead to the precision that the software requires.
In other words, now and for the foreseeable future, I believe that communication will be the key software development skill. I don’t want to discount technology skills, because there are always new technological frontiers to master (like .NET today); but without communication, we’ll fail to apply the technology in ways that matter. We have to communicate with our users, because we need to know what they need, how to accomplish it, what skills we must master to accomplish it, and how to recognize when we’ve succeeded. We have to communicate with our users in another way, through our user interfaces that allow them to access and command our software. We have to communicate with each other, because the problems are too large to solve in isolation. We have to communicate with future maintenance developers who must carry on our work when we can’t. We have to communicate with mentors and educators and experts (perhaps in a disconnected fashion, through their lessons and books and examples and presentations) to learn the new domain skills and new technology skills we must master to address user needs. When we ourselves become mentors and educators, we have to communicate to our students and readers by writing our own lessons and books and examples and presentations. We have to communicate to testers, so that they know what and how to test, along with how to recognize success or failure. We have to communicate with documenters, so that they know what to explain and how they will communicate it to the users. We have to communicate with marketers and sales personnel (yes, even them) so that they understand what we can and can’t deliver. We have to communicate with managers and executives to explain what they can and can’t expect from the technology within constraints of time and resources.
And we have to precisely communicate with the software and the other technology, instructing it to carry out the knowledge and skills we have mastered. I sometimes call this “shipping our brains in boxes”. While the metaphor is a bit gruesome, the idea is key: that software installed on my customer’s machine is a proxy for my brain, sitting there and doing for that user what I could do myself if I were there – only doing much of it faster than I could do myself (and more accurately, because software is more precise and repeatable than humans usually are). And besides speed and accuracy, there’s leverage: that software proxy for my brain can be installed on hundreds or thousands or more computers, helping far more users than I could ever help in person. We’re not just working with technology, we’re communicating with it, teaching it the things we know and then replicating our knowledge across the user community.
So that’s my conclusion, one final time: it’s all about communication. And while UML isn’t the answer to your every communication need (for instance, I thought about writing this entire chapter solely in UML diagrams; but the abstract nature of diagrams just wouldn’t express the precise thoughts I wanted to convey), I hope that I’ve shown it to be a powerful set of graphical tools for conveying complex ideas and relationships so that you can more easily communicate the skills and ideas from your users and experts to the software so that your users can apply them. Today, many UML tools will also produce the structure of your code directly from the models. In the future, UML will become a programming language, a tool for communicating with the technology directly. (Some UML tools like Compuware OptimalJ and ILogix Rhapsody already do this in certain niches.)
So UML is a valuable way to express yourself, both to people and to machines. It’s a new technology skill that will help you to apply all of your other technology skills, once you master it. Practice UML and apply it, not just by yourself, but as a means to communicate with your fellow developers and your users and everyone else with whom you must communicate. I hope that with time, UML can do for you what it has done for me: speed and smooth your communications so that you can solve more complex problems more successfully.
[1] Marcia Wehr, Ph.D., Mastering Psychology, “THINKING AND LANGUAGE”, http://inst.santafe.cc.fl.us/~mwehr/StudyGM/12Ove_Th.htm. Dr. Wehr provides an excellent introduction to psychology, as well as a good basic description of software development: “When we face a mental challenge in which there is a goal to overcome obstacles, we are engaging in problem-solving. Generally we use a common method of problem-solving. We 1) identify the problem, 2) define the problem, 3) explore possible plans or strategies 4) choose a strategy 5) utilize resources to act on the chosen plan 6) monitor the problem-solving process and 7) evaluate the solution.” That sounds like the basic outline of all software development processes.