I have collected hundreds of drawings, some are very beautiful. Rarely I get drawings of bamboo.
Invariably one nerd who wants to win the prize and show off his computer geekiness draws a directed graph. After all, he doesn’t know the criteria I'll use to choose a winner (none, it is a random drawing).
But most draw physical trees.
I get canonical tree shapes: mainly deciduous trees, with and without leaves, and a few conifers.
After I've collected the drawings, I ask how many drew roots and if so, why? If not, why not? Invariably, as Thiagi observes, most do not include roots, but some include roots or hints of root structures.
When asked why they didn’t draw any roots, invariably the answers is, “Because I drew what I can see. No need to show what’s below ground.” When asked why they included roots, those who did answer, “Because trees have roots.” Some software folks are very detailed and want to show everything. I’ve even received trees with tree parts labeled.
And there is my hook into the art of design storytelling. It depends upon your audience and the goal for telling your story whether you should include roots or not. There’s no “right” answer. Depending upon what your audience already knows and what you want to focus on, it is perfectly OK to leave out certain details.
The art of effectively drawing or describing any aspect of a software design, is to knowing what to leave out. It’s just as important to know what to omit as it is to know what to include. There’s always more detail. Effective design storytelling leaves out unessential details so that the important stuff can get emphasized.
"kept looking for something seriously implementable...we've gone to other tech-conferences and club meetings that were seriously more useful."
"I think people there [at conferences or meetings with published speakers] have way more credibility to lose, so are better accountable, [have] better presentations, handouts, websites, references."
Funny, I thought that requirements are the main driving for for the design. [The] author made me feel like I was blind all these years...Kidding aside, all these forces [the] author mentions are secondary forces, while requirements should be the primary and the commanding force.My first reaction is, well duh! I was trying to get behind that to an explanation of our design roots and current practices. Requirements may constrain what are valid solutions, but the choices you make as you design and implement a solution are wrapped up in your design values, aesthetics, practices, and development rhythms. As the person who coined the meme, "xxx-driven" that is used to characterize various driven practices (think Respsibility-Driven Design or RDD, TDD, BDD, AMDD, FDD, etc.) I presented a brief history lesson about how certain software design practices came into being, what values are associated with them, and how these values might conflict or co-exist.
I also challenged the software community to stop being so blindly "driven" and take a closer look at why they follow certain practices. Of course requirements should drive design. But what then drives the way you approach your work? I believe that from time to time it's good to pause to reflect on what you value (and what you think makes a design solution good) before integrating new techniques and practices to improve your work.
If you watch my talk, I'd love to hear about what you value and thoughts on how you approach design.
@jordanwb Are you related to Rebecca Wirfs-Brock? Her name was mentioned in my Software Design and Development class.
This class isn't any fun.
@thismax that's my mom! I'll let her know you guys are talking about her. 02:16 PM September 16, 2008
Software development can be fun when people collegially work towards solving a design problem. Last week I visited a client and helped them understand and apply responsibility-driven design principles and practices to the design of software components and subsystems. By far, the most rewarding activity during the week was a workshop where designers paired off and solved a common design problem. Sharing design ideas and initial solutions was fun. Reworking their designs to cover more cases was fun. And taking good ideas from others and melding them into a better solution was an unexpected benefit of all this sharing. One key to the success of this workshop was that a real problem was chosen that didn’t have a pre-existing owner or preferred solution. It was a problem without territorial boundaries and/or clashing vested interests. So design teams were genuinely open to constructive criticism from others. And the small teams could go much faster working in pairs than working in a larger group.
Collegial, thoughtful, reflective, not-too-detailed-at-first designs. Highly productive. And fun. Now why aren’t more design efforts like that? The best design and development experiences in my career have been where I've worked on small, tight teams. There was mutual respect, a common goal, pride in our work, and a healthy dose of reality: let’s think about the problem a bit, then prove our ideas by implementing them. We may have had disagreements, but we found a way to discuss and weigh options without getting bogged down or wedded to any particular solution. Collaborating was fun under those circumstances. I can remember some not so fun times too: people fighting over style instead of substance, working too hard but not too smart, and clashing egos preventing us from finding any common ground. That wasn’t fun. It was a grind. Even though those projects may have successfully completed, the thought at their end was 'finally!' instead of 'yay, we did it!'
Coding 'till almost 4am... am I acting like a stereotypical programmer now? On the upside, I implemented the Hill Cypher, and feel badass. 12:48 AM September 11
Getting things done at 4 a.m. can be fun, too. Nothing like a sense of real accomplishment after a long haul programming effort. But it can get old fast. Especially if you're not a grad student and you're working solo on a design effort without the support and encouragement from your team mates.
At the very least you should leave code as clean as it was before you made a change (if not better). One credo that Scott Bain extols in his new book, Emergent Design, is whenever you touch the code "do no harm". Do what you know to be best at the time (given the constraints you are under). Scott is a realist, but I like his stance on when to fight for one particular design approach over another, too. When you think it will be really difficult to refactor/cleanup the design later due to a poor design decision that is on the verge of being made now, argue for what you think now is a better solution.
But even with good intentions and experience, we need to refactor and rework our code as we refine our design ideas--and learn from the code. Yep, we should refactor. Continually. But we don't always do so. Emerson Murphy-Hill, a Ph.D. student at Portland State and Andrew Black, a professor at Portland State wrote an intriguing paper, Refactoring Tools: Fitness for Purpose, that also appears in the upcoming issue of IEEE Software. They explain why in practice refactoring tools aren't used as much as they should be and propose some principles that characterize successful regularly used refactoring tools. They also distinguish between "floss refactorings"--those which should be done a regular ongoing basis during programming in order to avoid more pain later on-- from "root canal" refactorings. They found that refactoring tools could be better designed and point out some that are better designed for daily use than others.
But even more annoying was the difficultly I had stopping my printer from printing a month’s worth of buffered faxes! Glancing quickly at the buttons on my Brother MFC-885CW I noticed one labeled Clear/Back and another Stop/Exit. I pushed the Clear/Back button a couple of times to no avail, then decided I’d just let the faxes print. (Mild curiosity led me to receive 3 fax ads for discount health care, 3 for vacation deals in Cancun, an invitation to the Presidential Who’s Who among business and professional achievers, and a Neo-Tech stock market news report.)
There will always be competing values and design goals. Business and users’ goals don’t always match. An ethical usability designer should point out these conflicts and not let them slide. I know that might be pushing it, but someone should have strongly questioned whether it is better to demand all cartridges be installed or not.
But usability concerns don’t stop at defining how to accomplish some task or what constraints exist on initiating one. How to start, stop, pause, quit, and retry should be considered, too. Clear/Back and Stop/Exit? How confusing! I wanted to clear the print buffer and stop all printing. But perhaps I should have stopped printing first. But then what? What I wanted was to stop all printing and clear my printer's internal buffer all in one easy to do action (I don’t read manuals when faced with an exception in real time). Maybe pressing Stop/Exit would’ve accomplished that. I’m not sure. If I remember, next time I’ll try that.
But what if I wanted to stop one fax job, but continue printing the others. Hm, maybe that Fax Preview button on the other side of the print console could come in handy. Grr. There isn’t just one path through an exceptional case that a user might want to pursue. They all need to be carefully considered. And too many buttons with small and potentially confusing labels don’t help me accomplish an emergency action in a hurry. I think Brother could do better by displaying alternate flow options on the console during printing (did I mention there is a display console on my printer?), but I’d have to get “trained” to look there. Since I don’t stand by my printer and watch it work enough to notice what kinds of informative messages it displays, it might’ve been telling me what my options are, and I just didn’t notice. Now that's a tough problem to tackle. Not sure how to avoid frustrating inattentive users who don't know to look for advice on how to logically push that missing big red cancel button. (I'll take a closer look the next time my printer prints a fax to see whether it tells me anything).
I've just returned from four weeks travel to Athens, The Netherlands, Australia (Brisbane and Sydney), and Las Vegas. It is good to be home in Sherwood sleeping in my own bed. This trip was a combination of vacation, work, and geeky holiday. I and spoke at three different conferences in three weeks. JAOO Brisbane and Sydney was an opportunity to hear Erik Meijer give a great talk about why fundamentalist functional programming languages (think Haskell) solve the problems we procedural and oo language programmers just sweep under the rug. And then I got to grill Erik on why he thinks that declaring types to include side effects so important to writing good programs. Where else does a geeky woman get to hang out and talk shop with other software geeks? I snuck in some sight seeing too. The picture is of me taking rental bike across the Brisbane Harbor on a ferry. A bike ride with Dave Thomas and Kresten Thorup was about the only sunny day we had in Brisbane. The rains came to Australia just in time for JAOO.
In Greece I saw lots of ruins, attended the annual IEEE Software planning meeting, and ate lots of Greek salads, simply prepared fish, and drink thick coffee. They call it Greek coffee, but a few years ago even the Greeks called it Turkish coffee. But one highlight I won't forget is hearing Linda Rising and her husband Karl sing "Take me out to the Ball Game" at the ampitheater at Epidaurus, Greece. They volunteered to demonstrate the phenomenal acoustics. It gave me goose bumps. Constructed in 500 BCE, the ampitheater perfectly amplifies sound from on stage to everywhere in the theater. You can whisper stage center and people in the back row can hear you perfectly. And sound is amplified back to you, too. Truly an engineering marvel, the acoustics are because of the location and how the ampitheater was carved into the rocky hillside.
I'll be sliding back into a more normal work routine, but before the magic of this wonderfult trip fades, I hope to share some thoughts and reflections and experiences over the next few days.
I've experienced both sides of reviewing. Early in my engineering career I presented the design of a universal linker to an external reviewer. I was scared to death that the reviewer would pick apart my design. I was relieved when my design was blessed, but annoyed when the reviewer doubted my ability to deliver on time. (I delivered, but in hindsight I could see why he and my management doubted me--as a new engineer I was working solo on a critical project...I just didn't know what I couldn't do).
These days, complex IT systems are rarely understood by a single engineer or architect. Teams come together to create complex software systems. Technical challenges can be enormous and the "tricky bits" involve the subtle interplay of business and technical design decisions. The focus is on achieving overall business objectives, not the optimal design of a single component. Yet poorly designed interfaces, sluggishly performing services, or crappily constructed components can cause enormous grief. Design still matters.
Last year we held an open space in Portland at the Kennedy School focused around the theme, “Agile for real.” The response was so positive that we’re picking up the conversation again at the Seattle convention center March 18 and 19. I’m happy to get to renew connections with folks I met last year and excited to meet some new folks and hear their agile experiences. Attendance is limited to 100. Registration is filling fast. We’ve kept the price low ($100) so that even if your company can’t afford to send you, you might still attend. Most who’ve registered so far are from Seattle, but this is a northwest regional conference. So expect a few of us from Portland and elsewhere in the northwest to show up, too. And maybe even some folks from further away. We hope to see you there!
At the beginning of my talk I asked attendees to write down their most challenging communication problem. I figured it was a fair exchange: I’d get direct feedback from about their problems, and two lucky attendees would walk away a book. Looking over their feedback, I’d categorize them as
Communicating to others who are not like me
“Communicating across domains (UI design to SW) or cultures (US to India)”
“The hardest communication was when I had to present a design to a group that does not specialize in my area.”
“As an embedded software engineer, the rest of my team are hardware engineers so they have neither the training in software methods nor the software mindset.”
“Communicating technical design to non-technical people.”
“Communicating to a non technical customer.”
Getting others to appreciate the important bits
“One of the most challenging aspects of communicating a design is educating the receiver of the design on design paradigms. This is especially true when the person is not familiar with or comfortable with object oriented design/analysis.”
“As a developer working in an agile environment, I often receive partially-conceived designs, sometimes as little as a single Photoshop mock-up. It’s easy to spot short comings, but difficult to communicate them. I sometimes end up implementing a feature just to illustrate its problems.”
“I sometimes have trouble getting others to understand why a simple solution is insufficient when the other person has very limited time to understand the problem.”
“To clearly point out the subtleties and nuances of the most critical or pivotal aspects of the design—what’s really important.”
Gaining common understanding
“Definitions [that] are not the same for the same term.”
“Just getting to a mutual understanding of the idea has been an issue for me.”
Story telling mechanics
“Communicating at the right level. What can we assume, what needs to be explicit.”
“Knowing what to put down.”
“Keeping the explanation simple. Explaining only the parts which are needed. … Pulling your imagination into paper.”
Most designers could tell far more about their designs than they should. We also could benefit from practice telling coherent stories and ensuring that the important parts get emphasized. If you have insights on how to effectively communicate design ideas or design communications challenge you’d like to share, I’d love to hear from you. Over the past year or two I’ve been working on effective design communication.
I also want to announce that I’ve put together a new one-day course, The Art of Telling Your Design Story. I’ll be teaching it publicly at OGI’s Center for Professional Development in Beaverton, Oregon, November 30th. The day before I’m offering another new course, Practical UML (if I called it Impractical UML would anyone sign up?). Design stories don’t always need formal UML notations (in fact, one of the challenges is communicating subtle ideas to non-technical folks). ButI’ve seen UML so disabused that I want to give developers some straight talk on how to effectively communicate using UML at different levels of detail (and show some nuanced design ideas effectively).
One of my favorite things I do in any architecture or design course I teach is to discuss AntiPatterns—design ideas hatched with good intentions but that prove problematic over time. We’ve all seen examples of software done badly. The purpose of an AntiPattern is to document a bad solution to a common problem, explain how people can slide into an AntiPattern, and mention ways to remedy it. The point isn’t as much to say “don’t do this” as it is to say “you probably already have this problem, you just might not have a name for it. And here is how you might’ve gotten there, here is what you might do to prevent this happening in the future, and some things you might do to fix up your design.”
A Boat Anchor is a piece of software or hardware that serves no useful purpose on the current project. Often, the BoatAnchor is a costly acquisition, which makes the purchase even more ironic. A Lava Flow is when unused blobs of code are hanging around in a system. It is characterized by the lava-like “flows” of previous developmental versions strewn about the code landscape, but now hardened into a basalt-like, immovable, generally useless mass of code (perhaps commented out, perhaps not) which no one can remember much if anything about.
Last week students at my class were incredibly inventive—they weren’t content to limit their discussion to examples of AntiPatterns that I mentioned. The new AntiPattern names are so good I want to share some of them. The first was the Frankenstein AntiPattern. It came about because “too many cooks were watching the pot.” Everyone wanted to contribute so they did, just not in any organized fashion. As requirements kept rolling in, people kept adding functionality—in a disjointed, haphazard fashion. Oh, you want two eyes? OK. And a body. That sounds good. You didn’t say you need toes. Hm. OK, we’ll bolt some on. How many do you need? Where should they go? Everybody contributed, design coherence wasn’t a goal, and the implementation just kept rolling in requirements.
One might say that good disciplined designers should’ve detected this emerging porblem and prevented it from happening. Well, projects get hectic and sometimes things slide. But what’s nice about this story is that it has a happy ending. Frankenstein was banished after a diligent designer who couldn’t with a clear conscience keep bolting on stuff and make it work said “Enough!” and worked to untangle this mess. He employed several strategies. One was refusing to take code directly from marketing—and to accept requirements and functionality via pseudo code instead of “patches”.
Another AntiPattern that was brought up was Rocky Road. It’s similar to the Lava Flow, but includes overloaded data fields and cobbled together or interpreted data fields in the mix. Not only is there dead code to stub your toes on, but there’s complicated data with overloaded, tangled encodings, too. The intentions were good—keep using the same schema but add more functionality to the software and keep encoding data in complex ways because heaven knows the data can't be redesigned. But over time this system became extremely difficult to work with. The code was complex in that it had to decode and vary functionality based on complex interpretations of the data, and the data fields grew more complex and entangled in support of new functionally. Now what’s great about this AntiPattern name is that “Rocky Road” is an ice cream flavor as well as a travel hazard. What might start out as a sweet, quick fix, can over time turn into an unnavigable development landscape. I’ve seen this situation at other companies I’ve worked at… and there is no quick fix. Someone or several people have to take the time to analyze the code and the data implications and to propose modest “safe” and agreed upon modifications. These repairs don't usually smooth out all the bumps they keep the system from totally becoming unworkable. Usually there has to be a compelling reason to make deep and significant changes (think Y2K or migration to a new database technology).
Sometimes discussing AntiPatterns can be depressing. Especially when people work in places where painful examples are in abundance, and little opportunity or incentive exists to improve things. I like hearing stories where people have been able to repair design problems and improve how systems function. Even better when these efforts are supported and encouraged by informed management. If you have any AntiPattern remediation successes, I’d love to hear about them.
OK, so how do design discussions play out where you work? In my latest IEEE Software design column I discuss some effective ways to give advice as well as hurdles you may have to overcome before your advice is heeded. Being an effective critic, advisor, and design colleague isn't purely a matter of being on top of your technical game. Cognitive biases affect how people naturally (and often illogically) receive and process information. They can have a big impact on how you your advice is received and interpreted. If you want to get better at communicating suggestions to others, you should become more aware of these biases and look for ways to mitigate or avoid them. Wikipedia has a good overview of cognitive biases in how people assess risk, make decisions, and rationalize them after the fact.
To whet your appetite for this topic I’ll mention one bias that has probably bitten every programmer at least once. A confirmation bias is when a person looks for what confirms a strongly held belief while ignoring or undervaluing contradictory evidence. Have you ever found yourself unable to isolate a software bug because you insisted that your software just couldn’t work that way? Your confirmation bias might have prevented you from noticing facts that would lead you more swiftly to identifying the bug’s root cause. I like the idea presented in Debugging by Thinking by Robert Charles Metzger that taking on the different mindset of a detective, mathematician, safety expert, psychologist (one of my personal favorites), computer scientist or engineer you can get a better slant on tracking down a bug. According to the author, “Each way has an analogy, a set of assumptions that forms a worldview, and a set of techniques associated with it.” In designing as well as debugging, having a variety of worldviews for tackling a problem helps you avoid getting stuck in a rut—and pick the right strategy based on the context. One way to get around a confirmation bias is to shake yourself out of “the normal way of doing business”.
Cognitive biases aren’t good or bad. They just are. And if you work with others it helps if you can identify biases that lead you (or others) to jump to conclusions, hold onto an idea when it should probably be discarded, or ignore risks. That knowledge can help you tune your message and become aware of and avoid bias traps.
This reminds me of another developer who sent me a lengthy email a couple of years ago, asking whether I could shed light on how to decompose problems using “behaviors” instead of functional decomposition. He copied other lengthy emails from other experts and authors—I wasn’t the first he’d asked.
I was quite impressed by how thoughtful those experts’ responses were. But they didn’t help him learn how to do behavioral decomposition. Instead of seeking out nuanced differences between object responsibilities, actions, and behaviors and what made a design object-oriented or not, he should have been studying examples of different ways to decompose the same problem. Compare, contrast, then reflect. Seeking definitions and nuanced meanings was barking up the wrong tree! At the time, I wasn’t sure I wanted to be yet another in that long chain. So I didn’t answer his email.
But these two responses by smart people got me thinking. Nuanced discussions can be infuriating if you haven’t internalized any rules of thumb about when and why to do something. If you are the person in that spot, don’t let those discussions choke your curiosity or drive you crazy. Instead, I advise you to live a while with uncertainty about the distinctions between shaded meanings or the relative strengths and weaknesses of one technique over another. Don’t try to disambiguate by thinking about what others say. Instead if you can, experiment with different solutions to meaningful problems that you have, perhaps with the help of a thoughtful colleague or guide. Then reflect on what you thought was important. Let the nuances come to you after you’ve personally wrestled with distinctions and techniques for a while. And don’t expect experts or colleagues to share the same values, use words the same way, or make the same judgment calls (when this happens the world as we know it will end).
As to what behavior means in an object-oriented context? The short answer is: the same as it does in any other. But how people use language is incredibly sloppy.
Behavior is defined as “how someone behaves” (how’s that for a circular definition in the American Heritage Dictionary?) or, more usefully, “the actions or reactions of a person or animal in response to external or internal stimuli.” Replace person or animal with software object and that definition seems to fit pretty well. But behavior also means “the manner in which something functions or operates”— a more general characterization of how something functions in a particular context. So we can talk about behavior of a dying star, a frightened mouse, or a even software objects.
Then I Googled "Wrong Design Hong Kong" and found a post on the Learning Cantonese blog about Wrong Design. The Chinese Characters are "Chit gai ji wong". "Chit Gai" means design, "Ji" is a connective , and the last character is "Wong" which means "Emperor" or sometimes "King". It's also a Chinese surname.
So the correct English translation of the name of this company should be "Wong Design" if the owner is named Mr. Wong, or "King of Design". Turns out that the owner (indeed a Mr. Wong) has a fine sense of humor as well as good Chinese business sense. He wrote to the blogger:
I took the name because I was disillusioned with all the rhetoric I see
everywhere, also because the Chinese name sounds like "wrong" ('Chit Gai Ji Wong' - 'King of Design'), and also just trying desperately not to be
serious. Business is booming.
So there you have it. A designer with a sense of humor and a love of word play. How wacky is that!