More about Rebecca

Resume/CV


I am an object design pioneer who invented the set of design practices known as Responsibility-Driven Design (RDD). By accident I started the x-Driven Design meme (TDD, DDD, BDD…) and along the way authored two popular object design books that are still in print. Recently, I collaborated with Mathias Verraes to write several essays about modeling and models, which are collected in the book, Design and Reality.

I help software developers, architects, technical leads, product managers, analysts, and testers hone their modeling, design, architecture, communication, and thinking skills. In addition to coaching and personal mentoring, I occasionally conduct workshops and give talks on a variety of topics. I enjoy collaborating with others, especially to tease out, reflect on, and then share our personal design heuristics.

My current research interests center around the cognitive and social aspects of software architecture and design, domain modeling, and collaboration. I'm particularly interested in architecture decision-making, generative pattern languages, personal design heuristics, and practical ways to characterize, design, and evolve complex socio-technical systems.

Rebecca's Software Development Life Story

Excerpted with minor changes from Discovering Your Software Umwelt

My introduction to computing was at the University of Oregon’s Test Scoring Center where I had a part-time job ensuring students’ multiple-choice exams were properly marked. They were read by a machine onto tape that was then processed at the computer center. The output of the test scoring program was a listing of the students’ test scores and some statistics.

Curious about that test scoring program, I signed up for a FORTRAN programming class where I typed my WATFIV programming assignments onto punch cards. I turned those in and picked up a listing of my results a few hours later. I was lucky to get a couple of execution runs per day. I got a printed trace of compiler errors (and usually, just the first one that tripped up the compiler and sent everything else south). Once my program compiled, I got (erroneous) output to look at…so debugging took a lot of effort. I found I liked writing code because the amount of effort that I put in paid off in direct results. Also, I could work on my programs as much as I wanted until I got the structure and algorithms “right.” I liked tweaking code.

After FORTRAN, I took more computer courses and graduated in 1975 with a dual major in computer science and psychology. Most of my computer sciences courses were programming courses. To me programming was much more satisfying than, say, proving theorems in Calculus, where I had to get the “right answer” at first crack.

In addition to writing in FORTRAN, I wrote in PL/I, 360 Assembly Language, and COBOL (all on punch cards). I also wrote some BASIC on the PDP-10 timesharing machine where access was limited. I also completed a senior practicum where I completed a programming project written in COBOL. Oh yeah, I took some courses in computing algorithms (we read Knuth) and logic.

I landed my first professional programming job as an analyst programmer II (I had a CS degree!) for the City of Vancouver, Washington. I introduced our five person COBOL programming shop to the structured programming techniques I had learned at school, and the use of perform statements, by creating a program that executed the story of Goldilocks and the Three Bears. I spent 3 short months writing thousands of lines of water and sewage billing code in COBOL (no one else read or tested my programs—I was given hand written specifications which I took as a starting point). I penciled in my programs on IBM COBOL coding forms and gave them to our keypunch operator to type up.

In January 1976, seeking more challenges, I took a Software Evaluation Engineer job at Tektronix. For the next year I tested a variety of graphics libraries, terminals, and an early graphics workstation. I read as much of the code I tested as I could and found several bugs simply by reading code. I also wrote test specs and test code.

Wanting to do more significant programming, I applied for a job as a Software Engineer I in the newly formed Microprocessor Development Products division in 1977. (At that time, Software Evaulation Engineers were a pay grade lower than Software Engineers). Over the next year I designed and wrote a download program in 2650 assembly and a universal linking loader in PL/M. I was the lone engineer on the linking loader.

Knowing nothing about linkers or loaders, I researched how linkers worked before designing the features to support different microprocessor instructions sets and architecture in a single program. Based on descriptive meta-data, my linking loader would allocate memory, resolve address references, and rewrite the binary file according to the “rules” specified in file headers. The linking loader could even process multiple files for different processors into a single relocated binary file (why we thought people would want this capability still puzzles me).

While I designed and programmed this universal linking loader, a small team developed a universal macro assembler. We also developed a common utility library that was shared between the assembler and linker. This was a fast-paced product development effort for Tektronix. We worked on a very tight schedule transforming an acquired product into a high quality Tektronix product line, turning out multiple product releases in a little over a year.

Tektronix was an engineering company where the “next bench” philosophy was practiced—build something of high quality that your peers would use. My colleagues were, for the most part, a highly motivated bunch of new hire recent grads. Our team also included one or two more experienced programmers and a couple of engineers without college degrees. Tektronix had lots of internal process for designing and engineering hardware products but (at least in this part of the company) very little experience with software. So, most of the processes and various design documentation requirements we used were imposed on us software developers with very little adaptation.

Over the next few years at Tektronix, I held engineering positions with increasing responsibility. I was lead developer for a networked file server (we basically wrote our own operating system, drivers, and file management system code from scratch) in Pascal. In 1981, I led a fast-track firmware development effort for a low-cost graphics terminal (written in PL/M). We wrote functional specs and created structured design documents. We incrementally developed and tested our code, and held frequent code reviews. This all was just standard practice.

Up until this point in my career I had briefly written billing software (my COBOL programming stint) and embedded systems software.

And then, along came Smalltalk which was the main programming language for the Tektronix 4404 Workstation. I joined the AI Machines Product group right after it was formed as a Principal Software Engineer (I was the first woman promoted to Principal Engineer at Tektronix), but shortly was recruited to manage the software team until the first product introduction (a little over a year—again, this was a fast-track product development jointly with Tek Labs folks). My engineering management position didn’t afford me much time to program in Smalltalk, yet I had a keen interest in grokking it. I wanted to become a Smalltalk developer and engineer products using Smalltalk.

Smalltalk was unlike any programming environment I’d encountered: immersive, graphical, and utterly alien. Its syntax was simple, but the terminology for Smalltalk programming concepts were foreign. I had to translate Smalltalk terms to roughly equivalent programming constructs familiar to me before I could even start to understand what people were talking about.

Objects were instances of classes. Classes defined an object’s methods and variables. Classes and objects didn’t have any analogs I could draw upon. However, methods seemed a lot like procedures. Objects were instantiated, that is allocated. Objects respond to messages. Messages seemed roughly equivalent to function calls.

To write a Smalltalk application (whatever that meant), I typically wrote statements in a workspace. I then highlighted that code and executed it. Were those statements then my program?

I didn’t need to create my own classes; I could do a lot using the classes that came with the Smalltalk environment. I could freely add methods to existing classes too (although that was frowned upon by those with more Smalltalk programming experience).

I still had several questions: What exactly was a Smalltalk application? What were good ways to think about structuring programs? When should I define my own classes and when should I use existing ones? Reasonable answers to these questions may seem obvious to today’s object-oriented programmer, but they weren’t so settled in those days.

Most of the early Smalltalk programmers worked in Tek Labs. They were tasked with demonstrating potential applications of Smalltalk in Tektronix products. I looked to those folks for good programming practices. How did effective Smalltalkers think? My first Smalltalk code was an ugly memory hog. Not knowing better, I extensively used blocks (closures) to define font families that could be lazily loaded from external files. Fortunately, a fellow engineer read my code and offered helpful suggestions for restructuring it to be more understandable and performant.

Over the next several years programming in Smalltalk, I came to value carefully designed class libraries. I rejoined the engineering team and led Tektronix’ Color Smalltalk product development. My design ideas and code were always reviewed. Since our Smalltalk code was visible to other programmers, we wanted it to be exemplary.

I came to appreciate the effort it takes to design frameworks (for color representations, graphic hardware memory, color matching, color graphics, use of color in Smalltalk windows, etc.). Developing libraries for others’ use demands attention to detail, code comprehensibility, design coherence, and utility. But people won’t know how to use your libraries unless you present a coherent model of how your classes and objects work together and demonstrate how to use them. Working code isn’t sufficient.

In retrospect, my Smalltalk experiences had a huge impact on my software development and the trajectory of the rest of my software development career. Through my Smalltalk engineering experiences, I learned not only how to create extensible code and frameworks, but also how to communicate the important aspects of a software design and the object design process. As I grew to understand how productive Smalltalkers thought, I realized that there were different schools of thought about how to approach object-oriented design.

I found that initially thinking in terms of the roles objects play—their “responsibilities” if you will—and how they interact led to significantly different design solutions than if you focused first on how objects responded to events, or what states they were in, or their internal data structure. This led to my inventing responsibility-driven design, teaching numerous design courses, and writing a book about object design. Over the next ten years, I refined my object design approaches as I refined my perceptions of object-oriented software development. I saw different patterns of object interactions and distributions of behaviors (this led to my idea of object role stereotypes and control styles, and a new object design book). I enjoyed figuring out (perceiving) patterns of good designs and software development practices I discovered in my work and colleagues, and then communicating them to broader audiences.

As a software design and architecture consultant I have worked on several multi-year projects employing various technologies. I have worked with developers, business analysts, domain experts, architects, engineers, and managers. I could always dive into programming. I felt most at home working with software engineers. But I didn’t want to be “slotted” into solely the role of object design guru. Over time, I became more comfortable with being uncomfortable in those new software environments and problem domains I encountered. My past experiences had taught me that I was capable of learning, and adapting and adjusting my umwelt, even though it wasn’t easy or comfortable. I came to realize that my outsider’s perspective especially as a consultant or advisor, was an advantage. So was my ongoing interest in cognitive psychology. Along with my design values and practices, I could offer unique and valuable insights. I became adept moving around between and among software development roles, adding value where needed. I could zoom out to establish the bigger picture of the overall system architecture, or dive into details and tweak the software design, processes, techniques, or practices. I have spent nearly twenty years writing patterns about all aspects of software development.

Throughout my consulting career, I have enjoyed “shifting” between different perspectives on complex systems while learning about new technologies and problem domains and details. I enjoy working with people with diverse backgrounds and interests. I found myself (still do) gravitating towards helping technology leaders explore design innovations, discovering new ways to think about software design and modeling, and experimenting with effective ways for others to communicate their design practices and personal design heuristics.