0% found this document useful (0 votes)
462 views383 pages

Addison Wesley - Object Design Roles, Responsibilities, and Collaborations (Nov.2002)

book about object design

Uploaded by

the4power
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
462 views383 pages

Addison Wesley - Object Design Roles, Responsibilities, and Collaborations (Nov.2002)

book about object design

Uploaded by

the4power
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 383
Nove uoard [a : [rable ot Contents Object Design: Roles, Responsibilities, and Collaborations By fsbecca wits B00 ian woken Publisher Addison Wesley Pub Date November 08, 2002 SBN 0-201-379483-0 Pages 416 Noted object technologists Rebecca Wirfs-Brock and Alan McKean present a modern, thoughtful treatment on the design of object software. © Introduces Responsibilly-Driven Design, the expert authors’ proven method to building better software. © Practical strategies for increasing software's rellabllly and flexibilty © Helps reader discriminate Important design choices from mundane ones, and to acquire a fundamental set of techniques that can be intelligently practiced After more than ten years, object technology pioneer Rebecca Wir's-Brock teams with expert Alan McKean to present a thoroughly updated, modern, and proven method for the design of software. The book is packed with practical design techniques that enable the practitioner to get the job done. Like many human endeavors, design is part art, part engineering, part guesswork, and part experimentation. Discipline, hard work, inspiration, and sound. technique all play thelr part as well. For any given problem, there are many reasonable, but only a few very good. solutions, The authors goal is to help readers learn to make those very good design decisions on thelr own. The book explores challenges that software developers wil face as they build thelr design, and shows how design patterns can be used to solve design problems. Long awaited and eagerly anticipated, this book represents the first great software design book of the century. A FUTURE CLASSIC! Rebecca Wirts-Brock is the founder of Wirfs-Brock Associates where she consults with clients on development practices and methods. Formerly, she was Chief Methodologist and Director of the Object Development Center of Excellence at Parc-Place Digitalk. She was the lead author of Designing Object-Oreinted Software, Prentice-Hall, 1990. Alan McKean is the co-founder of Wirfs-Brock Associates, He was formerly Object Methodologist at Parc-Place Digitalk. An experienced speaker and software developer, he has developed socre curricula in object-oriented design, programming, and distributed object systems. Nove uoard [a ve RuBboard acm esse : frable ot Conte Object De: Roles, Responsibilities, and Collaborations ohana el Bano Publisher: Adgison Wesley Pub Date = November 08, 2002 ISBN 0-201-37048-0 Pages 416 hapter 1. Design Concept bisct Machines oles bject Bole Stereotypes oles, Responsiilies, and Collabaration anew ychitectural Style at Further Reading apler 2. Responsibly Driven Desig Further Reading hapter 3. Finding Object Discovery Strateg ooking for Objects and Roles. and Then Classe ny Tell a Design Stor earch Strategie haracterzing Candidates sonnecting Candidates ooking for Common Groun etend Candidates and Look ior Others SUMMAR) URTHER READIN hapier 4 Responsible hat Are Responsible ere Do Responsibilities Come From ratogies for Assigning Responsibilities implementing Objects and Responsible esting Your Candidates’ Qual Further Reading hal is Object Colaboration he Design Story forthe Speak or Me Sotiward iralegies or Kentying Colaboratong Simulating Colaboraton Qesigning Good Collaboration taking Collaborations Possib nen Are We Finished hapter 6 Control Siyk hat Is Contrl Syl’ :Onirel Style Option Peveloping Control Genter raanizing Your Wor reserving Stories Further Reading hapter 9. Flexbily at Does It Mean to Be Flexible’ egrees of Flexibility jow to Documenta Flexible Desig hanging a Working Sysiom's Desig hapter 10._On Desig] he Nature of Sofware Desia| racking Core Design Problem: Coereponad ‘the Probl Qealing with Revealing Design Problem strategies for Solving Revealing Problems orking on the Res biography H@ve RuBoard ive es in Copyright Many of the designations used by manufacturers and sellers to distinguish thelr products are claimed as trademarks. Where those designations appear in this book, and Addison-Wesley was aware of a trademark claim, the designations have been printed with initial capital letters or in all capitals. The authors and publisher have taken care in the preparation of this book, but make no expressed or implied warranty of any kind and assume no responsibilty for errors or omissions. No liabllty is assumed for incidental or consequential damages in connection with or arising out of the use of the information or programs contained herein The publisher offers discounts on this book when ordered in quantity for bulk purchases and special sales. For more information, please contact: US. Corporate and Government Sales (600) 32.3419 orpsales @pearsontechgroup con] For sales outside of the U.S., please contact: International Sales (17) 581-3793 [email protected]] Visit Addison-Wesley on the Web: |nww.awprofessional.co Library of Congress Control Number: 2002112298 Copyright © 2003 by Pearson Education, Inc. All rights reserved, No par of this publication may be reproduced, stored ina retrieval system, or transmitted, in any form, or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior consent ofthe publisher. Printed inthe United States of America. Published simultaneously in Canada. For information on obtaining permission for use of material from this work, please submit a written request to: Pearson Education, no Rights and Contracts Department 75 Arlington Street, Suite 300 Boston, MA 02116 Fax: (617) 848-7047 Text printed on recycled paper 12345678910—CRW—0605040302 First printing, Noveriber 2002 ve RuBoard ive es in Foreword by Ivar Jacobson ‘Software development is very different than it was over 10 years ago when Rebecca first introduced us to Responsibilly-Driven Design. Use cases are now widely used to gather system requirements. The Unified Modeling Language Is now the common too! for describing software designs and architectures. Object-oriented languages are everywhere. Business pressures demand that we develop systems quickly and react to changing market demands, Good software design, however, remains essential. Object Design advances the state of the art as well as the practice of software design using objects. It offers a powerful way of thinking about software in terms of roles, responsibiities, and collaborations. Use cases speciy the role of your system when interacting with its users. Designers transform use cases into responsibilities of objects. This higher-level view of a design, which focuses on responsibiities that are tied to your system's usage, helps you step away from implementation detalls and focus on What the appropriate software machinery should be. Once you understand that, then you can decide how to implement your design using classes, interfaces, and inheritance hierarchies. Object Design presents a "theatre of design ideas." Its full of stories, design examples, and commonsense advice. It offers a vocabulary for characterizing object roles, application control styles, and design problems. It presents practical strategies for nding candidate objects and offers sound advice for naming them. This book is more than an introduction to design. It also offers in-depth treatments of design topics that will be of interest to the most experienced software designers. it explores how to effectively use design patterns, make trade-offs, and reason about design alternatives. It demonstrates the consequences that seemingly simple design decisions have on the distribution of responsibilities among collaborators. In the chapter on control style, the authors present one solution to a problem and then work through several alternatives, discussing each of their relative merits. ‘Another chapter Is devoted to designing rellable collaborations and establishing “trusted” collaboration regions. This book takes design seriously! There isn’t just one way to think about and describe a design. Informal techniques and tools can complement more formal ones. In this new, agile world, we need to use a variety of tools and techniques to communicate design ideas. Whether you are new to object technology or an experienced developer, this book Is a rich source of practical advice. var Jacobson Rational Software Corporation August 2002 ive es an ive es in Foreword by John Vilssides What makes for effective pedagogy? Well, frst you avoid words like "pedagogy." Next, you leam alll about your subject because a robust mental model is a prerequisite to enlightening others. Then you need a stockpile of examples that illustrate the model—varied examples that hit it from different angles. Finally, you must present the ‘material smoothly and progressively ke the graceful blooming of a rose under time-lapse photography. If that’s the gist of good teaching, then this book is its embodiment. Rebecca and Alan are master expositors, and they have done a masterful job conveying Responsiblty-Driven Design, their model of object-oriented expertise. Conceived in the late 1980s, Responsibilty-Driven Design has developed into a principled yet pragmatic approach with a big following. It was perhaps the first methodology to capitalize on the fundamental advance of objects—moving away from a mathematical, algorithmic view of programming to one of autonomous objects, each with its own responsibilties, collaborating in time and space much as people do. Object languages had captured the ‘mechanisms that made an advance possible; Responsiblly-Driven Design captures the thinking and practices that ‘make objects live up to their promise. This book explains the concept and practice of Responsibilty-Driven Design in the context of modern software technology, rich with examples in contemporary object language, informed by the growing body of software patterns, ‘and couched in notational (read UML") standards. Unlike many works with comparable goals, there's nothing daunting about this book. The authors ease you nto the material and keep you engaged with a steady revelation of wisdom, From beginning to end, this book teaches effectively. But this isn't just a book for beginners. I's filed with practical techniques and advice for all practitioners, experts, included. The more expertise you have, the harder itis to know what you don't know, and the more susceptible you become to over design and the dreaded second-system syndrome. The authors’ treatments of flexibility and the nature of software design is especially insightful, revealing the relationship of variability to problem focus, strategies for solving "wicked" problems, and the synergies between agile and Responsibilty-Driven Design. No matter what your technical persuasion, regardless of the school of design you practice, the wisdom here will enlighten you. You're holding the definitive work on Responsibilty-Driven Design of object software. More importantly you're embarking on what may be the most efficient path to designing better software. John Viissides IBM T.J, Watson Research Tews [rss |e ive es in Preface This book is about designing object software. Like many human endeavors, design is part art, part engineering, and part guesswork and experimentation. Discipline, hard work, inspiration, and sound technique all play their parts. Although software design is a highly creative activity, the fundamentals can be easily leamed. Strategies and techniques exist for developing a design solution, and this book is packed with practical design techniques that help you get the job done. We hope you will become adept at thinking in objects and excited about devising solutions that exploit object technology. You can consider design choices only in light of what you know to be relevant and important. To achieve good results, you need to learn how to discriminate important choices trom mundane ones and how to acquire a good set of techniques that you intelligently practice. The Informal tools and techniques in this book that don't require much ‘more than a white board, a stack of index cards, a big sheet of paper, and chairs around a table. Oh yeah, be sure to bring your brain, too! But more important than a grab bag of techniques are the fundamental ways you view a design. Although the techniques we present in this book are independent of any particular Implementation technology or modeling language or design method, our approach to object design requires a specific perspective: (Objects are not just simple bundles of logic and data. They are responsible members of an object ‘community. This approach, called Responsibilty-Driven Design, gives you the basis for reasoning about objects. Most novice designers are searching for the right set of techniques to rigidly follow in order to produce the correct design. In practice, things are never that straightforward. For any given problem there are many reasonable solutions, and a few very good solutions. People don't produce Identical designs even If they follow similar practices or apply Identical design heuristics. For each problem you approach, you make a different set of tactical decisions. The effects of each small decision accumulate. Your current design as well as your current lines of reasoning shape and limit subsequent possibilities. Given the potential impact of seemingly inconsequential decisions, designers need to thoughtfully exercise good judgment, Your primary tool as a designer Is your power of abstraction—forming objects that represent the essence of a working application. In a design, objects play specific roles and occupy well-known positions in an application's architecture. Each object is accountable for a specific portion of the work. Each has specific responsibilities. Objects collaborate in clearly defined ways, contracting with each other to fulfll the larger goals of the application, Design is both a collaborative and a solo effort. To work effectively you need not only a rich vocabulary for describing your design but also strategies for finding objects, recipes for developing a collaborative model, and a framework for discussing design trade-offs. You will find these tools in this book. We also explore how design pattems can be used to solve a particular design problem and demonstrate thelr effects on a design. We present you with strategies for Increasing your software's rellabllty and flexibility. We discuss different types of design problems and effective ways to approach them. This book presents many tools and techniques for reasoning about a design's qualities and effectively communicating design ideas. Whether you're a student or a seasoned programmer, a senior developer or ‘a newcomer to objects, you can take away many practical things from this book. ve RuBoard (ve RuBoard nm How To Read This Book This book is organized into twp major pars. Tre eo asad Design Concepts papier J iesponsibilty-Driven Design, Bhapter J Finding Objects chapter f Responsibitties Chapter 9, Collaborations, and aptar q Control Style—form the core of Responsibilty-Driven Design principles and techniques. You should get a good grounding by reading these chapters. Desig, pons ae tou of Responeity Driven Design n prac papier Fang bce. pecans statogls for aeacing and eualy mpartant jecng candidate obec in an emerging desgn mace, agi d Enastard calsboratons, ques mary practe! pe and examples of howe covelon acotaboaion noofnast | Taz Hor nalnges ou may enn ayo lp your bn ac hr ovr soc "Brier sexo cecsres now to caracorze stare varstens and design upper ps ‘ gree Desig, dacures ho So8 design robes noone tee buckts—ne core he eveang. an the roan tet each coer ive awa fs rrevious] Next] ive es in Acknowledgments Alot of people have helped us in this endeavor, and we wish to acknowledge and thank them, First, we would lke to thank our design clients and students, who over the years have kept us on our toes, have offered much support and enthusiasm for our ideas, and have kept our focus on the practical We'd also lke to thank our colleagues and friends with whom, over the years, we've had many thoughtful design discussions. While at instantiations, and later at Digitalk, we found good design practices and techniques a frequent and energizing part of dally discussions. Our fellow consultants and trainers kept us honest: If a design technique or concept didn't work for a real client with a real problem, it was ditched. As a consequence, what's in this book has been proven in the trenches. And thanks to the engineers at instantiations, who while they built amazing object-oriented applications and tools to support Smalltalk development, offered pearls of wisdom whenever we were able to divert their attention from thelr keyboards long enough to discuss thelr current design challenge. We'd also like to acknowledge our editor, Paul Becker, the publication staff at Addison-Wesley, and our reviewers. Paul, you offered constant, unwavering support. Thanks. Rebecca's Acknowledgments | would like to acknowledge several people who have been a spark of inspiration or a source of strength. First, dike to acknowledge my coauthor, Alan McKean. You truly are a student of design. You like to think and talk and reflect. You are excited about exploring ideas and turning them into things of value you can teach your students. Thanks for being my constant collaborator, coauthor, and friend. I'd also like to acknowledge Dave Squire, who (long ago as my ‘manager at Tektronix) gave me this challenge: "Either write a book on design, lead the color Smalltalk project, or manage the engineering team. You've got to pick one and just do it." Ignoring Dave's advice, | managed to do all three. And Ive been juggling the roles of designer, author, and manager ever since. Thanks, Dave, for believing | had something to write about that others would want to read, Sharon Holstein encouraged me more than she knows when she commented on my first solo efforts at writing in the Smalltalk Report. She told me that she liked reading what | wrote because It was just like having a conversation with me. John Schwartz is another colleague who sharpened our Ideas. John read and ripped on each and every chapter of this book. | learned to not only accept but also relish his. advice, and our book is better because of it. Finally, Id like to acknowledge the constant support and occasional words of wisdom from my best friend and the best designer | know on this planet: my husband, Allen Wirts-Brock. Allen, you know how to chip in ideas at just the right me and give me that gentle prod or word of encouragement. Alan's Acknowledgments My ideas about design are very broad. The Universal Traveler, by Don Koberg and Jim Bagnell, a design book from the 1970s, puts it well "Design Is the process of making your dreams come true.” | would lke to acknowledge many of the people who moved me along that path of fulfilment. R. Buckminster Fuller, architect, industrial designer, philosopher, mathematician, poet, and humanitarian, for demonstrating how to live a life in which genius Involved both heart and mind, He helped me know that | could make the world a better place. Murshida Vera Corda, Sul teacher, for showing me that laughter is the ultimate language. She opened my doors of perception, Richard Britz, architect, teacher, builder, and friend, for inspiring me with his devotion to good work. Surely a member of my karass. ‘Sarah Douglas and Art Farley, professors at the University of Oregon, for starting me along the Smaltalk path. Rebecca Wirts-Brock, business partner and friend, for hiring me at instantiations. Our work together has been more collaborative and stimulating than | had even hoped Walter and Marjorie McKean, my parents, who gave me their al. Their devotion to each other is an inspiration to everyone who knows them. My wife, Brenda Herold, and my son, Jesse Vaslinda, my life's companions. Most of al, for showing me that love is a verb, ive es an ive es in Chapter 1. Design Concepts Alan Kay's favorite metaphor for software objects is a biological system. Like cells, software objects don't know what goes on inside one another, but they communicate and work together to perform complex tasks. In contrast, ‘monolithic software Is ike a mechanical clock containing innumerable gears. Each gear functions uninteligently and only in relation to other adjacent gears. That design is hopelessly flawed. "When you're building gear clocks, eventually you reach a certain level of complexity and i falls in on itself," says Kay. AA software object may be machinalike, but, crafted by a thoughtful designer, it can be very smart. It makes decisions; It does things and knows things. It collaborates with potentially many other objects. Living in an enclosing machine, it |s awhole on one level and a part on another. As with a machine, or a cell, the behaviors of an object are strictly limited to those that are designed into it. Cells and objects follow programmed instructions. But the dynamic behavior of a software system emerges from the interactions of many abjects—each contributing, each playing a responsible role. ive es [rss |e ve RuBoard Object Machinery All but the simplest of devices, both hardware and software, are designed from parts. These parts interact according to someone's plan. In a physical machine, these parts touch one another or communicate through a shared medium. Their interactions may give way to force, transfer motion, or conduct heat Like all good questions, "What is an object?" raises a number of others. How do objects help us think about a problem? How are object applications different? Once we have found an object solution, can ‘we use it again for other purposes? ‘Software machinery Is similar to physical machinery. A software application is constructed from parts. These paris—software objects—interact by sending messages to request information or action from others. Throughout its lifetime, each object remains responsible for responding to a fixed set of requests, To full these requests, objects, encapsulate scripted responses and the information that they base them on (see Figure 1-1). It an object is designed to remember certain facts, it can use them to respond differently to future requests. Figure 1-1. An object encapsulates scripts and information. maintains connections makes decisions (to other objects) (to do the right things} ‘So how do we invent these software machines? At the heart of object-oriented software development there Is a violation of real-world physics. We have a license to reinvent the world, because modeling the real world in our machinery is not our goal. Building an object-oriented application means inventing appropriate machinery. We represent real-world information, processes, interactions, relationships, even errors, by inventing objects that don't exist in the real world. We give life and intelligence to inanimate things. We take difficult-to-comprehend real-world objects and spit them into simpler, more manageable software ones. We invent new objects. Each has a specific role to play In the application. Our ‘measure of success lies in how clearly we invent a software reality hat satisfies our application's requirements—and ‘ot in how closely it resembles the real world. For example, filing out and filing a form seems simple. But to perform that task in software, behind the simple forms, the application is validating the data against business rules, reading and refreshing the persistent data, guaranteeing the consistency of the information, and managing simultaneous access by dozens of users. Software objects display Information, coordinate activities, compute, or connect to services. The bulk ofthis machine is our invention! We follow a real-world metaphor—forms and fles—but our object model includes a much richer set of concepts that are realized as objects. Because they have machinelike behaviors and because they can be plugged together to work in concert, objects can be used to bulld very complex machines. To manage this complexity, we divvy the system's behaviors into objects that play well-defined roles. I we keep our focus on the behavior, we can design the application using several complementary perspectives: An application =|a set of interacting objects An object =/an implementation of one or more roles Arole =/a set of related responsibilities A responsibility =/an obligation to perform a task or know information A collaboration an interaction of objects or roles (or both) A contract =|an agreement outlining the terms of a collaboration "We take a handful of sand from the endless landscape of awareness around us and call that handful of sand the world. Once we have the handful of sand, the world of which we are conscious, a process of discrimination goes to work on it. This is the knife. We divide the sand Into parts. This and that. Here and there. Black and white, Now and then. The discrimination is the division of the conscious universe into parts.” —Robert Pirsig ieee in ive es in Roles No object exists in isolation. Its always part of a bigger machine. To fit in, an object has a specific purpose—a role it plays within a given context. Objects that play the same role can be interchanged. For example, there are several providers that can deliver letters and packages: DHL, FedEx, UPS, Post, Altborne. They all have the same purpose, If not the same way of cartying out their business. You choose from among them according to the requirements that you have for delivery. Is it one-day, book rate, valuable, heawy, flammable? You pick among the mail carriers that ‘meet your requirements, [Arole is a set of responsibilities that can be used interchangeably Itis useful to think about an object, asking, "What role does it play?" This helps us concentrate on what it should be ‘and what it should do. We have been speaking of objects and roles loosely. What Is the real difference? When a role Is always played by the same kind of object, the two are equivalent. But if more than one kind of object can full the same responsibilties within the community, a role becomes a set of responsibilities that can be fulflled in different ways. A role is a slot in the software machinery to be filed with an appropriate object as the program runs. ine iowa fs rrevious] vex] ive es in Object Role Stereotypes ‘A well-defined object supports a clearly defined role. We use purposeful oversimpliications, or role stereotypes, to help focus an object's responsibilities. Stereotypes are characterizations of the roles needed by an application Because our goal Is to build consistent and easy-to-use objects, itis advantageous to stereotype objects, ignoring specifics of their behaviors and thinking about them at a higher level. By oversimplifying and characterizing it, we can ponder the nature of an object's role more easily. We find these stereotypes to be useful © Information holder—knows and provides information © Structurer—maintains relationships between objects and information about those relationships © Service provider—performs work and, in general, offers computing services Coordinator—reacts to events by delegating tasks to others Controller—makes decisions and closely directs others! actions © Interfacer—transforms information and requests between distinct parts of our system Just as an actor tries to play a believable part in a play, an object takes on a character in an application by assuming responsibilities that define a meaningful role Software machinery is made of computation of information, maintenance of relationships, control of external programs and devices, formatting of information for display, responding to external events and inputs, error handling, and decision making, (Once we assign and characterize an object's role, its attendant responsibilities will follow. An object may ft into more than one stereotype. But sit playing one or two roles? Often we find that a service provider holds information that it needs to provide its service. In doing so, it assumes two stereotypes—information holder and service provider—but only one role because the responsibilities are all wrapped up together for the same customers to use. If its information Is being sed solely to suppor its service, it assumes two stereotypes but only one role. But iit is perceived as serving two different types of clients for different purposes, It Is Ikely playing two roles. ‘Some objects are hard to stereotype because they seem to fit into more than one category. They'te fuzzy. How can you choose? You must decide what you want to emphasize. A transmission Is a service provider if you emphasize the multiplication of power by the gears. Itis an Interfacer If you emphasize its connections to the engine and wheels. Can objects have more than one stereotype? If you want to emphasize more than one aspect, that's OK. There are blends of stereotypes, just as there are blends of emphasis. ine iowa fs rrevious] Next] ive es in Roles, Responsibilities, and Collaborations ‘An application implements a system of responsibilities. Responsibilities are assigned to roles. Roles collaborate to carry out their responsibilities. A good application Is structured to effectively fulfll these responsibiities. We start design by inventing objects, assigning responsibilities to them for knowing information and doing the application's work. Collectively, these objects work together to fulfil the larger responsibilities of the application. Objects and their responsibilities provide the common core for our new development process, techniques, and tools. (One object calls on, or collaborates with, another because it needs something. Both parties are involved. One needs help; the other provides a service. Objects work in concert to fultill larger responsibilities. Designing collaborations forces us to consider objects as cooperating partners and not as isolated individuals. Design is an iterative and. Incremental process of envisioning objects and their responsiblities and inventing flexible collaborations within small neighborhoods. Clearly defined objects that stick to the point when Implementing thelr roles are easier to understand and maintain, The services that an object holds and the information that an object provides define how it behaves when it exists alongside other objects. In early design, itis enough to know that particular responsibilities are clustered into objects. First and foremost, an object is responsible for providing and doing for others. A design model arranges responsibiities among objects. We will explore this issue in greater detail later, but, for now, consider this: [An object embodies a set of roles with a designated set of responsibilities, {As shown in Figure 1-4 an application is a community of objects working together. They collaborate by sending requests and recelving replies. Every object is held responsible. Each contributes its knowledge and services. Figure 1-2. Objects collaborate to solve larger problems than they can handle alon knows performs information. services maintains connections (to other objects} message asking for help makes decisions (to do the right things) needs help ‘An object can be more inteligent if does something with what it Knows. The smarter it gets, the fewer detalls a client must know to use its services. So the client Is liberated to do its work rather than take on the details of figuring ‘out something that it could have been told. Blending stereotypes makes the responsibilities of clients using these hybrids easier, streamlined, and to the point. Such clients can focus on their problem, not on putting litle detalls together that their helpers could have done. Making objects smarter has a net effect of ralsing the IQ of the whole neighborhood. Making objects smarter also makes the system more efficient. Objects can stick to thelr specific tasks, rather than worrying about detalls that are peripheral to thelr main purpose. When objects do collaborate, they are designed to follow certain protocols and observe specific conventions: Make requests only for advertised services. Provide appropriate information. Use services under certain conditions. Finally, accept the consequences of using them. Object contracts should describe all these terms. However, some of the value of a given object is determined by its neighbors. As we conceive our design, we must constantly consider each object's value to Its Immediate neighborhood. Does it provide a useful service? Is it easy to talk to? Is ita pest because it is constantly asking for help? Are its effects the desired ones? The fewer demands an object makes, the easier itis to use. The more it can take on, the more useful itis. if an object can accommodate many different kinds of objects that might be provided as helpers, it makes fewer demands about the exact kinds of objects It needs around it to perform its responsibilities. Although we don't want an object's clients to have to know all these detalls, we designers must consider this as we balance what each object offers to its clients with the requirements and demands that it places on its neighbors. Roles! Responsibiities! Collaborations! We use the roles-responsibllties-collaborations model in each of our activities to keep our focus on the behaviors of our software machinery. As our understanding of the problem grows, the roles and responsibilities of our objects evolve. We design and redesign the community's neighborhoods and the ways they interact. We reinvent the object roles and shift responsibilities among them until they “ft,” work together, satisty external constraints, and their responsibilities clearly support their purposes. We pin down more of the details until we reach the point where we can eventually bind the responsibilities to executable code. Tews an ive es in Object Contracts In well-bounded situations, itis possible to know a good deal about whom an object interacts with, the circumstances under which itis used, and what long-term effects an object has on its environment. These are spelled out in object contracts. They deepen our knowledge of an object's responsiblities and bulld our confidence In our design. Without saying how these things are accomplished, they show the conditions under which these responsibilties are called upon (conditions-of-use guarantees), and what marks they leave when they are finished (aftereffect guarantees). ‘An object contract describes the conditions under which it guarantees its work and the effects it leaves behind when its work is complete. Conditions-of-Use and Aftereffect Guarantees Knowing who collaborates with whom says nothing about when collaborations can succeed. "What do they expect from me? Under what conditions do | guarantee my services? My methods may only be called in this order!" For the designer to be confident that the objact will perform the request, the requirements it places on its context must be described in its conditions-of-use. For each responsibilty, any objects or internal values (or both) that affect its behavior should be noted, and any controls on them should be described This fine print of a contract specifies the conditions-of-use for each service and specifies the aftereffects of using each of the object's services. When an object is used outside its specified conditions-of-use, Its not obligated to fulfll the request! If an Account object has responsibilities for withdrawing cash, what are the conditions-of-use? One is that the balance be greater than or equal to the amount being withdrawn! Or it may be more complex than that, depending on the bank's policies regarding individual customers. The extra effort in describing these conaitions-of-use pays off in Increased reliabilty and robustness. Contracts are really meaningful only in the programmer's mind, Objects don't look for advertisements and read contracts; a programmer does, and writes code with those contracts in mind, Remember, an object's contracts with others describe how it interacts with them, the conditions under which it guarantees its work, and the effects it has on other members of the community. For our purposes in design, itis sufficient to know that particular services are clustered in interfaces and that these services will call on each other and succeed given the correct conditions. iowa [rss |e ive es in Domain Objects Domain objects provide a common ground in which developers and users can meet and discuss the application, Domain objects represent concepts that are familiar to users and experts In a specific field of interest. We reason about a banking application using accounts, deposits, withdrawals, interest rates, and the like. In an aitline booking application, we speak of reservations, aiplanes, seats, destinations, schedules, and so on, as concepts that we will find in our software object model. Later, we develop the underlying structures and code and run scenarios for using the software. Given that users and experts are familiar with these domain concepts, they can discuss these aspects of the application easily. They feel comfortable manipulating these domain objects’ information directly, and they Understand the procedures for requesting thelr services. For the developers, these domain objects are only the starting point for constructing a model of the domain and for developing the internal representations of these and additional concepts that will exist in the software machinery. Although the original, “common” concepts might not prove valuable in the executable system, they should be traceable through the design because they clearly express the stakeholders’ understanding and Issues surrounding the application, ‘Although not every software design effort starts by creating a domain model, most designs consist of certain objects that represent concepts familiar to experts in a particular domain supported by the application. In an object-oriented application, the domain is made of information and services that the user needs, along with structures that relate the two (see Figure 1-3). For example, an inventory control system consists of monitoring the stock on hand (information), adding and removing the stock (services), and supporting policies for maintaining related stock (relations). These three aspects (information, services, and structures) apply to virtually all data-centric applications, and we use them to guide our development of objects that fulfil these roles. Figure 1-3. A domain model does not represent the entire domain as it Is In the real world. It includes only the concepts that are needed to support the application. haar ren /@ customer ‘a stock Information ae Services {a shipping rule The objects in a domain model embody the application's logic in thelr interactions. The domain model captures, at the ‘most abstract level, the semantics of the application and its responses to the environment. It doesn't represent all concepts of a domain but only those that are necessary to support the application's intended scenarios of usage. The Individual objects in the domain model hold the real, concrete responsiblities for responding to the user actions and for creating the new information that the user requires. If we are only describing a car and arent building a model to execute on a computer, i's enough to construct a domain model that includes, among other things, a frame, an engine, a transmission, a steering wheel, a steering box, a steering column, wheels, and brakes. But when we must run it on a computer and design user interactions, we find that the domain of real-world race cars lacks many Important behaviors. We need a richer set of objects and a richer domain—that of a simulated race car in a computer game. Its important to choose the right domain for your design problem and to recognize that objects designed to work in one domain won't easily sip into another, seemingly similar domain. For example, in a race car simulation, the cockpit, racetrack, and competing cars must appear on the screen as visual images. What object from the domain of the real-world race car will do this? There isnt one! So for this, specialized purpose, we must invent an object that presents the program Images and captures user input: an Interfacer. hoveratoes fs rrevious] vex] ive es in Application-Specific Objects ‘Similarly, we need objects to translate the computer's user inputs (mouse clicks, joystick movements) to commands to appropriate objects in the racing application, These objects transform or filter user information and then call other appropriate objects to action. Or they may sequence movement from one screen to another, switching views of the race track and replaying the Images and sounds of exciting crashes. These computer and application-speciic objects—the interfacers, coordinators, and special service providers—supplement the domain model of the simulated race car with program-specific behaviors and glue the application together. Object-oriented software Is a community of objects. In this community, each citizen provides Information and computing services to a select group of its neighbors. The design of well-formed pattems of collaboration lies at the heart of any object design ‘As we shift our view from the model of the domain to objects that are important to the actual workings of the software, we encounter many such application objects. For example, when a typical application is launched, there is at least one special startup object that creates the first population of objects. When this group is initialized and ready, the startup object passes control to them. The application is off and running. As the user navigates through the application, ths intial group of objects responds to user actions, either by directly fulfling the requirements of the application or by creating and delegating work to a new batch of objects that have been designed for specific purposes. As execution continues, new citizens of this object community are born, live, and dle, according to the needs (and design) of the application Designers construct an executable application that is "true" (by some argument) fo other stakeholders’ views, even as it adds many new application-specific objects: objects that monitor inputs and user events; application-specific data formatters, converters, and fiters that act out thelr roles behind the scenes; and other objects that reach out to the extemal world of databases, devices, networks, and other computer programs (seeFiqure 1-4. Developers naturally need a more detalled view. Figure 1-4. An application model supplements the domain model with computer-specific objects for responding to the user, controlling execution, and connecting to outside resources. Relationships /a customer] an order an order manager I - discount a shipping rule ‘The user interface, application specifies, domain concepts, and even persistent stores can be viewed logically or concretely. Users and domain experts typically are concerned only with a more abstract, or logical, view. Developers are interested in al views of the system and they must move among Implementation details, design, and more abstract concepts if they want to communicate effectively The user's and the designer's views represent two different levels of thinking about applications and objects. The user view holds a representation of the highest-level concepis—the information, services, and rules of the domain under consideration. The designer invents aspects of coordination and connectivity to other systems and devices, reasoning about the application in a fundamentally different, lower level: the level of computer processes, computations, translation, conditional execution, delegation, and inputs and outputs. The key to developing a successful application lies in our ability as designers to wed these two views without compromising either. hoveratoes fs rrevious] vex] ive es in Interfaces Eventually, an object expresses its responsibilities for knowing and doing for others in methods containing code. An Interface describes the vocabulary used in the dialog between an object and its customers: "Shine my shoes. Give me my shoes. Thatll be five bucks, please. Here's your receipt." The interface advertises the services and explains how to ask for them. Itis offen important to know more than just what an interface declares. To use an object's services, the conditions Under which a service can be Invoked may be Important. Or an important side effect may need to be revealed. Consider a gear in a machine. The number of teeth and the spacing between the teeth defines the gears interface. This determines whether a gear wil fit into a machine. But what if we replace one gear with another, built from a different alloy than the other gears? This new gear fits the interface, but as the gears turn, it may tend to overheat or break because it has different stress load characteristics. Its interface says nothing about this real-world limitation. ‘The more we publish about the behavior of an object, the more likely it is that it will be used as its designer intended. From a client's viewpoint, an object is more than its interface: |An object implements interfaces and affects other objects. We separate an object's design into three parts: its public interface, the terms and conditions of use, and the private detalls of how it conducts its business. ‘So what about information hiding? We're not talking about exposing everything about an object, but only the services {and terms that are of concern to the client. We purposely hide the workings of our object's machinery. An object Is a semiautonomous member of the community, stating, "i's none of your business how I do my job, as long as I do it according to our agreement! | don't want customers peeking inside to see how I conduct my business.” Its the implementation of the object, not what to expect from it, that should be hidden. Only the designers of an object's inner machinery should care about how an object implements its responsibilities. ieee nn ive es in Classes The term class's used, in mathematics and in everyday life, o describe a set of lke things. It describes all of these elements in a general way but allows each instance of the class to vary in nonessential features. Whereas the class Is abstract and conceptual, the instances are concrete, physical objects. The visual image that appears to us at the ‘mere mention of a tree contains the essential features that enable us to recognize any of the Instances of tree when we see one, We easily distinguish between a car and a truck when one vehicle adheres to one description or the other, sport utlity vehicles aside. This everyday notion of a class also applies to software objects. We bulld our applications from sets of Ike objects. But a software class has some features that are specific to the software world, An object-oriented programming language allows a programmer to describe objects using classes and to define their behaviors using methods. There are additional requirements of an object-oriented programming language, but these two are key. They provide us with all that we need to bulld an application from objects. Unlike a mathematical class, a software class is not simply an abstraction. Like the instances that it desoribes, its concrete. To see it, you don't have to conjure it rom nothing because it is described on index cards, diagrammed with a design notation, and written in programming code. You can pick it up, tum it over, read its description. itis an object. The features that we give the class are the features that we desire in Its instances. Every responsibilty for “Knowing,” "doing,” or “deciding” that we assign to its instances becomes concrete in the class definition and the Instance methods that the class contains. Two Roles Ifa software class provides two distinct sets of services, usually to two different sorts of clients, the class is said to play two roles. First, it plays a role that has no real-world analog. During program execution, a class acts as a factory for manutacturing, or instantiating, the instances required by the program (see Eiqure 1-9. It populates the computer memory with physical, electromagnetic objects, and it binds these memory areas to sets of instructions that they are responsible for. Our design objects—the abstract machines, roles, and clusters of responsibilty that we invent to salisty our design requirements—become classes in program code. Figure 1-5. A class, when acting as a factory, manufactures (instantiates) objects that the application needs. a customer] a customer! customer la customer] Classes play two roles. First, they act as factories, instantiating instances and implementing responsibilities on their behalf. Second, they act as an independent provider, serving clients in their neighborhood. ‘A class holds the blueprints for building instances. By defining a set of instance methods, it declares the names of the behaviors that other client objects can use. When an instance responds to a request from a client, it performs the corresponding method scripted in its class. The detalls of how the instances perform a task are pinned down in the Instance's class definition and in its collection of instance method definitions. By browsing the instance’s class and its Instance methods, you can see whether the instance performs its responsibilities alone or delegates portions of its task to other objects in its neighborhood. Classes hold the "shape" of the objects that they make. Classes are the building blocks of our application. Just as we describe a single object through the attributes and operations defined in its class, we describe the relations among instances via corresponding relations among classes. For example, the millions of ownerrelations between people and cars can be abstracted into a single owner relation between the classes of the two. Relations among classes describe the myriad potential relations among run-time instances. In addition to its role as an object factory, the class can act as an object itself, with its own set of responsibilities. In this role, it provides information and services to other objects through its own interface. Orten, its only cllents are the Instances that ithas produced, but in other cases, itacts as the sole provider of data and services to a number of different kinds of objects. In fact, as shown in Figure 1-4. when a single object ofits kind is sufficient, a class can be designed to shed its instance factory role and assume the role of the object that is needed, Figure 1-6. A class can also act as an object when the application needs only one of its kind. Lee Customer class as collaborator Despite a shared definition, instances wil often behave differently because their behavior can depend on the values of thelr private data or different helpers in their neighborhood, Given the same conditions, all instances of a given class behave in the same way. They form a set of ike objects. Each has a structure identical to the others, along with a set of methods that it shares with the others of its kind. Because each instance is a separate object with its own internal data areas, it can hold private data that it shares with ‘no other. When asked to perform one of its responsibilities, it can base its response on this private data. A smart object encapsulates data that affects its decisions about how it fulfls its responsibilities. "The object has three properties, which makes it a simple, yet powerful model building block. It has state so it can model memory. It has behavior, so that it can model dynamic processes. And it Is encapsulated, so that it can hide complexity. —Trygve Reenskaug Each instance performs its tasks in two contexts. It behaves according to rules established by the community in which it lives, and it controls its actions according to its own private rules and data. The rules are usually embedded Inthe methods as conditional statements in a programming language. An object's state Is reflected by data held in Instance variables. These variables define the internal structure of an object and are one way an object sees others in Its neighborhood; an object can hold references to others. These references allow an object to "see," and subsequently interact, with others. These references say nothing about how they interact—only that the potential exists for collaboration, ine awa fs rrevious] vex] ive es in Composition There are only two types of relationships in an object model: composition and inheritance, Both have analogs in a family tree. A composition relation is like a marriage between objects. It is dynamic, it happens during the participating objects’ lifetimes, and it can change. Objects can discard partners and get new partners to collaborate with, Inheritance relations are more lke births into the family. Once it happens, Its forever. Just as both marriage and ancestry appear in the same family tree, composition and inheritance coexist ina single object model. A amily tree describes the structural relations of a group of people. Someone Is added to the tree In one of two ways: by marriage or by birth. We can extend an object's capabilities by composing it from others. When It lacks the features that it needs to futfll ne of its responsibilties, we simply delegate the responsibilty for the required information or action to one of the objects that the object holds onto. This Is a very flexible scenario for extension. As the program continues execution, it plugs components together, dynamically, according to the conditions of the application, For objects to communicate, they must know about each other for the duration of thelr collaborations. Composition is. one way to create those paths of communication. Passing a helper object along with a request, or creating a new Instance, are two other ways that an object gains visibility of potential collaborations. hoveratoes fs rrevious] Next] ive es in Inheritance Inheritance is another way to extend an objects capabilities. But whereas composition is dynamic, inheritance Isn't. It's static. The merging of the superclass responsibilities and the extension of its subclasses are done at compile time and not run time. Objects are not plugged together; instead, the descriptions used to compile them (the classes) are. ‘An instance uses anothers responsibilties through collaboration. An instancsassumes another's responsibiities through inheritance. Every inheritance relationship between two classes Involves two roles: the superclass role and thesubolass role. Each acts out its role during development. With few exceptions, a subclass assumes all of the responsibilities outlined in the superclass and adds new responsibilities of its own. The subclass inherits all of the features encoded In the superclass and has the responsibilty for instantiating objects having those features. The subclass extends the superclass. In this arrangement, the superclass contains features that are common to all of its subclasses, and each subclass not only creates its own instances but also adds features to them that are not described in the superclass. A subclass extends the superclass by adding attributes and operations. An instance’s responsibilities are the union of all of the responsibilities n its own class and all of the responsibilties of the superclasses that It inherits from. It's common to say that a subclass "specializes" its superclass because the added responsibilities make the subclass's role less general than that of the superclass. Classes sometimes relinquish thelr responsibilty for producing instances to their subclasses. These abstract classes define many of the features of instances, but they require subclasses to fillin some details and to do the actual ‘manufacturing, Inheritance relations demonstrate the Peter Principle. The higher ina hierarchy a class resides, the less capable of really doing anything it becomes. ine awa fs rrevious] vex] ive es in Object Organizations ‘As you begin to decompose your application into logical pieces, you may identify objects or roles and define classes that implement specific roles. You may also find design elements that have a certain logical integrity but, on further Inspection, can themselves be decomposed into smaller pieces. A common term for a logical grouping of collaborators is subsystem. Another term we use is object neighborhood. Within these organizations, objects dynamically form alliances and work together in a loosely knit community. By contracting with each other, such a confederation of objects serves a larger purpose than Is possible for any individual Each object in a confederation promises to fulfil the responsibilties outlined in its contracts. Thus, each object can depend on the others for a rellable and predictable response to its requests. Confederations are composed of potentially many objects and offen have a complex collective behavior. The synergy of the cooperative efforts among the members creates a new, higher-level conceptual entity ‘System architects may partition an application into subsystems early in design. But subsystems can be discovered later, as the complexity of the system unfolds. Viewed from the outside, a confederation offers a unified front. [Fiqure 1-7] shows an example. It isn just a "bunch of objects"; It forms a good abstraction. Although individually each object has a specific role and responsbbtes, i is the collective behaviors of the objects that define the confederation to the rest of the application. There is no conceptual difference between the responsibilties of an object and those of a subsystem of objects; itis simply a matter of scale and the amount of richness and detall in your design. Often, other objects interact with a confederation in limited ways. There may be a single object—a gatekeeper—that stands as the public representative of the larger group. Figure 1-7. This confederation of objects forms a company devoted to specific tasks. Acme Financial Consulting her assistant ive es in Components There are other ways to package and organize pleces of a design. Components typically are design elements that are Intended to be used in a number of different applications. But designers create components for other reasons, too. You can update or replace a component without reconfiguring the rest of the system. The insides of a component are hidden; its services are made available through a well-defined interface. Well-designed components, regardless of their implementation, can be plugged in and used by any object-oriented application. To be adapted for use, a component can provide interfaces that allow clients to plug in helper components or to set properties that control various aspects of its operation. You can design components to be used Independently or to be plugged together to build larger components or systems. Although a single class may not be a useful unit of reuse, a component that packages a number of services can be. Components enable medium-grained reuse. ieee nn ive es in Patterns ‘So far we've presented fundamental object design concepts. But there is more to object design than applying these basic techniques. The early adopters of object technology generated many successful object applications and strategies for solving problems. Wouldnt it be marvelous if we had those experts at our sides during our own projects to roll thelr expertise into our own problem-solving efforts? Well, this community of experts has developed a means to do just that: Patterns. There Is nothing mysterious about patterns. They simply capture the experience of expert practitioners by presenting solutions to commonly recurring problems in a readable and predictable format. But what good Is a solution if the problem is not well understood? What are the trade-offs? When is the solution applicable? Because problems and thelr solutions have an equally important context, patterns include descriptions of other aspects of the problem and its solution, Erich Gamma and several of his colleagues wrote the Design Patterns book (Addison-Wesley) in 1994, Their format for a pattern covers a lot of territory. It includes: © Patter name and classification © Intent © Also known as © Motivation © Applicability © structure © Paricipants © Collaborations © Consequences © implementation © sample code © Known uses Related patterns Most of the newer pattern books aren't so inclusive. Some patterns simply give a name to a problem and its solution. Other formats lle somewhere between these two extremes, For our purposes, let's boll a pattern down to this list: © Name: Communicates the pattern easily © Problem: Describes a recurring problem © Forces: Describes what considerations need to be balanced © Context: Describes where the solution is appropriate Solution: Can be talored to a specific problem Consequences: Let's be reall This is not to say that the other elements have no value, But this intermediate level of detail lets you be productive without getting bogged down in precision. However you break them down, patterns offer clear benefits to developers: © Vocabulary: In a team of any size, communications are a vital element of a successful project, Patterns establish a concise way of describing how a group of objects solve a problem, either behaviorally, structurally or both. © Expertise: Patterns capture the expertise of years of development. Because they are applicable to any domain, they can model the behavior and structure of a group of interacting concepts. © Understanding: Documenting how the system uses patterns enables new developers to quickly see the logical organization. By condensing many structural and behavioral aspects of the design into a few simple concepts, patterns make it easier for team members to discuss the design. Let's look at a common problem and see how an appropriate pattern contributes to a good design. Applying Double Dispatch to a Specific Problem To implement the game "Rock, Paper, Scissors" we need to write code that determines whether one object “beats” another. The game has nine possible outcomes based on the three kinds of objects (see Figure 1-8). The number of Interactions is the cross product of the kinds of objects. Figure 1-8. This UML sequence diagram shows the process of deciding who wins, based on checking object type. paper object is passed receiver checks as argument argument type :GameCoordinator Paper ‘Rock beats(aPaper) getClass().getName()| ASolution Case or switch statements are often governed by the type of data that is being operated on. The object-oriented language equivalent is to base its actions on the class of some other object. In Java, it looks like this: In class Rock public boolean beats(GameObject object) { if (object.getClass.getName().equals("Rock’) { result = false; } else if (object. getClass.getName().equals("Paper’) { result = false; } else if (object. getClass.getName().equals("Scissors") { result = true; } return result; This Is not a very good solution. First, the receiver needs to know too much about the argument. Second, there Is one of these nested conditional statements in each of the three classes. If new kinds of objects could be added to the game, each of the three classes would have to be modified. A Better Solution We would tke to come up witha solution that would let us avoid touching any working methods. Figure 1-Jshows an example that uses the double dispatch pattern to do that. Figure This UML sequence diagram shows the process of deciding who wins, based on polymorphism. paper object receiver delegates is passed to incoming as argument paper object /.GameCoordinator| paper object knows no if/then it beats rock decisions Note that rock does not need to know what kind of object itis comparing itself against. The second message clearly Identities the situation to the second object. Another Rock or a Paper will return false, but a Scissors will return true. Here are the GameObject, Rock, and Paper definitions in Java: Public interface GameObject { public boolean beats(GameObject o); public boolean beatsRock(GameObject o); public boolean beatsPaper(GameObject 0); public boolean beatsScissors(GameObject 0); } Public class Rock implements GameObject { public boolean beats(GameObject o); the receiver is a Rock. Ask the argument about rocks. return o.beatsRock(); } public beatsRock() { 1 could return either false or true return false; } public beatsPaper() ( 1a Rock doesn't beat a Paper return false; } public beatsScissors\) { 1a Rock beats a Scissors! return true; } } Public class Paper implements GameObject { public boolean beats(GameObject o) { {the receiver is a Paper. Ask the argument about papers. return o.beatsPaper(); } public beatsRock() { a Paper beats a Rock return true; } public beatsPaper() ( could return either false or true return false; } public beatsScissors\) { 1a Paper doesn't beat a Scissors! return false; } } Extending the application to include another kind of GameObject simply requires adding a new declaration of the comparison method to the GameObject interface, defining the new method in the existing classes, and creating a new class that implements the new GameObject interface The Double Dispatch Pattern Here's the pattern description: Name: Double Dispatch Problem: Select an action based on the type of two objects appearing in combination, Context: Sometimes you need to write code that makes decisions about what to do based on the class. of one of the parameters to a method. Forces: Case or switch statements are often used in procedural languages to decide what action to take, But deciding what to do based on the class of a parameter can result in code that Is hard to ‘maintain; each time you add a new class, working code will have to be modified. Polymorphism allows an object to send the same message to objects belonging to many different classes. Code in each of these classes can subsequently make different decisions and perform the same requested operation differently ‘Solution: Instead of writing code that specifically checks the class of a parameter, add new methods having the same name (a secondary method) to each class of all the potential parameter objects. Write {the original method to simply call this new secondary method, passing the original receiver as an argument. Its the responsibilty of each object receiving this secondary message to know specifically /what should be done. Typically, each secondary method tums around and invokes a specitic operation ‘on the original receiver (hence the name Double Dispater) ‘You can tie the specific operation to the class of object by appending the class name of each class that Implements a secondary method to the name of this specialized operation. If necessary, pass the original receiver as an argument to these specialized operations as well Consequences: Double Dispatch eliminates case or switch statements based on the class of a parameter. This makes the code that implements the design more maintainable. It doesn't completely solve the maintenance problem, but it supports extension by adding methods and not by modifying them, Double dispatching does have its drawbacks. Adding a new class of parameter means adding a secondary method to it, unless you are able to add a single method to a superclass and have it inherited| by its subclasses. It also may mean adding a class-specific method to the original object (or deciding to Invoke an existing operation). A case statement, however, is usually a worse solution. The Real Benefits of Using Patterns Imagine that during a design review, one of the team members mentions that a group of objects uses Double Dispatch. The discussion then centers on an analysis of the problem to see whether the pattem fits, the motives for choosing to use it, and a consideration of the trade-offs involved. The use of the pattern shifts the focus to a higher-level design concer. Litte time Is spent describing the mechanics of the object collaborations because they are condensed into two litle words: double dispatch, ive awa fs rrevious] Next] ive es in Frameworks, Inc. The business equivalent of a framework is a franchise. Having proven that there Is a market for its services, a company Incorporates and sells a generic design for Its business: a franchise. A franchise provides a general design for providing its products or services and dictates that franchise owners follow the franchising company's rules. Franchise owners tallor their businesses to their specific markets, within the limits of the franchise contract. With a franchise, services become better defined and widely known and used. Because of thelr familiarity with the business processes, owners often buy multiple franchises, reusing the business design in different locations. A franchise pools, business owners’ resources to advertise, train employees, and provide just-in-time services beyond those that a single company could offer. Simitay, a framework is general design for solving a software problem (see Figure 1-10). Unlke a patter, which is an dea of how to solve a familar problem, a framework provides library of classes that developers can tallor or extend to fit a particular situation. The success ofa framework depends on how useful itis to these developers and how easly they can tallr its services to thelr needs Figure 1-10. A framework codifies the rules of how things should be done. different sound cards have different behaviors, but each fits into the framework board/interrupts/elock/signals provide a framework that calls on parts slots are interfaces to the parts and the framework Here are some of the problems that frameworks have been applied to: © GUI: The Java Swing framework offers a set of features useful for bullding an interactive user interface, © Simulation: The early Smalltalk-80 language Included a framework for building discrete event simulations. © Programming environments: The Eclipse IDE (integrated development environment) has a plug-in architecture that lets tool providers supply different compilers, refactoring tools, and debuggers. © Web applications: Microsot's NET framework Is a unified set of tools for building distributed applications. it Includes frameworks for building user interfaces, performing transactions and concurrency, interoperating between platforms, and building Web services. Frameworks offer a number of advantages to the developer: Efficiency: A framework means less design and coding, Richness: Domain expertise Is captured in the framework. Consistency: Developers become familiar with the approach imposed by the framework, © Predictabilly: A framework has undergone several iterations of development and testing But they don't come without costs: © Complexity: Frameworks often have a steep learning curve. © ‘Iyou only have a hammer, everything looks lke a nall: Frameworks require a specific approach to solving the problem, © Performance: A framework often trades flexibilty and reusabilty for performance. Frameworks are sometimes used as is. n this case, they provide default behaviors that their designers deemed to be Useful across many potential applications. But most frameworks are meant to be extended to completion. They provide generic solutions but lack specific behaviors that vary by application. The behaviors that are left incomplete are hooks: implementations that are deferred to the developers for specific applications. When coding these hot, spots, a programmer must accept an inversion of control. This takes some getting used to. Typically, our code calls other objects and asks them to do work on our behalf. To use some functionality in a library, for example, you typically instantiate a library object and then call on It to provide a service. Inthe case of a framework, you must implement the hooks using code that fits into the framework. The hooks are those areas of the framework that the framework code will call. Instead of being in control, our objects are plugged in and must correctly implement hooks that are called by framework code. To use the features of a framework, you define classes that implement specific interfaces. To use a framework, you fill in the missing functionally, following the constraints dictated by the framework designers ive awa fs rrevious] Next] ive es in Architecture There is no single, defining architecture of an application. Often we see box-and-line drawings purporting to bethe architecture. Goof-juice! An architecture is a collection of behaviors and a set of descriptions about how they impact one another. Box-and-line drawings describe only the structure. They completely ignore the behavior. A revealing architecture demonstrates the assumptions that each subsystem or component in the application can make about its neighbors, whether it be thelr responsibilities, error-handling abilities, shared resource usage, or performance characteristics. Because there are many objects in an application, we need different ways of viewing its parts that, hide most of their details. The internal details of how a group of objects accomplishes a task should not be the issue when you consider its architecture. At the architectural level, the interfaces must tell tall Any single architecture description tells only part of the software's story. For example, the organization of system functions implies litle about how the modules are divided among team members for development. The process synchronization characteristics are conspicuously missing from the descriptions of how components are distributed ‘across machines and networks. Because there are many requirements of our software, we offen require many views of our “architecture” to convince us that it meets them, Which views shed the most light on our applications’ characteristics, of course, depends on the application. But several of these views are prominent: conceptual views, control flow, and, for object-oriented applications, views of components and subsystems as well as objects and interactions. It Is important to identify and document patterns of collaboration. Simply documenting the interfaces of the objects or components would not show how they collaborate. Writing the client-server contracts as part of the architectural descriptions clarifies the roles of each and provides a better understanding of the complexity of the design. Each development project should determine what subset of these architectures Is appropriate. In fact, choosing which architectural views to represent and study Is a key element of early design. hoveratoes fs rrevious] Next] ive es on Architectural Styles Just as design pattems otfer ways to distribute responsbities among collaborators to solve generic design problems, there are styles for organizing software objects. There are a number of aspects to consider when you think about architectural style. Two cof the most common viewpoints are component interaction styles and control styles. Both need to be considered. Component Interactions are concerned with issues that we commonly see addressed with block structure diagrams. These typically show components or layers of the system and generally describe how they are allowed to interact. Typical examples of these styles are layered, pipes-aneiters, and biackboard. Figure 1-1 ]showe a layered architecture. Figure 1-11. A layered architecture separates objects according to thei oles in the application. Presentation Applieation - J LU Bomain Ly Serviees Teehnieal | Services Control style dictates the approaches to distributing responsibilties for decision making and coordination within or between layers or components. We can construct a solution along a continuum of control from highly centralized to overly distributed. Each combination of architectural styles supports one or more characteristics that we may value in a project: © usapiity © Avaitbiity © security © Performance © Maintainabitty © Fexiilty © Portabiity To support these and other qualities before any analysis, design, or coding takes place, we can start by choosing architectural styles that support them. Using a particular mix of styles wil not guarantee that desired qualities will preval, but we have the window of opportunity left open in wich to bud them. Architectural styles have wel-known libilties. For example, pipes-anc-fiters is computationally expensive due to the need to cast all data into a common form, usually tex. Selecting architectural styes is largely dependent on an assessment of the desired attrbutes ofthe application. Most applications require a mix of these qualities and a combination of architectural styles. Choosing the right architectural styles can have a big impact. ‘So before examining a popular component interaction style—the layered style—let's examine the continuum of control styles we can empioy. Centralized Control Style ‘A procedural program makes a clear distinction between data and algorithms. Algorithms, whether they are called procedures or functions, use and operate on data. We can simulate a procedural style by creating a single smart object, led with algorithms. and surround it with numerous, data-structure-like objects that hold only information: pure information holders (see Fare \When the smart object needs to compute, it asks the information holders forthe information it needs, processes it, and elther puts it back or puts it in some other information holder. The procedures operate on data. The procedures tend to be redundant because other objects need to operate on the data, too. Many objects use the information holders, and many messages flow around the system. Figure 1-12. Centralized control concentrates logic into a single object. | kia But despite being procedural, a centralized style does have some advantages. The application logic is centered in only a few objects: the smart ones. Code may be more difficult to read because it is embedded in alot ofthe other logic, but you have only a few places to look. Now try to describe who uses which objects. Any one ofthe information holders has many clients. The processing oftheir Information is outside of them and is spread across many classes. What if you wanted to shift the responsibilty for knowing a piece of information from one to another? Many other objects would break because of the many dependencies. Dispersed Control: No Centers Inthe other extreme, we spread the logic across the entire few dependencies among them as possible. AsPigure 1-1 pulation of objects, keeping each object small and building in as shows, there are no centers tothe design, Figure 1-13. Dispersed control spreads the logic across many kinds of objects. ty logie begins here logie ends here When you want to find out how something works, you must trace the sequence of requests for services across many objects. [And they are not very reusable because no single object contributes much, Delegated Control {A delegated control style strikes a compromise or balance between these two extremes. Asigure 1-14 shows, each object, encapsulates most of what it needs to perform its responsibiites, but, on occasion, it needs help from other, capable objects. Every object has a suibstantil piece ofthe pie. It isn't hard to trace through the few objects involved to see how something ‘works. On the other hand, because each object is largely capable of fulfling its own responsibiltes, its more reusable. Reusing even the larger responsibilities means including only a few collaborators. System functions are organized into pools of responsibilty that can be used in relative isolation, Figure 1-14, Delegated control oreates pools of application logic. Examining Interactions: A Layered Architecture Example Let's take a closer look at the layered architectural style. We use ito illustrate how it guides our design of system responsibilty. We maximize simplicity and reusabilty by using a layered style. This architectural style groups responsibilities into layers. Each layer has a well-defined number of neighboring layers, typically one or two. Objects lving in each layer communicate mostly with other objects within the same layer. But there are times when the services that an object needs are not to be found within its layer, and twill reach out to an adjacent layer for the selected services. Here is atypical organization of responsibilties in the layers: One layer is devoted to interfacing withthe outside world. An adjacent layer coordinates responses to outside events. A third layer provides information and services that span the entire domain, and another layer provides technical services for connecting to external devices and programs. The layered style can contribute to simplicty, maintainability, and reusabilty Information systems, which often fit into this component interaction style, typically have a long life span, requiring that they be easy to maintain, scale, and port to new platforms. Figure 1-15. Interactive information systems often use layered architectures. browsers Presentation Web server NO [——)_ Application Control and Coordination app server 1 Domain Services and Information db server \ | - This architecture of a Web-based information system application separates areas of functionality into layers of functionality (layered style), defines groups of objects within each layer, and broadcasts events across network connections. Locating Objects in Layers We can combine the features just discussed with our notion of object stereotypes to demonstrate a very general layout of ‘objects in an object-oriented information system application. As we discussed earller, we use these stereotypes to characterize objects roles: information holder, structurer, service provider, coordinator, controller, and intertacer. How might we build a layered style application from them? Where would objects of each stereotype live? The architecture ofa layered system of abject looks something tke the diagram in Figure Figure 1-16. Each layer contains characteristic object roles. interfacers Presentation coordinators and ‘@pplication) events results controllers Application Services messages Tesults information holders, Domain serviee providers, Services et 1 coordinators, and domain controllers messages Tesults interfacers Technical Services Communication between objects tends to follow these rules: © Objects collaborate mostly within their layer. © When they do reside in different layers, client objects are usually above server objects. The messages (requests) flow mostly down. © Information (results) flows mostly up. ‘© Wen messages flow up, client objects are in lower layers, and they are loosely coupled to their server objects. This, usually uses an event mechanism, © only the topmost and bottommast layers are exposed to the “outside" world. They hold platform-specitic objects: ‘widgets in the top layer, and network, device, and extemal system interfacers in the bottom layer. ioe es an ive es in Design Description ‘As part of a design process, itis essential to communicate your ideas. During development there are many ways to think about your design, and many ways to informally describe it. Descriptions can range from design stories to roughly drawn sketches, to conceptual “art” that serves as a focal point for discussions, to handwritten CRC cards describing candidates. Design is an inherently messy process, and along the way many descriptions are discarded after serving thelr purpose. CRC cards were Invented by Ward Cunningham and Kent Beck in 1988 as a means of describing early design ideas about classes, their responsibilities, and collaborations. Instead of classes, we use them to desoribe candidate objects, which eventually are realized by one or more interfaces and classes, But there is a ime and a place for creating more precise descriptions. The Unified Modeling Language (UML) is a good way to describe your design using a standard graphical modeling language. It provides a vocabulary for describing classes, objects, roles, interfaces, collaborations, and other design elements. Itis a large language that Includes many more elements than we use in this book. But the UML is more than a graphical notation. Behind each symbol are well-defined semantics. This means that you can specify a UML model using one design tool, and another tool can interpret that model unambiguously. ‘Any design model or modeling language has limits to what It can express. No one view of a design tells all. That is Why in this book we use a rich toolkit that includes both low-tech and more precise ways to describe our designs. iawn Fcrrevous] next] ive es in Summary Object-oriented applications are composed of objects that come and go, assuming thelr roles and fulfiling thelr responsiblities. Typically, the initial set of objects that we find represents domain concepts that designers as well as users are comfortable talking about. Other objects are invented with specific responsibilities for controling and coordinating the user interface, managing the connections to the outside world, and governing the flow of control in the application. The software itself has properties that emerge. These systemic behaviors are accounted for by the software patterns, frameworks, and architectures. Thay contribute to system-level properties. Together, they form a collection of perspectives on the system under development. The "products" of development—the objects, responsibilities, collaborations, contracts, patterns, frameworks, and architectures—are the focus of a systematic development process, a method. With many levels and abstractions to ‘account for, we must be opportunistic in the way we approach the tasks. We shift perspective to reveal a new problem or another facet of an old one; we look for new solutions and explore half-formed ideas. Above all, we keep the focus on what Is important right now. This process Is the topic of the next chapter. hoveratoes fs rrevious] Next] ive es in Further Reading Timothy Buda's wonderful book, An Introduction to Object-Oriented Programming (Addison-Wesley, 2001), includes a thorough discussion of object-oriented concepts and programming principles. Although a college text, Its handy for professional developers, too. Programming languages come on the scene with great rapicity (they don't disappear so quickly, but new ones constantly appear). This book is in its third edition. One of the best things about itis the presentation of the same applications implemented in various object-oriented languages ranging from Smalltalk to Java, C#, C++, Object Pascal, and Oberon. In addition to inventing the Model-View-Controller concept, Trygve Reenskaug wrote a definitive book on thinking about objects in terms of roles. Working With Objects (Manning, 1995), written with Per Wold and Odd Arid Lehne, explores how patterns of interacting objects can be abstracted into patterns of interacting roles. We have been Inspired by Trygve's work over the years and believe that modeling roles Is essential to creating well-factored, flexible designs. The classic Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1995), by Erich Gamma, Richard Helm, Ralph Johnson, and John Viissides, launched the software pattern movement. This book contains twenty-some patterns organized into behavioral, creational, and structural pattems. If you want to learn more about the original design patterns that launched the pattern movement, pick up Gamma’s book. If you are a Java programmer, youll learn even more by reading Design Pattems Java™ Workbook (Addison-Wesley, 2002). In this, book, Steve Metsker clearly explains each and every pattern in the Design Patterns book from a Java programmer's perspective. The best source for leaming about the UML is The UML Language User Guide, (Addison-Wesley, 1999) written by Grady Booch, James Rumbaugh, and Ivar Jacobson. Others have tried to boil down this rich language to its fundamentals, but they lose something in the process. hoveratoes fs rrevious] Next] ive es in Chapter 2. Responsibility-Driven Design Betty Edwards, author of Drawing on the Artist Within, argues that many so-called creative talents can be taught. She poses this delightful thought experiment: What does it take to teach a child to read? What if we believed that only those fortunately endowed with inbom creative abilty could learn to read? What i teachers believed the best way to instruct was fo expose children to lots of ‘materials, then wait to see who possessed innate reading talent? Fear of stifling the creative reading process would ‘dampen any attempts fo guide new readers. Ifa child asked how to read something, a teacher might respond, "Try whatever you think works. Enjoy it, explore, reading is fun! Perhaps one or two in any class would possess that rare talent and spontaneously learn to read. But of course, this is an absurd belief! Reading can be taught. So too, can arawing. Her book challenges our assumptions that drawing requires rare and special “artistic” talent and that formal teaching of basic drawing skils stifles creativity. Basic drawing techniques, ike reading techniques, can be taught. No wonder many of us can't draw! Learning to draw is a matter of learing basic perceptual skills—the special ways of seeing required for accurate drawing. ‘This chapter presents the basic activities of Responsiblty-Driven Design and introduces examples of design work. Because object design is a highly creative process, designers should pick and choose ‘when to apply various tools that help them conceptualize the problem and invent solutions. Object design does not require rare and special “design” talent. Although design is a highly creative activity, the fundamentals can be easily learned. You can become adept at object design with enough practice and experience seeing the nature of the design problem and learning fundamental strategies for producing an acceptable solution. This chapter presents basic steps for developing object applications following an approach called Responsibiliy-Driven Design. We first describe the actions and activities for which our software should be ‘responsible,” We describe our software's responsibllties in terms that application users as well as developers Understand, Then we turn our attention to designing software objects that appropriately implement these responsibilities. hoveratoes fs rrevious] Next] ive es in A Process for Seeing, Describing, and Designing We wish to be very clear on one point: Although this book presents object-oriented development activities in a linear fashion, this Is rarely how design proceeds in practice. Software design processes are highly fluid and opportunistic, even though the final results are firmly fixed in code. Our presentation of this flurry of activity is limited by the constraints of the printed page. Possessing object design talent means that, through experience or ability, you “intuit” solutions that others need to learn how to see more clearly. You quickly come to see the essence of a problem and ways to design an acceptable solution. Responsibilly-Driven Design is an informal method. It offers many techniques for honing your thinking about how to divyy an application's responsibilities into objects and coordinating thelr performance. Our primary tool is the power of abstraction—forming objects that represent the essence of a working application. The name of our method emphasizes the thread that runs through every activity: our focus on software responsiblities. Responsibilities describe what our software must do to accomplish its purpose. Our work progresses from requirements gathering through roughly sketched ideas and then on to more detailed descriptions and software ‘models. Surprisingly, at the beginning of our process, we don't focus on objects. Instead, we focus on describing our system by capturing the viewpoints of many different stakeholders. We need to consider multiple perspectives in our solutions, Responsibility-Driven Design is a clarification process. We move from initial requirements to initial descriptions and models; from initial descriptions to more detalled descriptions and models of objects; from candidate object models to detalled models of ther responsiblities and pattems of collaboration We do not follow a straight design path as shown in igure 2-4) As shown irgiqure 2-4 our design journey is fled with curves, switchbacks, and side excursions, When tracking down design solutions, we often switch among Gferent design activities as we discover different aspects of the problem. We are opportunistic. We use a variety of tools that help us gain perspective, discover information, and craft solutions. Our work is fluid and malleable. Figure 2-1. Rigid, tightly planned development often leads to failure. —_~—_ no revisions revising the plan Figure 2-2. The Responsibllity-Driven Design path Is a flexible one. (Our ordering of activities and our focus will, of necessity, change (see| igure 2 Planning, adding new features, setting goals, characterizing the application via a prototype, creating an object model, identifying the hard problems—these are only some of our tasks. These tasks vary in their purpose, rigor, scope, emphasis, context, and applicable tools. Figure 2-3. We continually move our focus from one problem area to another, recasting relationships and finding new details. Our linear presentation of design activities is due to constraints imposed by printed, numbered pages. ‘As you read this book, ask yourself, Where can | bring this technique to bear on my problem? What thinking tool would be most effective to use right now? Be opportunistic! With all but the simplest software, we can't fathom what lies ahead. With so much complexity, we won't always make optimal decisions. Progress isn't always steady. Along the way we discover new information and constraints. We ‘must take time to breathe and smooth out these recurring wrinkles. Condon. This ews us oincorpraeour rong undttaning ito what we bul. Ae ehown ge 2-4 rcorennts getenganctepesteaton to ants cosa etna and oan eat ava eto ere our Figure 2-4. Discovery involves stating an Idea, reflecting It back to stakeholders for feedback, and then Incorporating changes and new insights in the revised model. Marvin Minsky says our intelligence comes from our abilty to negotiate solutions and resolve conflicts among competing goals. if part of your mind proposes solutions that another part finds unacceptable, ‘you can usually find another way. When one viewpoint falls to solve a problem, you can adopt other perspectives. {As designers, we naturally think that software objects are the center of the software universe. However object-oriented we may be, though, many other participants and perspectives go into the conception, design, and construction of a successful application. Just lke a theater production, software development involves much more than meets the eye during a performance. And although objects may take center stage for our work, itis important to recognize the Impact that aifferent perspectives and activities have on our design. Launching the Production: Project Definition and Planning We adopt a conventional approach to describing our object development process. First things frst. Its desirable to define project goals, construct a plan for achieving them, and receive buy-in before jumping into a big ettort. In Jong or complex productions, we need to survey and document the users’ requirements and demonstrate how our software system will serve those who have some "skin In the game"—the stakeholders who will be Impacted by our success or fallure. Even in quick projects, a litle planning goes a long way. This leads us to form a concise statement of the project, which includes a statement of purpose, an overview, and a definition of the scope and benefits. Project planning sets the stage for our design ideas. Its our plan for action. Keeping in mind that our main goal is to please our users and project sponsors, a project plan describes the following: © How the software will be developed © The values that are important to the project and the people involved © The people and their roles, the processes, and the expected outcomes © The expected deliverables "itis very much a matter of artist. The developer, like ancient bards whose epic poems were not writen down but recited from memory, must choose structures that will be readily remembered, that will help the audience not to lose the thread of the story.” —Michael Jackson ‘Athough not the focus of this book, project planning and definition are fundamental. Once we have a plan of action, we consider structures and processes. Our goal Is to understand what our software should do and how it will support its users, Setting the Stage: Early Description Initially, we narrow our scope and our descriptions. We begin with rough sketches, fudging in those areas that demand detall that we can't yet provide. We iterate through cycles of discovery, reflection, and description. Bit by bit We add details, pin down the ambiguous, and resolve conflcting requirements. Initially our descriptions aren't object-oriented; we add an object perspective atter we've described our system more generally. Object concepts wil form the kernel of a model of our system's inner workings. But our recipe for analysis looks something like [Table 2-1 ‘Table 2-1. Analysis includes system definition, system description, and object analysis activities. Responsibility-Driven Analysis Phase Activity Results System Develop high-level system [Diagram of system boundaries. Definition architecture. High-level diagrams of technical architecture ‘System concepts discussion and diagrams Identify initial system Glossary of terms concepts. Identify system ‘System perspective and functions responsibilities. Usage characteristics General constraints, assumptions, and dependencies Detailed Specify development Documentation of existing development Description environment. frameworks, external programs, APIs, and computer-based tools. Write text descriptions of the ways users expect to perform their tasks. A ist of the different types of users and external systems that interact with our system: actors Free-form text descriptions of the users’ tasks: use case narratives ‘Text descriptions of concrete usage examples: scenarios and conversations ‘Analyze special requirements for impact on design. ‘Strategies for increasing performance, maps to legacy data, plans for handling distributed data and computing, fault tolerance, and reliability Document system dynamics. ‘Activity diagrams showing constraints between use cases Show screens and interactions from users’ perspective. ‘Screen specifications Navigation model Object Analysis Identity domain-familiar objects with intuitive sets of responsibilities. CRC cards that describe object roles and responsibilities ‘A candidate object model Document additional ‘concepts and terms. Glossaries defining concepts, descriptions of behavior, and business rules Of course, results vary from project to project. Depending on application specitics, certain descriptions may not add value. if your application doesn't interact with users, screen specifications aren't appropriate. To design responsibly, we develop only those descriptions that give us a meaningful perspective. Certain requirements unfold during discussions with stakeholders. They correspond roughly to the users’ requirements but include a number of customer or administrator requirements: © Usage © Performance © Configuration © Authentication © Concurrency © scalability © security © Reliability We may also uncover these requirements during development and during initial use of early software versions by developers, testers, and beta users. Many requirements and concems averiap, and different stakeholders often articulate them in various ways. Security may be of utmost concern to users who “dont want credit card information plfered over the Web,” but this is afar less detailed requirement than those of the Web site administrator who speaks as a Web security expert In addition to the more obvious requirements that have an appreciable and direct impact on design, other requirements for flexibility, maintainability, extensibilty, or reusability can constrain acceptable design solutions, even though they aren't readily glimpsed by considering how our users interact with our software. In many cases, itis these ties" that, when ignored, cause a project to fal As designers, we must absorb requirements and present a design that conforms to their constraints. Of course, no matter how hard you try, you won't identiy all the requirements. Staging the Production: Design In design, we construct a model of how our system works. We break the object design process into two major phases: creating an initial design (exploratory work shown in[Table 2-) and then cratting more comprehensive solutions (refinement shown in [Table 2. Table 2-2. Exploratory design Is focused on producing an intial object model of a system. Exploratory Design Activity Results Associate domain objects with |A CRC model of objects, roles, responsibilities, and collaborators execution-oriented ones. Sequence or collaboration diagrams Descriptions of subsystem responsibilities and collaborations Assign responsibilities to Preliminary class definitions objects. Develop initial collaboration —_| Working prototypes model. ‘Table 2-3. Design refinement includes activities that mab design more predictable, consistent, flexible, and understandable. Design Refinement Activity Results Justify trade-offs. Documentation of design decisions Distribute application control. Easy-to-understand patterns of decision making and Control styles identified delegation in the object model Decide static and dynamic visibility relationships between objects. Refined class definitions and diagrams Revise model to make it more maintainable, flexible, and consistent. Creation of new object abstractions Revision of object roles, including stereotype blends Simplified, consistent interfaces and patterns of collaboration Specification of classes that realize roles Application of design patterns Document the design clearly. collaborations, interfaces UML diagrams describing packages, components, subsystem, classes, interaction sequences, Code Formalize the design. Contracts between system components and key classe: ‘The time spent exploring and refining a design, and the amount of design documentation you produce, can vary widely. Our advice: Work on those design activities and results that add value to your project. You don't need to do each and every activity or produce lots of design documents to be successful. Use these activities and results as general guidelines, and tune them to your specttic needs. ‘At some point after you've developed an initial exploratory design, you want to break away from designing and start coding, This could occur after a relatively short while, especialy it your design Is straightforward and you know what needs to be done. Perhaps you want to prove part of your design by implementing a prototype before investing energy designing other parts that rely on that proof of concept being solid. Or you may want to refine your design a bit before starting Implementation. Whether you take the time to polish your design a bit more before coding or you ‘adjust your design during implementation, your intial design Ideas will change. Most applications are too complex to “design right" the first ime, So creating a workable design means revisiting intial assumptions to make sure that your design lives up to stakeholders’ expectations. It may also mean spending extra time to design a flexible solution or to enable your design to respond to exceptional conditions, Design activities—from early explorations to detalled refinements—are the focus of this book. But before we dive into design, let's explore what we nead to "see clearly” in order to create an appropriate design. “Seeing” from Multiple Perspectives Each stakeholder in our design process has differing needs and values. Each person will view our work in progress and the emerging application from a unique perspective. Because many of the stakeholders do not speak our native object-oriented tongue, we object designers face two challenges: © Correctly interpreting stakeholders’ concems and requirements © Presenting our design work in terms understood by a wide audience "Facts are the alr of scientists. Without them you can never fly.” —Wvan Paviov Each participant in our software production has differing criteria for evaluating our software. Their primary concems and the aspects they value vary with thelr points of view. For example, users want to see that they can easily do thelr jobs using the application. They'll want application controls and processing to be consistent and “feel” natural. A business analyst will want to know that policies, rules, and processes are understood by the design team and clearly supported by our design. A tester wants to see that the actual application matches expected performance and usabllty objectives. Some stakeholders will care about our design's details, but many will not. All will want assurance that our design addresses their concerns and needs. Let's ‘now take a brief tour through the process and see how we develop a design that meets each stakeholder's specific concerns. ine iowa fs rrevious] Next] ive es in Writing the Script: Analysis Descriptions "There's no sense being precise about something when you don’t even know what you're talking about.” —John von Neumann Early in the process, our goal is to understand and reflect important requirements. We turn vague, formative ideas Into specifications of what we are to bulld. Errors in product specification are the most costly because they ripple through all of the downstream activities. So it's important to communicate our software's characteristics in simple, unambiguous language to those who will use it and to others who will Keep It running. To understand how our software fits into the immediate environment that it rns on and the extended environment of devices, databases, and external programs that it communicates with, we view our software from several perspectives as shown infrigure 2. Figure 2-5. Stakeholders’ descriptions of a system reflect their unique perspectives. escriptions are the externally visible medium of thought.” —Michael Jackson What language should we use to describe our system? No one language is common to users, customers, data analysts, developers, and managers that describes our software adequately. We collect a variety of descriptions Using appropriate language and notations. One of our goals is to make clear what is ambiguous, to collect and describe with one voice what our software should be responsible for. We gather various descriptions and reflect these different perspectives in our specifications. We strive to understand where our software “ends,” where its external environment "begins," and what functions it should perform. Once we draw these boundaries, we focus on our software's internal workings and the ways it responds to its environment. We develop and use a consistent, common vocabulary for describing the things our software affects, the processes it supports, and its responsibilities to its stakeholders, Use cases and a user orientation are important, but they don't tell the whole story. A model is a collection of related descriptions. There are various types of models—usage, data, object, state, and process, to name a few. Usage Descriptions Because many of an application’s obligations are to its users, we must clarify thelr understanding. From a user's vantage, there Is a boundary around our system that distinguishes the software from the external world. Users’ Understanding of our software Is based on how it supports thelr tasks. This task-oriented view can be described by a collection of descriptions, or use cases. Use cases are part of a UML model. We break up a large application's specification into use cases, which concisely describe discrete “chunks” of system functionality from this extemal perspective. Actors and Their View of Our System The Unified Modeling Language defines an actor as some one or something outside the system that interacts with it. These actors tend to be grouped into three different camps: © Users © Administrators © External programs and devices ‘Actors have two characteristics in common: © They are external to the application. © They take initiative, stimulate, and interact with our software. Objects best describe concepts, or things, their characteristic responsibilties, and interactions. By organizing our usage descriptions around these actors, we orient the software's responsibilities to each actor's, point of view. We eventually will use these descriptions and be guided by the “lities’ that we wish to preserve, But to develop a single object-oriented model, at this stage of development we need different, higher-level descriptions than an object model can provide—descriptions rich with detall, rich with intention, rich with implication and purpose. An object model prescribes only a solution to a problem. This solution leaves unspoken the needs, intentions, and day-to-day concerns of our system's stakeholders. ‘Any expected properties of our software must be apparent from some description. They won't emerge on their own, These rich and detailed descriptions depict usage, points of variability and configuration, and essential system architecture. We identify the groups of people and the external programs and devices that our software interacts with, and we describe how they interact. We note areas where flexibility is needed and variations our software should ‘accommodate. To the best of our abilly, we create descriptions that can be understood by those who need to know. If we build object models or code prototypes at this point, itis only to clarify our own understanding of this multitude of requirements. These prototypes can be disposable. Use Cases Use cases, introduced by Ivar Jacobson in 1992, are part of UML. Many people use them as a means to describe how a system is to be used. Others quite happily use hierarchical lists of features, simple user stories, or lengthy specifications documents, Use cases are especially valuable for describing an application from an external usage perspective, We use three forms of use case descriptions: simple text narratives, scenarios consisting of numbered steps, and conversations that emphasize the dialog between user and system. Each form of use case description has its particular emphasis, A.use case is "a behaviorally related sequence of transactions in a dialogue with the system.” —Ivar Jacobson Use cases can be written at differing levels of detall, depending on their intended audience. We can write high-level overviews and then add detail and describe the sequences of actions and interactions between the user and the program. The forms we choose depends on what we are trying to express. We may write one or more forms for each use case, depending on the needs of our audience. Typically, we start by writing narratives that present a high-level overview. Then, if appropriate, we can write one or more scenarios or conversations that elaborate this high-level description, A Word Processor Example Consider the use cases we exercised to write this chapter. Our word processor doesn't specifically support book wniting: itis a generic document preparation tool. So when we use our word processor, we map our activities onto those tasks supported by our word processor: entering text and revising It. Other tasks are not supported by our word processor: researching, brainstorming, and outlining. Tasks that do map to our application's chunks of functionality Include opening a document and creating and editing text. (Our goal Is to state the users’ tasks at the most meaningful level. Even the simplest high-level tasks become a series of decisions and actions on the part of the user. Writing is fairly free-form activity. We mix and match writing tasks in an unpredictable order. Because a word processor is meant to support a wide variety of writing styles, writing is best described with smaller use cases that can be exercised in any order. But meaningful tasks for writing a book are larger; they are composed of various subtasks. Formatting a page is a series of changes to the margins, indentations, headers and footers, and so on. Reorganizing 1 sequence of paragraphs Is a series of cut-and-paste operations. We name use cases and write them from the User's point of view—for example, "Eat Text," "Save a Document to a File,” or “Look up Online Help.” In these examples, the use case name takes the form "Perform an Action on Some Thing.” Here is a use case, written in narrative form, that describes saving a document. Documents can be saved in different fle formats. When you save a new document, the default fle {format is used unless another is specified. When a Save Document operation has completed saving an existing document, the fle represents accurately the document as displayed to the user upon saving, Alternatively, we could name and describe use cases from our word processor's perspective. "Open a Document might be recast as "Open a File and Read It into a Text Butter.” We don't recommend taking the system's point of view. Ife do, it gives us an eerie sense of our system peering out at the user, detaling what itis doing, ‘Although a system-level perspective is important, it isnt particularly relevant to our user. Keep the point of view of the user. (Our word processor's use cases describe rather small functional chunks, Our rule of thumb Is to write use cases that the user finds meaningful. The level of detail also varies. Users might want to see general statements, or excruciating detail, depending on how familiar they are with the task and how complex itis. Despite the variations in the level of abstraction and detail, use case narratives share one common feature: They describe general facilities in a paragraph or two of natural language. Scenarios Whereas use case narratives describe general capabilties, scenarios describe specific paths that a user will ake to perform a task. A single use case might be performed a number of different ways. This "Save Document to an HTML File" scenario explains how it varies from its “parent,” the "Save Document to a File" use case narrative: ‘Scenario: Save a Document to an HTML File 1. The user commands the software to save a fle. 2. The software presents a File Save dialog box, where the directory, filename, and document type can be viewed and modified, ‘3. Ifthe fle is being saved for the first time and it has not been given a filename by the user, a filename Is constructed based on the first line of text in the document and a default fle extension, 4, The user selects HTML document type from the File dialog's options, which replaces the default fle extension to ".ntm’ if needed, 5. The user adjusts the fllename and the directory location as desired. 6 The user commands the software to complete the Save Document command, 7. The software warns the user that formatting information may be lost I the fle is saved In HTM format. The user Is presented with the option of canceling or continuing the save operation. & The user chooses to save the document in HTML format, 9. The software saves the document and redisplays the newly reformatted contents. Certain {formatting information, such as bullets, indentations, and font choices, may have been altered {rom their original If we need to be more concrete to clarity how a task is to be performed, we write scenarios that describe the actions {and information relevant to specific situations. If more detall wil be helpful and we want to emphasize the interactions between user and system, we expand narratives into conversations, Conversations Conversations describe the interactions between the user and the software as a dlalog. Thelr purpose Is to clarity the responsibiities of each: The user, who initiates the dialog, and the software that monitors and responds to the user's actions. The more detailed conversation form allows us to clearly show the application's responses to the actions of the user. Each conversation has two distinct parts: a column of actions and inputs, and a parallel column of the related software responses. These responses are a first-order listing of the software responses and actions. We designers will use these statements as we design our system and assign responsibilities and actions to a population of software objects. We develop conversations and scenarios around a course of action, sometimes choosing a single path among many alternatives, Conversations record rounds of interaction between the user and the system. Each round palts a sequence of user actions with a sequence of software responsibilities. Rounds can be highly interactive or batch-oriented, depending on the application. For example, a highly interactive round in our word processor might capture and validate every key press, correcting often-mistyped words or signaling the user immediately about an invalid entry. In contrast, the batch-oriented style of Web-based input has you fll out many entry fields and then submit them all at once. Figure 2-q snows a conversation for “Save a Document to a File.” Figure 2-6. A conversation for saving a file lists the user actions and corresponding system responsibilities. User Actions ‘System Responsibilities Indicate save file, Display the name of the file to be saved and the current directory contents, including all subdirectories and all files having the same extension as the document to be saved, If saving document for the first time, construct a filename: with the extension matching the default document format. Optionally, change directory. Redlisplay contents of directory in dialog box. Optionally, rename file, Rename file and redisplay filename. Optionally, change document format. Record document format. Redisplay filename extension to match new format exten- sion conventions. Redisplay directory contents showing files whose exten- sions match the extension of the file to be saved. Indicate OK to save, If formatting information will be lost, present notice. Save UOCUTTIENIL UG Ime, Redlisplay contents if document format changed. This conversation shows details not found in either our use case narrative or our scenario. For example, it shows that ur system is working to keep the user informed about al les sharing the same extension as the to-be-saved document, Presumably this Is to help the user choose a unique filename, Adding Detail Designers, ike users, need to understand exactly how the software responds to its extemal environment, The descriptions in conversations and scenarios shape our design work. System responsibilities will be assigned to neighborhoods of objects working in concert to perform various system responsibilities. Conversations can be written sparsely or can pack more prose, mimicking talk between old friends, Conversation and scenario descriptions need even more detall before most designers can bulld a working system and most testers can write test cases. What are the conventions for handling errors? What defaults should be assumed? We can describe the following © Information supplied by the user and defaults f any, for missing information © Constraints that must be checked before crfical system actions are performed © Decision points where the user may change course © Details of key algorithms © Timing and content of any signiicant feedback © References to related specifications Descriptions are easier to understand if they are written at a consistent level of detail, We can include details outside the main body of a usage description, Rather than cram these details into the main body of a use case narrative, scenario, or conversation, we append or reference additional facts, constraints, information, and concerns. By annotating our descriptions with these details, we tle usage descriptions to design constraints and Ideas as well as other requirements specifications. Alternatives, Annotations, and Other Specifications Conversations and scenarios benefit from their simplicity and sparseness. However, we may want to capture nit-picky detalls about how our software carries out its responsibilities. Our software may vary its behavior in response to Information supplied by the user or other extenuating conditions. To keep things simple, we separate these detalls from the body of the conversation or scenario, Exceptional Actions To round out our description, we record deviations from the normal course of events in the "Exceptions" section: Exceptions [Attempt to save over an existing fle—inform the user and ask him or her to confirm a choice to replace the existing fle. Exceptions describe both an atypical condition and its resolution. A resolution can be a short sentence or two if the response Is simple. Or it can refer to another conversation or scenario that describes a more complex response. Exceptions describe how our software should react to anticipated conditions. Sometimes our software can react and recover. In this case the user continues the task but on an altered path. At other times, the only response may be to give up and stop forward progress on the users task. Business and Application Policies (ur system's responses often depend on explicit application and business rules. Our software's behavior must reflect policies such as “documents should be storable in different formats.” We make pertinent policies explicit by listing them separately: Policies Do not allow a user to save work to a file that another user has open. If the document is being saved for the first time, construct and suggest a filename based on contents of {the first line of text In a document. ‘An Idea Is an opportunity. Dortt ose it! (ur growing understanding of our application often gives us ideas about how the system might be designed. Our guiding principle is "Be opportunistic!" Rather than rigidly compartmentalize our activities and documents into "analysis" or "design," we gather and document information as we encounter it. Design Notes We note conditions and conventions that are of interest to the designer in a "Design Notes" section of a use case Design Notes Document format is indicated by the file's extension. Some formats share the same extension, but Information about the actual fle format is in the fle format descriptor: © .doc—standard format flles ofall versions © .rit-tich text format © .txt_plain text fles with or without line breaks © .ntmt_Hypertext Markup Language format Other Specifications Screen layouts, window specifications, documentation of existing regulations, constraints on system performance, and references to policy manuals provide even more context. We get even more insights into our software's behavior It we tie these to our usage descriptions. This type of information, although invaluable to designers, also gives other stakeholders an opportunity to see that their concems are being considered. Glossaries ‘As we write use cases and other descriptions, we try to use consistent terms. By compiling project-spectic definitions for frequently used words, phrases, and jargon into a glossary, we clarify and make our speoification more consistent: Document—A document contains text organized into paragraphs and other bitmap or graphic objects. tt Is created with the editing tool. Its contents can be modified using various ealting commands. Graphic Object—A graphic object can be visually displayed in a document. A graphic object can be created within the text editor or be imported from other applications and inserted into a document. Depending on its properties the user may be able to resize, scale, or adjust its physical properties, So far, our descriptions have had litle object orientation. Only after we gather descriptions from many perspectives can we make a stab at representing them In a unified form—a candidate object model. Conceptual Objects We want our design to readily translate to an object-oriented programming language. As a first step toward object design, we describe key concepts—a collection of candidate objects. We have crossed into object thinking. Our stakeholders understand these high-level concepts because they directly reflect the core concepts of the domain. But as we progress into even more detalled design activities, our objects will take on more computer-related characteristics and appear even more alien to others, Concentrating on the Core What you consider to be "core" will depend on the emphasis in your application and what your stake Is inits success. Cur goal Is to bulld well-designed software that works according to specifications and can accommodate modest changes. It needs a solid core. This “core can mean many things: © Key domain objects, concepts and processes © Objects implementing complex algorithms Technical infrastructure Objects managing application tasks Custom user interface objects Candidate objects may or may not survive intact to become part of the application object model. In our word processing application, those objects that represent parts of a document—objects such as Document, Page, Paragraph, and SpellCheoker—form a core. They appeared during initial concept formation. Document ‘A document contains text and other visual objects that represent the contents of other applications. Documents are organized as a sequence of document elements, including paragraphs, graphic objects, tables, and other document elements that the user formats and visually arranges on pages. Page ‘A page corresponds to what is visually present on a printed document page. Its composed of paragraphs and other document elements and, optionally, headers and footers consisting of text organized on the top and bottom of each age Paragraph A paragraph is a document element that consists of text or other graphic objects. A paragraph Is created when the user signifies a paragraph break by pressing Enter. Paragraphs have an associated paragraph style that Is used to display its contents and control spacing between lines of text in the paragraph. Spell Checker The spell checker verifies that words within the document or a highlighted portion of text are contained in the dictionary that comes with the word processing application or have been added by the user to the user dictionary. The spell checker informs the user about each misspelled word and presents the user with the opportunity to correct, Ignore, or add the word to the user dictionary. If these objects survive candidacy and join the ranks of other newly coined design objects, it means that they represent the application responsibilities in a fashion that supports our design goals. ieee in ve RuBoard Casting the Characters: Exploratory Design If analysis is about our application's behaviors, design is about the underlying objects that we derive from them. In design we are laying out and paving the streets that our application does business in. Like a good city planner, a good designer will consider how software will grow and change and what elements are most likely to be the focal points for change, hapter d, Finding Objects, presents strategies for identifying and characterizing design objects. There is a significant distance between conceptual objects and design objects. Both describe things. However, high-level descriptions ignore detalls that add heft and definition. This gap rightfully exists. Concepts and system responsibilities form a bridge to the work that remains to be done. In design we create a model of objects that work together to achieve our system's responsibilities. "While most of our mental models are intultive and largely subconscious, the essence of both science and business Is the creation of explicit models, called manifest models, which we can share and discuss." —Trygve Reenskaug Designers examine conceptual objects for merit. These conceptual objects are only candidates that may be discarded If they are rejected as unworthy of further consideration. Or they may be incorporated into the design and become Important elements of It. In our word processing application, Document proves a worthy design object. Its responsible for knowing and structuring its contents, a collection of Paragraphs organized on Pages. Similarly, a Paragraph is composed of Text, which is formed into Words. (On further examination, Paragraph proves a design gold mine! We can envision Paragraphs to be composed of Text objects and various kinds of nontextual objects representing graphics, drawings, figures, or even elements from external sources. Paragraphs are separated by ParagraphBreak objects. Text Is composed of characters that form Word objects that compose Sentence objects. We glean responsibilities from various descriptions and recast them into well-formed design objects. We add our own inventions to form a more complete, detailed model. AAs text is entered, a Parser object forms Text into Words. Words have a document location—a beginning and an ending position—and character contents. Words are composed of characters delimited elther by punctuation marks or other nontextual elements. As each Word is formed, itis passed to the SpeliChecker object, which checks for correctness. Often, conceptual objects and early candidates are rich design fodder—being transformed into several objects as design progresses. Less commonly, candidates pass directly from analysis to design, with responsibilities remaining relatively intact. Each object, fit continues in design, will need a clearly stated role and an appropriate set of responsibiities. Most Ikely, these responsibiliies aren't clearly articulated by any earlier description. Experienced designers, as soon as they hear "requirements," immediately start thinking about objects and their responsibiities. They often quickly conceive of additional responsiblties that round out candidates’ behaviors, ‘seemingly taking a leap from rough concept to well-formed candidate. And they invent new concepts and software ‘machinery on-the-fly to fil the gaps in their object model. Sometimes this leap can appear starting to someone relatively new to object thinking, For example, as we look further at the SpellChecker, we see that to actually perform its responsibilly for knowing correct spellings, we might design it to keep base parts of known words in a SpellingDictionary object and to know rules for pluralization and forming tenses. Its unlikely that the candidate object SpeliChecker will survive as a single object. More likely, as design progresses, it will become a community of collaborating objects, perhaps a subsystem. ‘Although CRC cards were originally intended to describe classes, their responsibiities, and collaborators, we recommend you look for candidates frst. Decide on how they are realized as classes later—once you have an idea they'l stick around, CRC Cards We record preliminary ideas about candidates, whether they are candidate objects or candidate roles, on CRC cards. CRC stands for Candidates, Responsibilities, Collaborators. These index cards are handy, low-tech tools for exploring early design ideas. On the unlined side of the CRC card, we write an informal description of each candidate's purpose and role stereotypes (see Figure 2. Figure 2-7. The unlined side of a CRC card characterizes the candidate. candidate a Document Furpose: A Document acts a¢ a container for graphics and text. its role in the application Fatterns: Composite-component «— Steve shunee: Shaw hive of | & characterizations its role in the Composite pattern Gelting more specifi, we fp over the CRC card to record is responsibil for knowing and doing (see figure 2 Responsibilties spell ut the information that an object must know and the ations that it must perform, Collaborators are those objects whose responsibltes our objec calls upon inthe couse of fling its own Figure 2-8. The lined side of a CRC card describes responsibilities and collaborators. candidate —. i collaborators Document Knows contents TextFlow | | Knows storage location o Inserts and vemoves text, graphics, ard other elements : | | responsibilities hapter 4, Responsibilities, discusses how to identity and assign responsiblties to appropriate candidates. Cards work well because they are compact, low-tech, and easy. You move them around and modify or discard them. Because you don't invest a lot of time in them, you can toss a card aside with few regrets it you change your mind. They are places to record your initial ideas and not permanent design artifacts. Because cards are small and not in a computer, you can easily arrange them on a table and view many (perhaps all) of them at the same time, You can pick them up, reorganize them, and lay them out in a new arrangement to amplify a fresh insight. You can leave blank spots to represent gaps in your design. If you insist on using a computer, don't be lulled into thinking your candidates are well formed because typed responsibilities look neater. At this stage, exploring options should be fun, easy, and low-cost. Itis pointless to insist on cards, however. if you work best with sheets of blank paper or yellow legal pads, use them. Use a white board to see the big picture. Describe candidates on Post-it notes, which you can rearrange in an instant (see Figure 2 Figure 2-9. Post-it notes are easy, compared to CRC “cards.” Document Forpose: A document represents a container That holds text and/ or graphics that the veer can enter and visually arrange on pages Stereoty pes: Structurer The obvious conceptual objects that we Identify first on CRC cards are only one piece of the puzzle. It is the Unintuttive inventions that challenge our creativity. They are the hallmark of a flexible and well-tactored program, They are what we look for during design. Good designers short-circuit the difficult work of invention by adapting proven solutions. They study other designs and reuse their own and others’ experience, Inventions: Using Patterns You gain a measurable advantage by knowing where to look for adaptable solutions. One powerful way to increase design skills to seek out good patterns and learn where and when to apply them, Using solutions that have proven themselves useful in a variety of contexts can help us fill in the gaps in our thinking. These litle “whacks on the side of the head’ Jar us into thinking about solving new problems in proven ways. There Is a key aspect of our word processor that we should study: how it responds to the myriad user actions. The Word processor is, quite Iteraly, “responsible” for interpreting requests for editing, inserting, finding, formatting, saving, opening, cutting, copying, pasting, printing, viewing, checking spelling and grammar, and so on. © How should we perform these actions? © Each item selected from a menu represents a request for our word processor to take action. How can they be undone? © Many actions affect a specific portion of the document. How do we keep track of which section to operate on? For example, a cut action removes highlighted text into a cut butter, whereas a bold action sets bold emphasis on elther the currently highlighted text or, ino text is highlighted, the word containing the current cursor position. Saving a document means writing the document to a specific fle. ‘The problem of how to exercise control is central to most applications. The Command pattem, described in Design Patterns: Elements of Reusable Object-Oriented Software, turns an action Into an object. Each specific action can be represented by a distinct object that plays the role of a Command. Using inheritance, these objects can be implemented by classes in an inheritance hierarchy. As described, the ‘Command pattern is very general and must be tallored to fit our word processor application. To use it, we must. structure all of our thinking about responsibilities for performing and undoing our many word processing actions into various command objects. What exactly does this mean? How can we fit all actions into the command pattern form? ‘An experienced designer might recognize the need for the Command pattern almost immediately. A ‘new designer might prototype different ways to solve the problem of providing aifferent types of -ommand” behavior, before discovering that the Command patter offers a consistent solution. When you discover that a design patterns is a good fio your problem, you are leveraging others’ design experiences, vie at delight an bet aig a Command has a esponsbly br patming spect acon ices se ig. uncoated, cr co ease nave any elect de ot Gonmara cece, an cases each ‘Command that declares that all Commands can "execute an action” and can "undo" Its effects. Additionally, any ‘Command knows the target of the action. n the word processor, a Command's target is the portion of the document that it affects Figure 2-10. The Command object responsibilities are stated very ger general responsibilities for knowing nN Command Knows target of action request Knows whether action 16 reversible Executes an action Undoes a reversible action = general responsibilities for doing Each different kind of command object will support all the responsibilities of the Command role—but they will do so In specitic ways. For example, executing a SaveCommand means saving the document's contents to a file. Save is not reversible and will never be asked to undo. A SaveCommand object knows that the target of the action Is the entire document, and, because it collaborates with the document to full this responsibilty, we show Document as a collaborator (see Figure 2. Figure 2-11. The SaveCommand object responsibilities are more specific statements. exactly what it knows ee | SaveCommand ) \_ ) Document: Kwows target.entive document Kyows save i not reversible Saves document | Not available to vido | * exactly what it does. We create a CRC card that shows the responsibilities of each different kind of command object. A PasteCommand fulflls the role of a Command by placing text into a document at the current cursor location, knowing paste Is reversible, and cutting it out if asked to undo (see Figure 2 Figure 2-12. The PasteCommand object responsibilities fulfill the Command responsibilities, too. this one knows differently ) FasteCommand Knows target location in document) Document Knows paste is reversible CutBuffer Uneloes by moving. pasted portion back to buffer Factes evt buffer into document this one does differently’ ‘As we specify how each command's responsibilities are delegated, we add responsibilities to the Document CRC card (see Figure 2-13] Figure 2-13. Working out more detalls, we add responsibilities and collaborations. Document Knows contents Text Flow Knows storage location hoceke we kek I INGEN TS anes YEMOveS TEXT, graphics, and other elements Saves contents anew responsibility ‘Although we applied the Command pattern in this case to llustrate the power of applying a proven solution to our particular design problem, sometimes design is much harder. We must think and rethink our design ideas, bouncing from one card to another, clarifying object roles, allocating responsibilities, and developing collaborations. ‘Sometimes, as we press forward, solutions aren't readily apparent. Worse yet, when we know more about our design, our earlier solutions may—on further reflection—seem brittle or inappropriate. In early design, ideas are fluid. It is easy and desirable to make radical changes. We can relocate responsibilities, rearrange collaborations, adjust object roles, and introduce new players without much effort. We gain certainty and conviction by considering options. Pursuing a Solution Cur primary too! for design is abstraction. It allows us to effectively use encapsulation, inheritance, collaboration, and other object-oriented techniques. How should you choose among acceptable design alternatives? Consider this simple strategy: It you don't have any predefined notions, create a solution that seems to work. 2. Explore the limits and strengths of that solution. To hedge your bets, measure at least one alternative against the frst solution 3. Favor solution that contributes to design consistency. 4, Don't overwork a solution 5. Fityour solution into known design pattems. 6. Borrow and adapt proven design ideas and archetypes. 7. Be wiling to revise eater decisions when things get ugly 8. If you don't have the time, don't search for insights. Abstraction or cleverness can't be forced. Bouncing Between Ideas and Details (One way to make sure we don't get off track is to constantly test our design with detall, A solution that sounds great in principle can crumble under the weight of detall. We use nitty-gritty descriptions in conversations and scenarios. We challenge our design with extra conditions that occur to us as we dig into details. After modeling at a high level, we spend time working with details. There is a shift in our design work between modeling and abstraction, elaboration and detailing, We can also use "detal” to help spot abstractions. By looking at all the various commands that one needs in a word processor, you may gain insight into what they have in common and spot the need {for some way to unity them. We can turn to our descriptions for these details. Revisiting the "Save a Document to a File" conversation, we find ‘many responsibilties that must be assigned to objects (see Figure 2-14). System responsibilities stated in conversations are a great source for finding object responsibilities. When we concentrated on the core design, we purposely ignored these detalls. To complete our design, we need to sort through system responsibilities and many other details, inventing many design objects and collaborations. To give you a hint at how we assign initia responsibiities, we've noted in parentheses how we made initial assignments of system responsibilities to one or more potential candidates. Figure 2-14. System responsibilities are assigned to objects. User Actions System Responsibilities Indicate save file. Present a dialog box that displays the name of the file to be saved and the current directory contents, including all sub- directories and all files having the same extension as docu- ment to be saved. (Assign high-level coordination to SaveDialogController, which is directed by SaveCommand) If saving document for first time, construct a filename with the extension matching the default document format, (Assign to a new service provider?) Optionally, change directory, Redisplay contents of directory in dialog box (SaveDialog- Controller collaborating with Directory). Optionally, rename file. Rename and redisplay filename (SaveDialogController collaborating with Document, which collaborates with File). Optionally, change document format. Record document format (Document) Redisplay filename extension to match new format exten- sion conventions. (Assign to SaveDialogController, which will collaborate with some object that knows the mapping between extensions and document type—possibly a FileManager?) Redisplay directory contents, showing files matching to- be-saved file's extension (assign to SaveDialogController). Indicate OK to save. if formatting information will be lost, present notice (Save- DialogControlle). Save document to file (SaveCommand collaborating with Document). Redisplay contents if document format changed (Save- Command collaborating with WordProcessingControlles) (Once we've made an initial stab at gleaning responsibllties from conversations and assigning them to objects, we ‘need to construct a more complete solution and weigh its merit against alternatives. We'll answer in detall how any objects supports responsibilities stated at a high level: © What does it do? How does it contribute to a high-level statement of responsibilty? How does it collaborate with others that also play a part in supporting this high-level responsibility? © What does it need to remember? What messages does it send to others? In what sequence? What are their arguments? What Is retumed from each request? Welll design object interactions and further divide their responsibilities. We will create additional design documentation and drawings. We will draw and preserve a few diagrams that depict typical collaborations and show the classes that implement our design. Ultimately, our design will be expressed in code. hapter 7, Describing Collaborations, presents options and advice for documenting key collaborations using both informal techniques and UML diagrams. ine iowa fs rrevious] vex] ive es in Tuning the Production: Design Refinement As designers, we play a significant par in realizing a smoothly run production. Exploratory design is only the star. ‘After we mull over inal ideas and explore enough to know where we are headed, we systematically give our design ‘a more thorough consideration. We ask many questions and then make many decisions and adjustments that will have a broad impact: © What styles of collaborations should predominate? © How can our design accommodate users’ varying needs? © Where should we build in capability for future extension and modification? © can we make our design more consistent, predictable, and easy to comprehend? © How robust does our software need to be? Alot of work remains! Strategies for working on and evaluating these detalls form the heart of this book. Let's briefly touch on some of these activites. Determining Collaboration and Control Styles hapter J, Collaborations, discusses how to design objects to work togetheohapier q Control Style, presents options for developing consistent pattems of collaboration and application "control centers. (One important decision Is how best to allocate control and decision-making responsibilities among collaborators. Control questions crop up in several areas: © How do we control and coordinate use cases and user-intated actions? © What are the architectural constraints on collaboration and control styles? © Where do we place responsibilities for making decisions? How should exception detection and recovery be managed? ‘Answers to these questions have a huge influence on how responsibilities are distributed across the rest of the ‘model. Our goal is to design consistent, predictable patterns of interactions. Command objects are the locus of control for user actions. With this design choice, a clear pattern for controlling user-dlrected actions emerges. The ‘Command pattern abstracts what it means to respond to a user action and gives us a recipe for adding new kinds of user-directed action controllers. It should be fairly straightforward to fit new user actions into our existing design by creating new kinds of Command objects. But there are other places where we will need to ponder what control style is appropriate. Consider spell checking, We must make decisions about how to represent spelling rules and how to detect and report spelling errors. The control of how documents are saved and recovered needs careful design. Developing a style of collaboration and control involves deciding how to distribute control among collaborators as well as deciding on what patterns of collaboration should be repeated. Our options for distributing these command and control responsibilities range from ‘more centralized to more distributed solutions, Designing to Support User Variations Atypical word processor supports many different user styles, preferences, and modes of interaction. Numerous features are under the user's direct control, ranging from how a document is displayed to details of how often the document is saved to what spellings are considered “legal In an application of this sort, how best to support each of the myriad variations will be a predominant design consideration. Our word processor needs to make many tactical decisions as it executes based on current seltings and preferences. hapter g, Flexibility, discusses how to design an application so that it ~lexes” and supports planned variations. Patterns and implementing designated "hooks" are key to adding flexibility Designing for Flexibility and Extension Fiexibilty isnt intrinsic to any design. To gain flexibility, we add appropriate bends and folds to our objects’ behaviors that allow for extension and reconfiguration. We start by characterizing the ways our software needs to flex. We brietly describe how a behavior varies, note when this variation should occur, and present enough examples to llustrate the essence of the variation. We write brief descriptions of variations on hot spot cards (see[Eiqure 2-15). As with CRC cards, the real estate on a hot spot card is limited. So we record only the essentials, Figure 2-15. The hot spot card describes and demonstrates a variation. Hot Spot Name: General description of the semantics of come variable. behavior Descriptions of hot spot behavior for at least two specific sitvations (Once we've characterized how and when our software should flex, we then can employ one or a combination of design techniques: abstraction, classification, composition, inheritance, and parameterization. (Our word processor must accommodate many user-specified variations. In addition, we expect to support new features and abilties—new graphics, new document formats, new and more sophisticated grammar checking, and. document templates. Our software must be flexible from the star. There are many techniques we designers use to accommodate planned variations. They range from simple checks on values to much more elaborate schemes. We can configure an object's behavior by passing method parameters. We can design an object to remember information that it can query to decide how it should perform an operation. We can configure an object to vary how it supports a responsibilty by having it delegate to a configurable set of service providers. For example, we can add support for a new document format, plug in the appropriate service provider to generate that format when the document is saved, and plug in another to read and interpret it when it is opened. There isn’t one best strategy to accommodate variation. We favor simple solutions that build on each other. We can always add complexity i we need a more accommodating solution. Redesign is big part of sustaining a long-lived production, Designing for Reliability ‘Much complexity in a software design is the result of situations that, although expected, aren't "normal." In the word. processing application, there are many opportunities for our user to supply us with incomplete information or to ask the software to do something that isn't exactly n the script. hapter | Reliable Colaborations, explores strategies for increasing an application's ability to react to and handle exceptional conditions. What happens when we try to save our document over an existing file? How should our software respond to requests to save a document in an exchange format that would lose formatting information? These are the easy ones to handle, and there are many more. What happens when our application doesn't have enough room to execute, or when It discovers a place in a document with uninterpretable data? These are a bit harder to accommodate. Our users expect our application to gracefully recover from those situations if it can, and to politely Inform them when it cannot. We need to design our objects to responsibly and consistently (and to the best of thelr abilities) react to these exceptions. Designing consistent exception-handling policies and locating them systematically in controllers, service providers, and other "responsible" objects makes the way our software reacts to exceptions more predictable. Making Our Design Predictable, Consistent, and Comprehensible The essence of a good design Is predictability and consistency. We handle our application's complexity by designing consistent solutions. We don't want our design to be starting. So, if we solve one design problem in a particular way, we look for places where the solution might be repeated. Given a complex application, there are an infinite number of designs that will solve it. Many factors contribute to a consistent, comprehensible design: © objects are grouped in neighborhoods. © There are few lines of communication between neighborhoods. © Noone object knows, does, or controls too much © Objects perform according to their designated role. © When one solution is designed, variants will be applied to other parts that are similar. © There are few patterns of collaboration that repeat throughout the design. We need to balance a number of forces when we work on developing a consistent, predictable design. There Is no reojpe. We weigh various design trade-offs and make concerted efforts to be consistent across our design ‘Sometimes a system architecture or application framework will impose a collaboration and control style on the design. Sometimes using a standard design pattern will help. At other times, we need to discover and adopt a consistent style as we move along, ine iowa fs rrevious] Next] ive es in Summary Just as a good cook alters a recipe's ingredients or the order of the instructions, a good designer treats a design method as a guide. Once you are comfortable with the basies, you should feel more comfortable adjusting the dials con the design process—producing what's needed when itis needed, cutting to the essence, and working on the hard problems. With experience you'll learn how to see and describe the problem and then readily design and bulld objects that model a solution, hapter 1d) On Design, explores three different design problems—core, revealing, and the rest—and discusses how best to approach them. If you know the nature of the design problem you are working fn, you can be prepared and adjust how you work. Responsibiliy-Driven Design is suitable for a wide variety of projects because the emphasis is on thinking and creativity. First, guided by the various stakeholders’ requirements, we determine how our application should behave. ‘Second, we explore what we know so that we will find out what we don't know. Knowing that designs emerge over time, we create initial design ideas using low-tech tools such as CRC cards that easily let us change our minds or consider different options, Finally, we turn the lights on the shadowy areas. We pin down what we have fudged. We look for solutions that have proven themselves elsewhere. Our success Is directly related to how much opportunity we have seized, how much time for discovery, reflection, and revision we have created, and how satisfied the project's stakeholders are. ive es an ive es in Further Reading Responsibilty-Driven Design was first described in a paper by Rebecca Wirfs-Brock and Brian Wilkerson, "Object-Oriented Design: A Responsibilty-Driven Approach,” presented at the OOPSLA '89 Conference. A year later, the book Designing Object-Oriented Software, (Prentice Hall, 1990) authored by Rebecca Wirfs-Brock, Brian Wilkerson, and Lauren Wiener, expanded upon ideas presented in the paper. Since then, the notion of object responsibiilies has become commonplace. Responsibilly-driven thinking fits into and complements most development processes and practices. For example, Rational has defined a process called the Rational Unitied Process, or RUP. It defines four phases of an iterativeincremental development process: inception, elaboration, construction, and transition. Responsibilty-Driven Design principles can be applied during inception and elaboration (what others may consider object design) and certainly should not be forgotten during construction. A good book on RUP Is The Rational Unified Process: An Introduction (Addison-Wesley, 2000) by Philippe Kruchten. Agile, adaptable development processes are a popular topio—and Responsibilly-Driven Design techniques ft here, too, If you are interested in reading about what makes a development process agile, pick up Jim Highsmith’s Agile Software Development Ecosystems (Addison-Wesley, 2002). There are several diferent processes whose authors {and proponents classify as being agile. The most written about is Extreme Programming, or XP, which includes just 12 development practices. Extreme Programming Applied: Playing to Win (Addison-Wesley, 2001), by Ken Auer and Roy Miler, summarizes Extreme Programming practice and then presents many nuggets of wisdom. It you are interested in the art and practice of writing good use cases, there are several books we recommend, Ivar Jacobson introduced use cases in his classic book, Object-Oriented Software Engineering: A Use Case Driven Approach (Addison-Wesley, 1994). Several authors have put thelr unique spin on use cases and have made several refinements to Ivar Jacobson's original ideas. The best of the bunch are Alistair Cockbumn's Wrling Effective Use Cases (Addison-Wesley, 2002) and Larry Constantine and Lucy Lockwood'Software for Use: A Practical Guide to the ‘Models and Methods of Usage-Centered Design (Addison-Wesley, 1999). Alistair Cockbur's book, an easy read, is packed full of examples and advice on how to fix common use case problems. Larry Constantine and Lucy Lockwood's book isnt strictly just about use cases, although it goes to some length in describing different styles of usage descriptions and thelr strengths and weaknesses. Their book presents a systematic and thorough approach to developing usable systems and user interfaces, through the development of role models, task models, and content ‘models. Anyone who wants to focus on system usability will fnd much of value in this book. It is packed with wisdom, great stories, and many practical tools and techniques. Lary Constantine and Lucy Lockwood introduce the notion of an essential use case. Its a structured narrative expressed in the language of the application domain and its users. It describes a user task in a simplified, technology-free and Implementation-independent fashion. Because it specifically omits details I leaves more options for the user interface design. hoveratoes fs rrevious] vex] ive es in Chapter 3. Finding Objects Joseph Albers could make colors dance or retreat: "I see color as motion ... To put two colors together side by side really excites me. They breathe together. It's Ike a pulse beat... | Ike to take a very Weak color and make it rich and beautiful by working on its neighbors. | can kill he most brillant red by putting it with violet. | can make the dullest grey in the world dance by setting It against black." Albers, one of the great graphics artists of the twentieth century, was a master at making visual Imagery emerge from form and color. By careful juxtaposition of colors, textures, and shapes, the artist can make Images leap off the page. Albers calls this the "1 + 1 = 3" effect. A good design is more than the sum of its parts. A bad design muddles what should be emphasized. Charljunk—misuse of bold lines and color or addition of pretty stuff that adds no value—shits attention away trom vital information. in graphic design, composition, form, and focus are everything] An object design poses similar challenges. Itis strengthened by vivid abstractions and well-formed objects that fit into an overall structure. It can be weakened by glaring inconsistencies or ‘muddled concepts. The abstractions you choose greatly affect your overall design. At the beginning, you have more options. As you look for candidate objects, you create and invent. Each invention colors and constrains your following choices. Initially, i's good to seek important, vivid abstractions—those that represent domain concepts, algorithms, and software ‘mechanisms. Highlight what's important. I you invent too many abstractions, your design can get overly complex. Not enough abstraction, and you'll end up with a sea of flat, lifeless objects. Your goal is to Invent and arrange objects in a pleasing fashion. Your application will be divided into neighborhoods Where clusters of objects work toward a common goal. Your design will be shaped by the number and quality of abstractions and by how well they complement one another. Composition, form, and focus are everything. ‘A graphics designer enhances important information by layering and separating it, giving focus to the data rather than its container, and by using multiple signals to remove ambiguity. Vow rsa [revo |e] ive es in A Discovery Strategy So let's get to it! Conceiving objects is a highly creative activity, but it isn't very mysterious. Finding good candidate objects isn'ta topic that has recelved a lot of attention. Early object design books, Including Designing Object-Oriented Software, speak of finding objects by identifying things (noun phrases) written about in a design specification. In hindsight, this approach seems naive. Today, we don't advocate underlining nouns and simplisticaly ‘modeling things in the real world. It's much more complicated than that. Finding good objects means identifying abstractions that are part of your application's domain and its execution machinery. Their correspondence to real-world things may be tenuous, at best. Even when modeling domain concepts, you need to look carefully at how those objects ft into your overall application design. Well-formed abstractions and careful attention to how they complement one another have a direct effect on the quality of an object design. This chapter discusses how to find and arrange software objects in an inital object design. The ultimate goal is to develop a practical solution that solves the problem. However, we find that such designs typically are also esthetically pleasing ones. Although software objects aren‘t just waiting for you to find them, you can identify them somewhat systematically Although many different factors may be driving your design, there are standard places to search for objects, and you'll find many sources of inspiration. You can use your knowledge of your application domain, your notions about needed application machinery, lessons learned from others, and your past design experience, (Our recipe for finding and assessing candidates has a number of steps: © Write a brief design story. Init, describe what is important about your application, © Using this story, identity several major themes that define some central concerns of your application, © Search for candidate objects that surround and support each theme. Draw on existing resources for inspiration: descriptions of your system's behavior, architecture, performance, and structure. © Check that these candidates represent key concepts or things that represent your software's view of the World outside its borders. © Look for candidates that represent additional mechanisms and machinery. © Name, describe, and characterize each candidate. © Organize your candidates. Look for natural ways to divide your application into nelghborhoods—clusters of objects that are working on a common problem. © Check for thelr appropriateness. Test whether they represent reasonable abstractions, © Defend each candidate's reasons for inclusion. © When discovery slows, move on to modeling responsibilities and collaborations. This chapter will cover each of these steps in greater deta, But be aware that you don't always complete each step before moving on to the next. The process of discovery and invention is more fluid than that. Sometimes you perform several steps at the same time. You may discard some candidates and start over i they don't seem to fit in to your emerging design. But if you start by characterizing what is vital to your application's success in a design story, you can then proceed with an organized search for objects that support this core. At the end of your intial exploration, you will have several handfuls of carefully chosen, justified candidates. Many ‘more will be invented as you proceed. These initial candidates are intentionally chosen to support some key aspect of your system. They will seed the rest of your design. Finding and inventing this first batch of candidates takes careful thought. Initially, we recommend you look for candidate roles and objects. Once you have an idea that they'll stick around, make decisions on how they are realized as interfaces and classes. ive awa fs rrevious] Next] ive es in Looking for Objects and Roles, and Then Classes The first candidates to look for should represent important things: concepts, machinery, and mechanisms. Typically these kinds of candidates are smart—they do things. They may know things, too, but they perform actions based on what they know. intially, think very concretely. Abstraction will come later, after you see more concrete objects and understand their relationships to others. To start, identity distinct objects that have clear roles. Next, decide what candidates should know and do (their responsibilties) and whom they work with (thelr collaborators). Then, thinking more abstractly, you can turn to identifying aspects that are common to a number of candidates. Shift your focus from thinking about objects and thelr individual roles to deciding what objects have in common. Only after youve made decisions about common responsibilities that are shared by different candidates can you define ‘common roles. We deem our objects and roles candidates untl thelr value has been proven. Only then do we decide how they will be realized as classes and interfaces, When you transition from candidates to classes and interfaces, you have options. You can employ inheritance, abstraction, interfaces, and collaborations to construct a well-factored, flexible design. You will specify abstract and concrete classes as well as interfaces. An abstract class provides a partial Implementation of responsibilities. It leaves subclasses with the obligation to implement specitic responsibilities. A concrete class provides a complete Implementation. An interface specifies responsibiiies more precisely as method signatures but leaves thelr implementation open. Any class can implement an interface, regardless of its position in any class inheritance hierarchy, Abstract and concrete classes are the bullding blocks we use to specify an implementation. Declaring Interfaces Is one means to make It more flexible and extensible. A reusable role Is best specified as. an interface that can be implemented by one or more classes. hoveratoes fs rrevious] Next] ive es in Why Tell a Design Story? We suggest you create a framework for searching for potential candidates by writing a story about your application, After you've done this, the candidates you identity should fall into place and support various aspects of your story. When you state things in your own words, you get to decide what's important, Everybody may have been talking about what your design should do and what will make it great, but you should make a few bold statements of your ‘own. In this design story, identify the things about your application that you know with certainty, as well as things you don't yet know. Rather than being driven by one particular view of your software—whether it be use cases, requirements, architecture, users, or sponsors—pull together all these factors and craft your own description. Write a rough story—two paragraphs or less is ideal. Don't take a lot of time revising and polishing it. Be quick and to the point. What is notable about your application? What is it supposed to do? How will it support its users? Is it connected to a real-world example that you can study? Have you done something similar? What will make your design a success? What are the most challenging things to work out? What seems clear? What seems ill defined? You need not answer all these questions. Simply write about the critical aspects of your application. If it helps you ‘make your point, draw a rough sketch or two. Focus on the main ideas, I'you are a member of a larger design team, write your own story first and then share it with your team, See how your concerns differ from others’. The team can draft a single, unified story, but this Isn't necessary. More importantly, identity the important themes in these design stories. Then look for candidates that support these themes. Here are two design stories that were writen quickly. The first one rambles. It tells of an online banking application: ‘This application provides Internet access to banking services. It should be easlly configured to work for different banks. It should support fast access to banking services for potentially thousands of users at a time. There is a limited number of software resources, such as database connections and connections {to backend banking software, that are available. A critical element in the design is the declaration of a ‘common way to callin to different backend banking systems and a rellable means of sharing scarce resources. We will define a common set of banking transactions and a framework that will call into banking-specitic code that "plugs into” the standard layer implementing the detalls. The rest of our software will only interface with the bank-Independent service layer. We've developed a prototype implementation of this layer and have configured It to work for two different banks. Although itis still a prototype, we understand how to write a common banking service layer. Lately, our bank has been busy acquiring other banks and integrating thelr software. We've been {through three system conversions in the past year. We want to focus on making this service layer easy {to Implement and test. At the heart of our system is the abil to rapidly configure our application to wor {or different backends and to put a different pretty face on each. This includes customizing screen layouts, messages, and banner text. The online banking functions are fairly simple: Customers register {to use the online banking services and then log in and access their accounts to make payments, view account balances and transaction histories, and transfer funds. This Is straightforward, easy to Implement. There is added complexity. Customers record information and notes about each online transaction. This extra information will be maintained by our application in its own database because preexisting bank software has no way to store it. We want a customer to view human-readable Information, not ancient bank software detailed transaction records. When a customer asks to view an accounts transaction history we'll have to merge this data with records supplied from the backend software, Multiple users can access a customer's accounts, each with potentially different access rights. Certain users might have no access to sensitive accounts. A company executive might view only ‘account balances, whereas a clerk in the accounts payable department could make payments and a comptroller might be able to transfer funds between accounts. This next, more focused, story is about a Web-based game. It describes new design challenges as well as, to us, familiar territory: ‘This game playing application supports an Internet variant of chess called Kriegspiel. Krlegspiel Is a chess version of the popular game Battleship. The novelty is that players make moves not knowing |where thelr opponent's pieces are located. Our immediate concern Is how to distribute responsibilities ‘among major software components. In this distributed application, we need to consider time lags and limited communication bandwidth between architectural components. We also need to consider the unpredictability of Internet communications. Each player interacts with our application via a Web browser. Hundreds of games can be played simultaneously. A user logs in and requests to play a game with another. If no one is available, the user can elect to play a game with the computer. We will need to design our software to play a credible game of Kriegspiel as well as referee games played by humans. Al |game can be suspended and resumed, From our computer gaming experience, we know that computerized games generally have player input directives, rules about legal actions, some representation of the current state of the game, and animations. In this application, our animations are simple and not a major concern. Its worth stating how Kriegspiel Is played, although our application [won't mimic the real-world game. We will draw design ideas from this description, In the game of Kriegspiel, three boards and sets of chessmen are used. There is a referee, whose chesg set isin the center, with two players seated back-to-back, each at his own board. Each player moves his| lown chessmen, and the referee duplicates each move on his own board. The referee tells a player wherd his attempted move is Impossible. Each player tries to guess what move his opponent is making. When a player completes a legal move, the referee announces, “Black (or White) has moved.” When a player {ries an illegal move, the referee waves his hand to prevent it but does not let the opponent know. When} ‘a move results in a capture, the referee announces, “Black (or White) captures on (the rank, fil, long or short diagonal)" and removes the captured plece from the board of the player who lostit. A player may ask, "Any?" and be told by the referee if he has a possible capture with a pawn. That's the only question| he Is permitted. Having asked the question he must try at least one pawn capture before making a different move. To summarize, players make moves, ask "Any?,” suspend or resume a game, claim a draw, or concede. Let's contrast what we can glean from each story and then sketch out our candidate search strategies. The Underlying requirement for the online banking system is flexibility. Functionally, implementation, and information ‘need to be configurable. The application will maintain additional user-supplied information and construct account history from online and other banking transactions. (Our strategy for identifying candidates for this application will be to focus initially on modeling concepts that represent cline banking services, the common interface to backend banking systems, and acoounts. We should have objects that are responsible for performing banking functions and storing application-specific Information about online transactions. Because we are building a multiuser online system, we also need objects that are responsible for ‘managing access to limited resources such as the database and backend banking system connections. The key themes in the banking story are © Modeling online banking services © Flexibly configuring behavior © Sharing scarce software resources among thousands of users © Supporting diferent views of accounts and access privileges The Kriegspiel application, even though It too is an Internet application, has fundamentally different drivers. As with any gaming application, we need to take a step back from our vivid real-world reference of the physical board game and ponder what mechanisms and inventions are needed by a computerized game. This Is always a major design challenge with gaming applications. Its one we are familiar with from past experience. Our goal in designing Internet krlegspiel Isnt to simulate the real world but instead to construct a model that represents what is needed to run a ‘computerized game. Choosing the right abstractions to represent the game and moves will be critical. We also need to consider how running over the Internet will mpact our design. This will affect how we divide the work between application components. Finally, we'll need to implement a semL- intelligent computerized game player—something that is smart enough to play a decent game against a human opponent. Our central concerns for Intemet Kriegspiel © Game modeling © Computer playing a game © Partitioning responsiblities across distributed components hoveratoes fs rrevious] Next] ive es in Search Strategies (Once you have identified major themes, you can use them as sources of inspiration. Make educated guesses about the kinds of inventions that you will need based on the nature of your application and the things that are critical to it. Candidates generally represent the following © The work your system performs © Things directly affected by or connected to the application (other software, physical machinery, hardware devices) © Information that flows through your software © Decision making, control, and coordination activities © Structures and groups of objects © Representations of real-world things the application needs to know something about We guide our search from these perspectives. The kinds of Inventions we seek are closely related to the role stereotypes. If an application's central mission boils down to computation, look to populate it with objects playing the role of service providers that calculate, compute, transform, and figure. You wil ikely invent objects that represent algorithms or operations along with objects that control work processes. If your application's major activity is to assemble and move Information from one place to another, identify candidates that model this Information as objects along with others to coordinate their movement. If your application connects with other systems, invent extemal interfacers that form these connections, Most designs need objects that control or coordinate the work of others. Depending on the complexity of the control, this design decision may or may not be a prominent one. If your application needs to sort through, organize, and make connections between related objects, structurers need to be identified. There are relatively direct links between the kinds of objects you look for and the nature of the work your software carries out ‘The best way to evaluate potential candidates that represent external things Is to shift perspective. Climb into your software and look out at the world. Take your application's viewpoint. Ask what you need to know about your users, the systems you connect to, and things out there that you affect. ‘As you look for candidates one question to ask is, "How much does our software need to know about things in the external and virtual worlds itis connected to?” At the borders, model connections to other systems as interfacer objects. You may include in your design objects that represent these other software systems. These service providers will be called upon by other parts of the application. But when should you model things that are outside a computer, such as your software's users? If itis only their actions that matter and not whom thay are, leave them out of the design. Users’ actions can be conveyed via user interface objects (objects charged with translating user requests and information to other parts of the system). There Is no need to know who Is pushing your application's buttons! On the other hand, if whom users are makes your software behave differently, include some representation of them as a candidate. Some knowledge ofits users (and objects to represent that knowledge) Is needed if your software bases any decisions on whom it interacts with, For example, it different users have alfferent access rights to accounts or ifthe abilly to resume a game requires knowledge of whom the players are, then some representation of these users should be part of the design. [rabies 3-1 ang. outine our search strategies fr our two applications. though we consder each perspective ‘ypicaly only one or two are relevant to any particular theme. if we find that a particular perspective does nat yiela any insights, we move on. For each theme, we briefly summarize the perspectives that yielded insighis and the kinds of candidates we are looking fr Table 3-1. The initial search for online banking application candidates Is based on exploring four themes. Theme Perspective Candidates That Specifically Support. Online banking The work our system Performing financial transactions, functions performs querying accounts Things our software _| Accounts, backend banking system affects transactions Information that flows Information about transactions, account {through our software _|balances, transaction amounts, account history, payments Representations of Customers, users, and the accounts they real-world things access Flexibly configuring Things our software [A common interface to backend systems behavior affects Information that flows through our software Configurable display of Web page banners, text, messages, and account formats Sharing scarce resources Structures and groups of objects Managing limited connections to backend systems and our online banking application database Different views of and access to accounts The work our system performs Restricting users’ views of and ability to perform banking transactions that modify account balances Decision making, coordination, and control Prohibiting access to accounts unless user has specitic privileges ‘Table 3-2. The initial search for Kriegsplel application candidates Is based on the themes of game modeling, Intelligent computerized game playing, and distributed games. Theme Perspective Candidates That Specifically Support... Game modeling |The work our [Assigning players to games, refereeing, system performs _|storing and resuming suspended games, playing a game, determining the legality of a move, determining the outcome of a move, displaying the state of each player's board Information that Information about moves and player requests flows through our software Representations of |Players and their actions real-world things Structures and Managing saved games, the various games, jgroups of objects _| game pieces, and their locations on a game board Computer playing a |The work our Playing a game with a user game system performs Decision making, _|Determining a reasonable move to make control, and based on the current view of the game (which coordination ‘should be just as limited as any human player's view) Partitioning Decision making, _|Communicating a player request to the responsibilities control, and referee and game state between players, across distributed coordination detecting whether a player is still connected components Information that | Player moves, updated boards, and game iflows through our | state software We will identify candidates that support the relevant perspectives. Sometimes candidates leap right out of the page from our brief descriptions; are Player and PlayerAction good candidates based on the fact that we need to have candidates that support our game's real-world view of “players and their actions"? Highly likely. At other times, we ‘must speculate about exactly how our software might work in order to come up with candidates; perhaps there should be a BankingServicesConnectionManager that manages BankingServicesConnections or a DatabaseConnectionManager to manage DatabaseConnections that are scarce resources? Often, different themes and perspectives relterate and reinforce the need for certain kinds of candidates. This Is good. It builds confidence in the relevance a particular candidate has to our application. At other times, ideas do not come so quickly, and we must think more deeply to come up with potential candidates. We won't find all the key candidates in this first pass; nor will our intial ideas about our candidates remain fixed. Our notions change as we give candidates further definition. The initial candidates that we come up with will seed our design. So its particularly important to give each candidate a strong name that suggests its role and purpose. So before we continue searching for candidates, let's explore what it takes to find useful names. iawn Fcrrevous] next] ve RuBoard What's in a Name? Good names increase design energy and momentum. You can build on a good name. When the name of a software object Is spoken, designers infer something about an object's role and responsibilities. That's why grizzled object, designers say, "Choose names carefully." A well-formed name creates a link to past experience and common practice. Meaning comes along with any name, whether we like it or not. Our brains are wired to find connections to things we already know. So the key to giving an object a good name is to make its name fit with what you already know while giving a spin on what it should be doing. Most names fit into a system of names. Different naming ‘schemes coaxist, even within a single application. There isn't one universal naming system. "...the relation of thought to word Is not a thing but a process ... Thought Is not merely expressed in words; it comes into existence through them. Every thought tends to connect something with something else, to establish a relationship between things. Every thought moves, grows and develops, fulfils a function, solves a problem.” —Lev Wygotsky Quality generic names. One scheme for naming things that are special cases of a more generic concept sto tack on to the generic name a description of that special case. |A Calendar represents a system of dates and time at a particular location. GregorlanCalendar extends {the Calendar class. Following convention, we could invent JullanCalendar or ChineseCalendar classes. (Others familiar with this scheme could make educated guesses about how their implementations would itfer trom GregorianCalendar. Include only the most revealing and salient facts in a name. The downside of any descriptive scheme Is that names can become lengthy. Don't name every distinguishing characteristic of an object; hide details that might change or should not be known by other objects. /Should people really have to care that they are using a MilisecondTimerAccurateWithinPlusOrMinusTwoMliseconds, or will Timer suffice? Detalled design decisions should not be revealed unless they are unlikely to change and they have a known impact on the object's users. Exposing implementation details makes them hard to change. Consider the Singleton pattern described in the Design Patterns book. This pattern ensures that a class has only one Instance with a global point of access. We could name every concept that applies this pattern a ‘MumbleMumbleSingleton. Following our guideline, we recommend against this. Singleton is a distinction that is more Important to a class implementer than to a client who uses a singleton. Give names that will be meaningful to those who will be using the candidate, not those who will be implementing it. If someone using your candidate must know the details of its implementation, you have likely missed an opportunity to do a better job of abstraction. One possible exception to this rule Is to append Singleton to a class name when It Is crucial for its users to know this, Give service providers "worker" names. Another English language naming convention Is to end job tiles with "er." ‘Service provider objects are "workers," “doers,” "movers," and "shakers." If you can find a ‘worker name,” it can be a powerful clue to the object's role. Many Java service providers follow this "worker" naming scheme. Some examples are StringTokenizer, ‘SystemClassLoader, and Applet-Viewer. lf a worker-type name doesn't sound right, another convention is to append Service to a name. In the CORBA framework, this is a common convention—for example, TransactionService, NamingService, and so on. Look for additional objects to complement an object whose name implies broad responsibilities. Sometimes a candidate represents a broad concem; sometimes its focus is more narrow. if you come across a name that implies a large set of responsibilities, check whether you've misnamed a candidate. It could be that your candidate should have ‘a narrower focus. Or it might mean that you have uncovered a broad concept that needs to be expanded. Looking for objects that round out or complement a broad name can lead to a family of related concepts—and a family of related candidates. Many times we need both specific and general concepis in our design. The more generic named thing will define responsibiities that each specific candidate has in common, |An object named AccountingService lkely performs some accounting function. The name |AccountingService isnt specific. We cannot infer information about the kinds of accounting services it performs by looking only at its name. Either AccountingService Is responsible for performing every type of accounting function in our application, or it represents an abstraction that other concrete accounting service objects will expand upon. If this is so, we'd expect additional candidates, each with a more specific name such as BalancelnquiryService, PaymentService, or FundsTransferService. These more spectically named candidates would support specific accounting activities. Highlight a general concept with more specific candidates. If you can think of atleast three different special cases, keep both the general concept and specific ones. If later on, you find that these more specific candidates don't share any responsibilities in common, the more abstract concept can always be discarded. However, f you have simply assigned a candidate a name that Is too generic, by all means rename it I your candidate could represent historical records of many other things, better to leave it with a more {generic name, History, instead. If you intend to model transaction history, rename your candidate ‘TransactionHistory. You decide how specific you want to be. Forming an abstraction by looking at two specific cases might work, but comparing and contrasting three or four cases is even better. The more closely related concepts you can compare and contrast in order to identity what they have in common, the better. Therein lies the art of naming: choosing names that convey enough meaning while not being overly restrictive. Leave open possibilities for giving a candidate as much responsibilty as it can handle, and for using itn different situations with minor tweaks. It certainly Is a more powerful design when a candidate can fit into several different situations. The alternative—having a different kind of abject for each different case—is workable, but not nearly so elegant Choose a name that does not limit behavior. Don't limit a candidate's potential by choosing a name that implies too narrow a range of actions. Given the choice, pick a name that lets an object take on more responsibilty. Cur thoughts shape our words, and our words influence our thoughts. Names subtly shape our Ideas about our candidate's expected behaviors. (Consider two altematives for a candidate: Account or AccountRecord. Each could name an object that maintains customer information. From common knowledge we know one meaning of record is "information or facts set down in writing.” An AccountRecord isnt likely to have more than Information holding responsibilities if we fit its role to conventional usage of this name. The name Account, however, leaves open the possibilty for more responsibilities. An Account object could make informed decisions on the information it represents. It sounds livelier and more active than AccountRecord. Choose a name that lasts for a candidate's lifetime. Just as it seems funny to hear a 90-year old called “Junior,” it's a mistake to name a candidate for its earllest responsibilities, ignoring what else it may do later on. And don't be content to stay with the first name you give a candidate If ts work changes. [An object that defines responsiblities for initializing an application and then monitoring for external events signaling shutdown or re-intialization, is better named ApplicationCoordinator than |Applicationiniiaizer. Applicationiniiaizer doesn't imply having ongoing responsibilities after the application Is up and running. ApplicationCoordinator is a better name because its more general meaning encompasses more responsibilities. Choose a name that fits your current design context. When you choose names, select ones that fit your current design surroundings. Otherwise, your candidates’ names may sound strange. What sounds reasonable in an ‘accounting application may seem jarting in an engineering application. |A seasoned Smalltalker tried hard to set aside his blases when he started working with Java. Although he expected Java classes to have totally dlfferent responsiblities, he was surprised to find the Java Dictionary class to be abstract. In Smalltalk, Dictionary objects are created and used frequently. ‘Shed your past biases when they don't ft your current situation, ‘Do not overload names. Unlike spoken language, where words often have multiple meanings, object names should have only one meaning. It isn't good form to have two different types of Account objects with radically different roles that coexist in the same application. Some object-oriented programming languages let you assign the same name to different classes but then force you to uniquely qualify a name when you reference a particular class in code. In Java, for example, classes from different packages can have the same name. In order to uniquely designate a specific one, its name must be qualified by the name of the package where Its defined. ‘A Java designer can define classes with the same name, each residing in a different package. You should do so only i one package Is designed as a replacement for another. Names of things that can simultaneously coexist within a single application should be given different names. Don't overload a name. Programmers have only one context—the running application—in which to interpret names. They already have enough to think about without adding yet another source of confusion. Compilers are good at automatically applying the correct qualification to a name, Humans aren't Eliminate name conflicts by adding an adjective. Sometimes the best names are already chosen. Stil, you need to name your candidate. By adding a descriptive phrase to a name, you can come up with a unique name, ‘The candidate TransactionProperties might be a reasonable name for a candidate whose preferred name conflicts with the preexisting Java class named Properties. ‘A word of caution: If your candidate has a radically diferent meaning, dont co-opt a familiar name. Follow convention. Designers familiar with existing names will expect your candidate to fit in and work similarly. Eliminate conflicts by choosing a name with a similar meaning. Sometimes, your best bet is to look for a synonym. Each synonym has a slightly different shade of meaning, so finding a satisfactory name may be hard, ‘The synonyms for Property, a class defined in the Java libraries, include these words: characteristic, attribute, quality, feature, and trait. Although “attribute” or "feature" might work, "characteristic" seems stuffy, and "quality" seems strained. Choose names that are readily understood. A name shouldn't be too terse. Don't encode meaning or cut comers to save keystrokes. If you want others to get a sense of an object's role without having to aig into how it works, give it ‘a descriptive name. A name can be descriptive without being overly long. "Acct" Is too cryptic. "Account" is better. I your problem domain has well-known and understood abbreviations—such as USD in banking, or Mhz or Gbyte in technology—it is reasonable to include these in a candidate's name. ioe es [revo |e] ve RuBoard Describing Candidates We judge an object by how wells name suits its role and how well ts role suits its situation, Stereotyping a candidate's role provides a handy means for quickly creating an image about an object's intended use. When you find a candidate, name it and then characterize it as fitting one or more stereotypes. Each candidate could be a service provider, controller, coordinator, structurer, information holder, or interfacer. To be even more specific, you may want to distinguish between three different types of interfacers: user interfacers (objects that interface with users)external Interfacers (objects that interface between your application and others) aintersystem interfacers (objects that bridge different parts of an application). To be more explicit with your intentions, you can distinguish whether an object is designed to be passive and just hold on to related information (an information holder), or whether you expect it take a more active role in managing {and maintaining that information (an information provider). If these finer distinctions seem too subtle, don't fret about them. Don't worry about giving an object the “ight” stereotype. If your application fs populated with objects that don't seem to ft these predefined stereotypes, come up with your own stereotypes. Stereotyping is intended to help get you started thinking about your candidates, not to bog you down, It you arent sure about the role your candidate will play, make an educated guess. Use its stereotype as a guide to build a simple definition. in that definition, explain what your candidate might do and list any traits that distinguish it from others. Write this brief definition on the unlined side of a CRC card (see Figure 3-1 Figure 3-1. The unlined side of a CRC card Is used to describe an object's purpose and stereotypes. In this ‘case, a RazzmaFrazzer has only one stereotype. RazzmaFrazzer Furpose: A RazzmaFrazzer i¢ a converter that acewately and speedily translates Razzma objects into Fraze objects. Ag it tranclates, it logs ctatictics on how acewately tt tranlates and whether any information «¢ loct im the tranclation. Stereotypes: Service Provider More generally, a pattem to follow when describing an objects as follows: |An object is a type of thing that does and knows certain things. Briefly, say what those things are, Then ‘mention one or more interesting facts about the object, perhaps a detail about what it does or knows or who it works with, just to provide more context ‘Service providers, controllers, and coordinators are distinguished by what they do. Here's a simple way to describe these stereotypes: |A service provider (or controller or coordinator) Is some kind of thing that does some kind of work. Briefly, describe this work. Then mention something about what is important or interesting about the ‘work it performs or whom it interacts with, If you are working on your own, you may feel less of an urge to write down these thoughts. Alter all, you know what you mean! Even so, i stil can be helpful to jot down an abbreviated thought. You don't want to forget what was so important about that damed RazzmaFrazzer by next Friday. Similarly, if you are working in a team, others likely won't know what's important about a candidate unless you tell them. Any description you can write about a candidate's purpose and what you expect It to do will help. Consider this definition: comers epg al abi eum rons gl Contrast it with this slightly abbreviated definition: "A compiler translates source code into machine language.” The two definitions are nearly Identical. The first adds that a compiler Is a software program. This seems nit-picky—as software designers, we all know that compilers are programs. But the frst definition provides just enough context so that someone not on our same wavelength can relate a compiler to other computer programs. Whenever you can relate something to a widely understood concept (such as a computer program), its meaning will be clearer to all Ifyou and your fellow designers eat, sleep, and breathe design 24 hours a day, a lot may remain unspoken and Unwritten. You understand one another because you think alike. However, if there's ever a question or disagreement about what a candidate Is, it could be that you are making different assumptions. To make intentions clear, add enough detail to remove any doubt; then expect to have a discussion about whose ideas are better. Describe both what a candidate is and what It's not. Relate itto what's familar We provide even more context by giving examples of how a candidate will be used and a general discussion of its duties. This Is particularly important when you are describing a role that can be assumed and extended by several different objects. /A FinancialTransaction represents a single accounting transaction performed by our online banking application. Successful transactions result in updates to a customer's accounts. Specific FinancialTransactions communicate with the banking systems to perform the actual work. Examples are! Funds TransferTransaction and MakePaymentTransaction. Ia common meaning sults a candidate, use it fo form a basic definition. Don't invent jargon for invention's sake. In the case of alternative definitions, choose one that most closely matches your application's themes. Start with a standard meaning, fit fits. Then describe what makes that object unique within your application The American Heritage Dictionary has six definitions for account: Anarrative or record of events 2. Areason given for a particular action 3. A formal banking, brokerage, or business relationship established to provide for regular services, dealings, ‘and other financial transactions 4. Apprecise list or enumeration of financial transactions 5. Money deposited for checking, savings, or brokerage use 6 Accustomer having a business or credit relationship with a firm Itisn’t too much of a stretch to conceive of different candidates that reflect each of these definitions. In our online banking application, accounts most likely represent money (definition 5). ules that govern access to and use of funds are important. Different types of accounts have different rules. Although itis conceivable that an account could also be "a precise list of financial transactions” (definition 4), we reject that usage as being too far off the mark. People in the banking business think about accounts as money, assets, or liabilities and not as a list of transactions. In the same fashion, we reject definition 6. It doesn't specifically mention assets. We easily reject definitions 1 and 2 {as describing something very different from our notion of accounts in banking, In banking, accounts represent money. We choose definition 5 because itis the most central concept to the world of banking: |An account is a record of money deposited at the bank for checking, savings, or other purposes. Add application-specific facts to generic definitions. The preceding definition is OK, but it's too general for online banking. In the online banking application, users can perform certain transactions and view their balances and transaction histories. We add these application specifies to our original description: |An account is a record of money deposited at the bank for checking, savings, or other purposes. In the online banking system customers can access accounts to transfer funds, view account balances and {transaction historical data, or make payments. A customer may have several bank accounts, The more focused a candidate is, the better. Of course, a candidate may be suited to more than one use. Objects can be designed to fit into more than one application. A framework operates in many different contexts. A utilitarian object can be used in many cases. If you want your candidate to have a broader use, make this intent clear by writing the expected usage on the CRC card, Distinguish candidates by how they behave In your application. If distinctions seem blurry in the world outside your software, itis especially important to clarify your software objects’ roles. Even if you can distinguish between a customer and an account, you still need to decide whether itis worth having two candidates or to have one merged Idea. (Don't expect the business experts to help make this decision. It s a purely “technical” modeling one.) A candidate that reflects something meaningful in the world outside your application's borders may not be valuable to your design. Let's look at the sixth definition of account: An account is a customer having a business or credit relationship with a firm.” What is the difference between a customer and an account? Are they the same? If we had chosen this definition, Would we need both customer and account objects in our banking application? When you discover overlapping candidates, refine thelr roles and make distinctions. Discard a candidate or merge It with another when its purpose seems too narrow (and could easily be subsumed by another candidate). When In doubt, keep both, For both Customer and Account to survive candidacy and stick in a design, thelr roles must be distinct and add value to the application. We could conceive of a Customer as a structurer that manages one or ‘more Account objects. And, in the online banking application, one or more users can be associated with ‘a Customer. For example, the customer “Joe's Trucking” might have four authorized users, each with different privileges and access rights to different accounts. Another option would be to give an Account responsibilty for knowing the customer and users. We could then eliminate Customer. We decide to Include both Customer and Account in our design because giving those responsibilities to Account objects doesn't seem appropriate—we can envision customers and users sticking around even when {their accounts are closed (and perhaps new accounts are opened). So customers are somewhat Independent of accounts. During exploratory design, expect a certain degree of ambiguity. You can always weed out undistinguished candidates when you find they don't add any value. Put question marks by candidates that need more definition. A candidate Is Just that—a potential contributor. hoveratoes fs rrevious] Next] ive es in Characterizing Candidates Before eliminating any possibility, consider how a candidate might work and how it relates to others. itis best to consider a candidate in a larger context. We can characterize candidates according to their © Work habits © Relationships with others © Common obligations Location within an application architecture © Abstraction level To explore a candidate's work habits, ask, ‘ake one point of view—from the outside looking in. This is the same view a peer or cllent would take, Speculate about what services it might offer or how it might affect others. Think about these things, but don't assign responsibilities just yet. Ask whether the object Is sel-contained, working on its own initiative, or directed by others. Will it be constantly busy? Or wilt need to be prodded into action? Is it an important, central character, or is it somewhere on the periphery? Ask what each candidate might do and be. if you haven't any idea, dig in and look for its potential value. if you are undecided, spend few minutes speculating how it might it into its neighborhood and about the nature of its role: hat does it do, and how does it ft in? We think of an Account as an information holder. So we do not think of it adjusting its balance on its lown—it Is probably changed by outside requests (both online banking transactions and other account activity). An Account knows its balance and transaction history. An account doesn't manage its customer, so it doesn't have much of a structuring role, but itis associated with its customers (does it need to know its customer, or does its customer know about it?) It isn't obvious how backend banking {transactions that affect an account's status will be controlled (will an Account be involved in delegating this work or not?) so we are uncertain how much work it will actually do. We'll defer thinking through {these issues until we develop a more detailed blueprint for our application's control architecture. iow rsa [revo |e] ive es in Connecting Candidates Given Its limited space, what you can say on a CRC card will be brief. But CRC cards are much more than a compact, space to record design ideas. They are real and tangible. You can pick up a card and talk about itas if it were the object itself, forgetting that the card "stands in" for a “real” object. You can use CRC cards to explore what candidates are and how they relate to others. You can move a card closer to any collaborators. You can poke at them, making as many connections and distinctions as you can. You can pick them up and lay out a new arrangement that ampities a fresh insight, looking for patterns and similarities and differences. Which objects do similar things? Put them in a pile. Which objects are part of a neighborhood working on part of the problem? Move them closer. Get a sense of how your candidates fit and relate. Some useful ways to cluster candidates are as follows: © By application layer © Byuse case © By stereotype role © By neighborhood By abstraction evel © By application theme CRC cards, as invented by Ward Cunningham and Kent Beck, were originally used to teach object-oriented concepts. They have far broader applicabilly than as teaching aids. They can help you think about and link candidates. There Is no standard way to fll out or use CRC cards. Several books have been written on the “art” and "practice" of CRC card modeling. David Bellin and Susan Suchman Simone's The CRC Card Book (Addison-Wesley, 1997) talks ‘much about the process and people aspects of CRC cards. In Nancy Wilkinson's Using CRC Cards: An Informal Approach to Object-Oriented Development (SIGS, 1995), a CRC model for a library application is worked out and its translation to a C++ implementation is described. Figure out what works best for you. Use CRC cards to express your ideas. Jot down initial ideas on the unlined side: Atthe very minimum, record a candidate's name, a brief description, and its role stereotypes (see Figure 3-3. That's ‘mainly what you'e intially looking for. Later you'll get more specific. Figure 3-2. The purpose of a candidate Is recorded on the unlined side of a CRC card. De pBiaadaia rYSsiina tion Furpose: A Destnation represents any of several locations where a message can be sent. It ako Knows the objects that are responsible for hardline. the actval delivery to the destwation that it represents. Stereotypes: Structwer, Service Frovider But you can also note things of interest: Does a candidate play a role in a well-known design pattem? Name that pattern and the candidate's role init. Is it intended to fit into a narrow context, or, if carefully designed, might it be Used in different applications? Note anything unusual and worth remembering. Is it an important abstraction? Put a se CRC cards to express what you think is Important to know about a big star by its name, As shown in Figure 3. candidate. Figure 3-3. You can add scribbles, questions, and comments to a CRC card to help you remember key points. Destin inatio ATION Mev valves t Firpoce: A A Destination as any of several location where a message can be sent, It alo Knows the objects that ave responsible, for hranelling. the actual delivery to the: destwation that it represents, preload Patterns: Composite component Stereotypes: Structwer, Service Provider arty anes check on Ot Vow rsa [revo |e] ive es in Looking for Common Ground Earlier, we suggested that you make sharp distinctions between candidates. If you couldn't find enough differences, We recommended that you merge candidates that have overlapping roles. Now we suggest that you take another, closer look at your candidates. This time you want to see what your candidates have in common. You should always be on the lookout for common roles and responsibilities that candidates share. If you can identify what candidates have in common, you can consciously make your design more consistent by recognizing these common aspects and ‘making them evident. You can identify a common category that objects fit into. You can define a common role that all objects in a category play. Shared responsibilities can be defined and unified in interfaces. Objects that collaborate with them can ignore any differences and treat them allke. Furthermore, a class can be defined to implement shared responsibiities that make up a shared role, guaranteeing that the implementation of classes that inherit these Implemented responsibilities works consistent. You are likely to find several ways to organize your candidates. Some will be more meaningful than others. Each one that seems useful wil Ikely contribute to your design's clarity. The more you can identify what objects have in ‘common, the more opportunities you have to make things consistent. Eventually you may define several new roles that describe commonly shared responsibilities. Your inital cut at this won't be your last. Keep looking for what objects have in common and for ways to exploit commonailies to simplify your design. ‘Common behavior could also imply the need for another candidate that is the supplier of that shared behavior. Look for powerful abstractions and common roles. Things in the real world do not directly translate to good software objects! Form candidates with an eye toward gaining some economy of expression. Carefully consider Which abstractions belong in your object design. In our Kriegspiel game, there are various actions that a player can perform: "propose a move," “ask /whether a pawn can capture in a move," ‘suspend a game,” and so on. I's a pretty safe bet that we have a different candidate for each action: ProposeAMove, SuspendAGame, and so on. Proposing a move seems quite distinct from suspending a game. A harder question is whether we should define PlayerAction as a common role shared by each of these action-oriented candidates. if we can write a |good definition for PlayerAction, we should do so and define a role that is shared by all player action candidates. There seem to be several things common to all actions (such as who is making the request and how long its active). Eventually, if we find enough common behavior for PlayerAction, it will be realized in our detailed design as a common interface supported by different kinds of PlayerAction objects. We may define a superclass that defines responsibilities common to specific player action subclasses. Or common behavior might imply the need for another candidate that is the supplier of that shared behavior. Look for the right level of abstraction to Include in your design. Finding the right level of abstraction for candidates takes practice and experimentation. You may have made too many distinctions and created too many candidates—a dull design that works but Is tedious. At the end of the day, discard candidates that add no value, whether they are too abstract or too concrete. Having too many candidates with only very minor variations doesn't make a good design. Identify candidates that potentially can be used in multiple scenarios. (Certain actions affect the position of pieces on a board. Should we have different candidates for each plece's potential types of moves? Not likely. This solution is tedious and offers no design economy. If [you can cover more ground with a more abstract representation of something, do so. A single candidat: can always be configured to behave differently under different situations. Objects encapsulate Information that they can use to decide how to behave. The Propose-AMove candidate can easily represent all moves suggested by any chess plece. This single candidate will know what piece is being moved and Its proposed postition. Discard candidates if they can be replaced by a shared role. To tind common ground, you need to let go of the litle details that make objects different in order to find more powerful concepts that can simply your design. What do books, CDs, and calendars have in common? If you are a business selling these items over the| Internet, they have a lot in common. Sure, they are different, too. Books likely belong to their own category of items that can be searched and browsed, But all these kind of things share much in ‘common. They all have a description (both visual and text), a set of classifications or search categories {they belong to, an author, an availabilty, a price, and a discounted price. It sounds as if their common aspects are more important, from the Web application's perspective, than thelr differences. This suggests that all these different kinds of things could be represented by a single candidate, Inventoryitem, that knows what kind of thing itis and the categories it belongs to. Purely and simply, you gloss over minor differences. You don't need to include different candidates for each category of thing. infact, those distinctions may not be as important to your software as they are to those who buy and use the items. When you are shopping for items, you may be thinking of how they are used—books are read, calendars hung on a wall, and CDs played—but those distinctions are not important it you are designing} software to sell them. Sure, you want to allow for your software to recognize what category something belongs to. You want to list all books together. But you probably want to categorize things in the same subcategory, whether or not they are the same kind of thing. Books about jazz and jazz CDs are in the "Jazz items" category. Only if objects in different categories behave differently in your software do you need to keep different categories as distinct candidates. The real test of whether a category adds value to a design is whether it can define common responsibilities for things that belong to I. Blur distinctions. There are times when both concrete candidates and their shared role add value to a design. There are times when they do not. If you clearly see that candidates that share a common role have significantly different behavior, then keep them. Test whether the distinctions you have made are really necessary What value is there in including different kinds of bank accounts, such as checking or savings accounts In our online banking application? Checking accounts, savings accounts, and money market accounts have different rates of interest, account numbering schemes, and dally account draw limits. But these distinctions aren‘t important to our online banking application. We pass transactions to the banking software to handle and let them adjust account balances. In fact, because our application Is designed to support different banks, each with its own account numbering scheme, a distinction made on account ype (checking or savings) Isn't meaningful. Our application doesn't calculate interest. So we choose to Include only BankAccount as a candidate. If we were designing backend banking software that calculated interest, our decision would be different. hoveratoes fs rrevious] Next] ive es in Defend Candidates and Look for Others For a candidate to stay in the running, you should be able to state why itis worth keeping, along with any ideas you want to explore: "A user accesses accounts to transfer funds, make payments, or view transaction history.” In the next breath you can add, “Accounts contain information that enables a customer to perform financial transactions. Accounts know how to describe themselves; they know and adjust their balance; they are affected by different financial transactions; they know their transaction history. Ate there any other candidates we should be identifying to support accounts in their role?” By taking short side excursions to look for more candidates, you will come back with a better sense of whether you are on target. You can find more candidates by looking for ways to support and complement the ones you've already found: Marvin Minsky theorizes about the many agents working at different levels during problem solving, Most people don't forget that they are packing a suitcase to go on a trip when they stop to fila toiletry bag. Side excursions are a normal part of problem solving. Potential candidates that complement and support Account: |AccountHistory—A record of transactions against an account FinancialTransaction—An operation applied to one or more accounts. A service provider could represer leach type of transaction that affects an account. There are multiple types of transactions that we suppor ‘with our online banking application. What's the difference between a transaction that affects an accounts balance, and an inquiry into some aspect of an account such as its balance, history, or activation status? How should we model each inquiry? You are always tree to decide all your candidates stink, toss them, and start over. At the beginning this is cheap and relatively painless. Defend candidates on their merits, and don't protect them from close scrutiny. ‘Searching can go on for quite a while If you are full of ideas. Stop when you feel you are looking too far afleld. You need enough candidates so that you can compare and contrast them and to seed your further design work. There isn't any magic number. The more you know about a problem, the more candidates you are likely to invent in a first pass. Fifty candidates may seem lke a lot, but i's not an unreasonable number. Twenty is OK, too. You find candidates in bursts as you consider your design's themes. I's pretty common for candidates to support more than one theme, All this means Is that your objects fit into and support more than one central concern. ‘Stop brainstorming candidates when you run out of energy. Then review how these candidates might collectively support the responsiblities implied by a theme. When you think you have enough candidates, review them once ‘more for their mert Keep any candidate and put it on the "A" list, for acceptable, when you can © Give ta good name © Define it © Stereotype it © See that it might be used in suppor ofa particular use case © See that itis an important architectural element © Assign it one or two intial responsibilities © Understand how other objects view it © See that itis important Differentiate it from similar candidates Discard a candidate when it Has responsibilities that overlap with those of other candidates that you lke better © Seems vague ‘Appears to be outside your system's boundaries Doesnt add value © Seems insignificant or too clever of too much for what you need to accomplish ‘You may stil be uncertain about some candidates. Put these on the "D,” or deferred, lst to revisit later. For now, keep them in the running. The best way to make more progress Is to design how these objects will work together. The very next step welll take is to assign each candidate specific responsiblities. And during that activity, we will come up with ‘more candidates and reshape those we've already found, ioe es [revo |e] ive es in SUMMARY You can approach the finding of objects somewhat systematically. Establish a framework for searching for candidates by writing a story about your application. In this story, write about the important aspects of your application. The candidates you Identify should support various aspects of your story. You can use CRC cards to record your preliminary ideas about these candidates. CRC stands for candidates, responsibilities, collaborators. Candidates generally represent work performed by your software, things your software affects, information, control and decision making, ways to structure and arrange groups of objects, and representations of things in the world that your software needs to know something about. Good names for candidates are important. Choose them with care, Choose names that fit within a consistent naming scheme and aren't too limiting or overly specific. Once you've named and described each candidate's purpose, you can compare and contrast the candidates. For a candidate to stay in the running, you should be able to defend why it Is worth keeping, But your intial ideas are just educated guesses about the kinds of objects that you will need based on the nature of ‘our application and the things that are critical to it. The real test of each candidate's worth will be when you can assign It specific responsibilities and design it to collaborate with others. hoveratoes fs rrevious] vex] ive es in FURTHER READING Timothy Buda, in An Introduction to Object-Oriented Programming (Addison-Wesley, 2002), presents a thoughtful discussion of abstraction and object-oriented design. Another source of inspiration Is Martin Fowler's Analysis Patterns: Reusable Object Models (Addison-Wesley, 1996). This book reveals how a good modeler and analyst thinks through issues and comes up with useful abstractions, hoveratoes fs rrevious] Next] ive es in Chapter 4, Responsibilities Christopher Alexander states, "Form is part of the world over which we have control, and which we decide to shape hile leaving the rest of the world as itis." The measure of a design's goodness Is how well the form fits into its context. When we shape an object's responsibilties, we are inventing a form that should fit smoothly into its environment. We have the luxury of shaping both form and context when we distribute responsibilities among collaborators, The rightness of a form, according to Alexander, depends on how effortlessly it contacts with its environment. To make informed decisions about an object's responsibllies, we should divide form and context across several dimensions and consider several aspects of the problem. Looking at several possible divisions of form (that which we can shape and make whole) and context (that which we cannot control) sheds light on the problem. You should consider what the real problem Is before you design a solution, But how many dimensions of a design problem should you consider? Too much digression, and you never finish. Not enough exploration, and you hack out a solution while potentially missing a significant opportunity. You need to strike ‘a proper balance. There's a lot to be gained by taking quick side excursions from time to time. It's easier to reshuttle responsiblities on cards than Its to rewrite thousands of lines of code, Consider some alternatives before you spend. a lot of time bullding the wrong solution. ‘A careful designer considers several divisions, identifies those that provide fruitful distinctions, and then designs the form. iowa an ive es in What Are Responsibilities? Responsibilities are general statements about software objects. They include three major items: © The actions an object performs © The knowledge an object maintains © Major decisions an object makes that affect others Physical objects, unlike our inteligent software objects, typically do work or hold on to things or information. A phone book is a physical object but it takes no action. A thermostat exists, and it makes decisions and sends control signals. A teakettle exists, but it does litle more than act as a reservoir (and occasionally whistles to send a signal). Physical objects usually don't make informed decisions. However, a dog is man's best friend and companion and does many different things on its own behalf. Our software objects lle somewhere between these extremes: They aren't sentient beings, but they can be more or less lively, depending on what responsibilities we give them. Let's consider the design of a simple physical object. Alexander, In Notes on Synthesis and Form, asks what the right form is for a kettle. A teakettle holds water that can be heated until bolling. People safely pick it up when itis filed with boiling water and pour a cup of tea. And, if we follow convention, a teakettle signals us by whistling when the water bolls. We can rephrase these characteristics as general responsibilities: © Pour contents without spiling or splashing © Hold water that can be heated until boing © Notity when water bolls © Offers a convenient means for carrying In a safe manner How do we know whether we've got these right? Sure, some designers shamelessly redraw boundaries between the form they are working on and the context within which it exists. Overzealous framework designers we've known come to mind. If you think “outside the box," you can always change the boundary between a form and its context. You can claim that it s not the kettle that needs to be designed, but the method of heating water. Then the kettle becomes part of the context, and the stove or heating appliance becomes the form under consideration. In this case, lateral thinking might lead to innovation—an “instant hot" unit that heats tap water as it flows through it. We walk a fine line when we invent design solutions. If we are clever In redrawing the boundaries of the problem, we may come up with a Novel solution. But we also risk creating unnecessary complexity instead of following a more straightforward path, "Do not try to design objects to have all the conceivable behavior shown In the real world. Rather, make software objects only as smart as the application needs them to be and no smarter.” —Jon Kem The key Is to know when to push on redefining the problem and when to push on defining a solution. In this chapter we explore the art of finding, defining, and assigning object responsibilities ... and striking a balance between thinking through alternatives and making reasonable responsibly assignments. Responsibilties aren't just there waiting for us. Ouch, Ive bumped into a responsibility, better assign it to one of my candidates! How to optimally distribute individual responsibilties between objects is offen the most difficult problem in object design. iawn nn ive es in Where Do Responsibilities Come From? ur strategy for assigning responsiblities to objects is very simple: Cover areas that have big Impacts. Look for actions to be performed and information that needs to be maintained or created. You can glean information from several sources: Perhaps you have a specification of your software's usage; you may have written some use cases; or you may know of additional requirements or desired characteristics of your software. Responsibilities emerge from these sources and from ideas about how your software machinery should work. You will need to reformulate demands and characteristics and software descriptions into responsibilty statements. If statements seem too broad to be assigned to individual objects, create smaller duties that can be. These smaller subresponsibilties collectively add up to larger ones. Formulating and assigning responsibilities to objects Involves inspiration, invention, and translation of constraints and general descriptions into specific responsibilities. Assigning responsibiities to objects gives them shape and form. Once you make intial responsibilty assignments, you should test whether they are well formed. Let's consider several activities for forming responsibities. We do the following: © ‘Identity system responsibllties stated or implied in use cases, © Plug inherent gaps in use cases and other system descriptions with adaitional lower-level responsibilities © Tease out additional system behavior from themes and software stories © Follow ‘what i... then..and how?" chains of reasoning © Identity stereotypical responsibilities to match stereotypical roles © Search each candidate's deeper nature © entity responsiblites to support relationships and dependencies between candidates © entity responsibllties associated with objects’ major “fe events" © Identity technical responsibilities that need to be assumed by objects to fit into a specific software environment Activities for identifying responsibilities fall into one of three categories: nding them from external descriptions, inventing, and adding details. Responsibilities come from statements or implications of system behavior found in use cases. There Is a gap between use case descriptions and object responsibilities. Responsibilities are general statements about what an object knows, does, or decides. Use case descriptions are statements about our system's behavior and how actors Interact with it. Use cases describe our software from the perspective of an outside observer. They don’ tell how something is accomplished. Use cases provide a rough idea of how our system will work and the tasks involved. AS designers we bridge this gap by transforming descriptions found in use cases into explicit statements about actions, Information, or decision-making responsibilities. This is a three-step process: © Identity things the system does and information it manages. © Restate these as responsibilities. © Break them down into smaller parts if necessary, and assign them to appropriate objects. Consider this narrative that describes how a university student registers for courses. It leaves out a lot of detalls (such as how the user interface Is laid out and the specific rules that affect registration), which we presume are found elsewhere: Use Case: Register Online For Classes |A student can register online for classes by filing out and submitting an online registration form for approval. While fling out the registration form, a student can browse the course schedules and cross-listed courses, audit degree requirements, and update personal and financial aid information. The student can also access the Waltist Class and Drop Class functions. Each course on a student's schedule has the following information: grading option, term, course tite, section number, and class number. Although not prohibited from adding courses with time conflicts, a student should be made aware of any potential problems when bullding a schedule. When a proposed schedule Is submitted for approval, it will be checked for conformance to all of the rules that the University specities for course load, prerequisites, and required approvals. The system should notify the students of full lasses and allow students to add themselves to the walt list for a particular class. In some cases, exceptions to the rules can be requested (such as time conflicts or overload of credit), but {these actions are performed separately. Once students have received confirmation of an approved course schedule, they are considered registered for the term. Depending on how much detail is included in a use case, it can be more or less dificult to find statements about our software's behavior. Use cases aren't packed with actions or behaviors that are readily ascribed to individual objects. However, even from this high-level narrative we can glean these responsibilities and in parentheses suggest some Ideas about how they might be dealt with: Generate and display an online registration form. (Something needs to know the structure of a registration form and the details of how itis displayed.) Provide feedback as the student enters course selections about conflicts or problems. (Something needs to check that the student can sign up for a course, given the student's academic standing, and ‘then there is a UI component that displays feedback.) Provide capabilities for browsing, auditing degree requirements, updating personal and financial Information. (Browsing sounds lke a large responsibilty involving several objects. Auditing degree requirements seems complex. We don't know how much work Is involved in comparing a student's {transcript and major against required courses. This needs further investigation. Updating personal and {nancial information seems specific. It will involve objects with responsiblities for displaying and editing {this information.) Provide capabilities for wait listing and dropping classes. (These two functions wil kely involve several objects: Something needs to coordinate both tasks, update the waiting ist, and adjust the student's schedule.) \Validate that each course in a schedule meets constraints such as pre-requisites, approvals, eto. (Sounds lke a specific task that could be assigned to a StudentSchedule object.) Notify the student of approved course selections (Notification seems like a subresponsibllty that could be assigned to the same object who has responsibilty for coordinating the work of schedule validation and reports the results to the user. The means of notification will ikely Involve instantiating and using objects from pre-existing UI components) Notify the student of conflicts and allow him to resolve them (Again, notification seems like a responsibilty of an object responsible for coordinating the registration task; other objects will likely be Involved in the resolution of confit.) descriptions that we use as general guides as we bulld our design. Use case scenarios describe step-by-step glean from this scenario: Use Case Scenario: Register Online For Classes 1. Student pulls up the registration form and identities selt. 2. System verifies that student Is allowed to register at this time. 3. Student enters the following for each course: course number, section number, and grading option 4, Student submits course schedule for approval ‘System verifies that the student meets credit load policies and course prerequisites and that By intent, use cases leave out design details. They are descriptive, not prescriptive. They tella story. Use cases are sequences. Supposedly they include more detail than an overview. Let's see what additional responsibilities we can ‘none of the requested courses are full 6. System retumns approved courses in proposed schedule for confirmation, 7. Student confirms schedule. & System adds student to each class roster and retums confirmation of successful registration. We find a few additional responsibilities that are more specific: (Check that the student is eligible to register. (From step 2. Probably can be assigned to an object that, coordinates the registration activity.) |Add student to course rosters. (From step 8. Seems pretty specific. Some object will undoubtedly coordinate registration and ask the course roster to be updated.) Display confirmation of registration. (From step 8. Again, Ul elements are involved, and something that coordinates the work.) \Validate that each course in a schedule meets constraints such as prerequisites, approvals, eto. (Sounds lke a specific task that could be assigned to a StudentSchedule object.) Notify the student of approved course selections. (Notification seems lke a subresponsibilty that could be assigned to the same object that responsibilty for coordinating the work of schedule validation and reports the results to the user. This will kely involve instantiating and using preexisting U! components.) Notify the student of conflicts and allow him or her to resolve them. (Again, notification seems like a responsibilty of an object responsible for coordinating the registration task; other objects will likely be Involved in the resolution of contilcts.) Most of these statements only hint at part of the work that needs to be done. They tell that confirmations are displayed, but not that they should be constructed by formatting specific registration information. They don't define acceptable responses to errors. They don't tell which system responsibiliies Interact. They dont tell what actions will be complex, nor do they specify timing constraints. Use cases describe the general nature of our work. We must shape all the details Additional responsibilities come from plugging inherent gaps in use case and other system descriptions. To gain confidence in your design, you must dig deeper into the nature of the problem and ask questions. Just by looking at our list of responsibilities we can come up with questions leading to more responsibilities. Here are a few: How are course prerequisites specified? They may be part of a course description that our system can check, or they may be a relationship between courses, or a course may be responsible for knowing its prerequisites. What states does a student's schedule go through? A student can bulld a schedule, submit it for validation, and confirm it. But what happens when things go wrong or problems are detected? When Is al student really finished with his or her schedule? What different responsibilities does a student schedule have depending on what state it is in? What happens when a student submits a schedule to be validated? Are the slots in the class reserved after each course Is validated? How long does it take or should It take for prerequisites to be validated? What happens in exceptional cases? Does registering happen in “teal time," or does the student receive notification after work Is carried out behind the scenes? How much help should the system give to a student when things go wrong? Is notification of problems lenough, or should the system provide suppor for remedying problems? The sooner you ask and get answers to specific questions that will shape your system's behavior, the better. The answers will guide your thinking as you discover more detalled software responsibilities. Use cases rarely describe aspects of control, coordination, error detection, visual display, timing, or synchronization. Designers must figure out these details. You can push forward with assigning responsibilities, even with many questions left answered, Tag those questions that will have the biggest impact. If you envision a range of possible answers and guess at those that are most lkely to have the most impact, you can know where to push for answers, Take two approaches: Identify responsibilities as well as unresolved questions. Continue to work on what you do know. Identity questions that are most likely to significantly impact your design. Once you get answers, you undoubtedly will refine your design. You won't know how comprehensive your solution needs to be until you get some answers, Defer the specific design of control and coordination responsibilities until you make choices about how to distribute decision making and control responsiblities. Test your collaboration model with both "happy path" and more complicated scenarios. For now, collect and assign as many specific responsibilties as you can. Design, and the assignment of responsibilities, is iterative. You make an initial pass at pinning down responsibilties, and then you rework your ideas as you come to know more about your objects and thelr interactions. Responsibilities come from themes and design stories. Earlier, we recommended that you write a brief story that describes the key Ideas behind your software, This design story kept you focused on what's important and stimulated your thinking about appropriate candidates. You can return to this story to extract some responsibilities. Let's reconsider the Internet banking story. Phrases that require system action are bold: ‘This application provides Internet access to banking services. It should be easily configured to work {or different banks. A critical element in the design is the declaration af common way to call In to different backend banking systems. We will define a common set of banking transactions and a |ramework that will cal Into banking-specific code that "plugs into" the standard layer implementing the details. The rest of our software wil interface only with the bank-Independent service layer. We've developed a prototype implementation of this layer and have configured It to work for two different banks. Although itis still a prototype, we understand how to write a common banking service layer. Lately, our bank has been busy acquiring other banks and integrating thelr software. We've been {through three system conversions in the past year. We want to focus on making this service layer easy to Implement and test. At the heart of our system is the abilty to rapidly configure our application to wor {or different backends and to put a different pretty face on each. This includes customizing screen layouts, messages, and banner text. Theonline banking functions are fairly simple: Customers register to use the online banking services and thenlog In and access thelr accounts to make payments, view account balances and transaction histories, and transfer funds. This is. straightforward and easy to Implement. There Is added complexity. Customers record Information and notes about each online transaction. Thisextra information will be maintained by our application in Its own database, because preexisting bank software has no way to store it. We want a customer to ‘view human-readable information, not ancient bank software detailed transaction records. When a customer asks to view an account's transaction history we'll have tomerge this data with records supplied from the backend software. Multiple users can access a customer's accounts, each with potentially different access rights. Certain users might have no access to sensitive accounts. A company executive might only view account balances, whereas a clerk in the accounts payable [department could make payments and a comptroller might be able to transfer funds between accounts. Because of the story's brevity, the responsibilties we find reflect only the highlights. This story mentions maintaining transaction-specttic information but doesn't describe anything about registering for online banking. We search for responsibiities that support something the story emphasizes. We summarize these responsibilties and note where they lead us: ‘The more specific the responsibilty, the easier itis to assign. Broad statements need to be broken down into smaller activities that can be assigned to one or more objects. © Know a specific bank’s configuration of supported features, default languages, and so on (will lead to designing objects with responsibilties for knowing a bank's configurable parameters and options). © Translate common service requests to standard backend bank calls (will lead to designing service providers that handle these requests}. © Translate results from backend API calls into standard results (will lead to responsibilities assigned to intertacers between the common service layer and backend bank systems). © Manage configurable banners, customized screen layouts, and user messages (will lead to th design of customization responsibilities and design of external resources). © Perform financial transactions (will lead to designing objects that perform individual transactions). © Record information and transaction notes in the database (will cause us to design transaction records and a means for storing them in our database). © Merge notes with bank transaction records (will ead to specific responsiblities for assembling transaction summaries from notes and merging them with backend bank data). © Display and format account histories and current balances (will lead to Ul objects, objects that represent account history, and responsibilties for coordinating their display). © Manage users and their access rights to accounts (wil lead to responsibilities for knowing and: changing access rights—perhaps directly associated with customers and users). © Manage connections to the database and the backend banking services (leads to specific responsiblities for various connection and connection managing objects). We can assign responsibilities for managing connections to specific connection managers. Financial transactions will be performed by the coordinated work of many objects, each with specific responsibilities. To assign responsibilities for performing transactions, we need to consider the details of each transaction in turn. Each transaction will require a different sequence of work steps, although some may be in common (for instance, al transactions are logged along with user-specific notes in the system's database). Responsibilities come from following "what It... and then... and how?" chains of reasoning. To gain even more Insight, you need to consider how various requirements may impact your design. This involves more heavy mental liting than our other responsibility sources. In this case, you don't start with a specifi task such as "make a loan payment" or specific action such as "verity credit Ioad.” Instead, you need to lay a path from a high-level goal, such as “the software should be offline only during routine maintenance," to a series of actions or activities that achieve it Only then can you make statements about what the system needs to specifically do as a consequence. Once you've come up with these specific conclusions, you can formulate specific responsibilities. Coming up with a plan to solve a familiar problem Is trivial, We're talking about something much harder—reasoning about an unfamiliar problem and a solution at the same time. This involves making an initial assessment and then following that to some logical conclusions. We can think of many situations when we've chased design implications. Most involved short, solo excursions. Individuals thought through the problem and followed thelr instincts. As a group we might have kicked around the nature of the problem before the individuals went away and thought through the problem. Reasoning toward a solution seems to be an individual activity or one taken on by a small team of like-minded souls. Here is one example that shows how thinking about a design constraint led to a new understanding and additional responsibiities. Our online banking application had a design constraint: it needed to recover from component failure. Ifa component went down or became unavallable, our system had to keep working and bring up another copy of a. component. Our timeline for researching solutions was extremely shor. Len Lutomski, our distributed system expert, quickly assessed that the weakest link in our architecture was the name server. As the registry for distributed components, if this server failed, the entire "memory" was lost of how connections could be made to services. If this component failed, the entire system went down. This led Len to conclude that the name servers needed additional responsibilities for publishing location information changes, and that we needed additional shadow name servers standing in reserve, ready to be tapped into service if the leading name server falled. In his own words, here Is how Len came to a workable solution: [the solution] was dictated by the need to get something up fast, and by my desire to begin by Isolating the problems of fault-tolerance from the problems of developing support for service groups. Early moves made on these grounds constrained the possible future developments, just as though it was ‘a game of chess. My separation between the fault-tolerance part and the service groups part was developed prior to a clean understanding of the problem space ... | was operating off the intuition that naming contexts should be naming contexts and not something else, and the sense that the fault-tolerance would not be {trivial ...n a good design the notions of a service group, a naming service, and of fault-tolerance and state-replication, would be both orthogonal and simply composed ... If | had had the time, | think | could have put in another level of abstraction Often your intial design will not be as simple or as elegant or as complete as you'd like. You don't have time to make ‘many wrong moves. On the online banking project, the designer followed these principles: Keep concems separate, and don't intermix responsiblties. Each object or component should do its job simply and well ‘The key to solving design problems quickly and adequately Isto stick to your principles while you follow your hunches. Following his intial line of reasoning led him to very specific responsibilities. His objects weren't up to his high standards, but they did the job. Responsibilities naturally arise from an object's stereotypical roles. Whether an object primarily "knows things,” "does things," or "controls and decides" Is based on its role stereotype. Exploring an object's character will lead to an Initial set of responsibiities. Up to this point, we have been looking outwardly at descriptions of our system's behavior, its main themes, and its challenging requirements. The following activities shift our focus from external descriptions to stereotypical views of objects within their software environment, Information holders answer questions. They are responsible for maintaining facts that support these questions. When assigning responsibilities to an information holder, ask, "What do other objects or parts of the system want to ask?" Restate these queries as responsibilities for "knowing." Look for specific information that fits each candidate's roe. Each information holder should support a coherent, related set of responsibilities. Secondarlly, ask, "What else does this information holder need to know or do in order to carry out its public obligations?” These will be private responsibilities it undertakes to carry out its public duties. When designing a service provider, ask, "What requests should it handle?" Then tum around and state these as responsibiities for "doing" or "performing" specific services. Similarly, structurers should have responsibilties for ‘maintaining relationships between other objects and for answering questions about them. Interfacers will have specific duties for translating information and requests from one part of the system to another (and translating between different levels of abstraction). Coordinators have specific duties for managing cooperative work. Controllers should be responsible for flelding Important events and also directing the work of others. Look for private responsibilities that are necessary to support public responsibilities. Even as you make general statements of responsiblties, you may think about how your objects might accomplish them. When should you focus on these details? As a matter of principle, concentrate first on what an object does for others. Once you've arranged these core, publicly visible responsibilities, reach for additional private responsibilities that support them. ur early attempts at characterizing our candidates naturally leads to ascribing to them certain, responsibiities. We can find more if we dig deeper. Consider a BankAccount object designed for the online banking application. Its a simple information holder. it has these public responsbbiltes: © Maintaining its current balance © Knowing recent transaction history © Knowing a displayable representation of itself (an abbreviated account number) ‘The fact that it needs to know a unique account identifier (used when using the backend bank {transaction services) and a currency (for representing balances and transactions) Is incidental to clients that use its public responsibilities. These responsibilities contribute to fulflling its public duties but aren't directly visible to clients Record responsibilities as you think of them. Make sure you are comfortable with your object's role in its community before you work out many details. If you know these detalls, you can record them. What's the best way to do this? ‘Should you get more specific with your responsibilty statements, or are there other options? Nalling these supporting responsibilities means the difference between a workable design and fallure. We live and dle by these details! Although they are as important to our design as any publicly visible responsibilties, don't get bogged down in them too soon. ‘Consider another example from the online bank: the design of an ErrorMessage object. This object holds onto specific error information and can translate errors into text in multiple languages. It is a pretty ‘smart Information holder. The request "Please translate this error into a human-readable message!" becomes a responsibilty to “construct an error message.” This high-level statement doesnt reveal how messages are formatted into different languages. We could refine our intial responsiblity “construct an error message" to read, "construct error message Ina specified language." Adding "format messages with specifi error parameters" Is even more specific. However, we can also revise our object's purpose to be, "An ErrorMessage represents a specific error condition in the system that can be displayed in a form readily understood by end users. User-readable messages are constructed from language-specific templates and include detalls about the spectic error. If we do this, the general statement "construct an error message" doesn't need to be overloaded with these detalls. We choose this option, leaving the responsibilty stated simply and lexpanding the purpose instead. Earlier, we mentioned that responsibllties are recorded on CRC cards along with a statement of purpose and a list of collaborators. Given the limited space on the CRC cards, you should use this real estate wisely. Make responsibilty statements as brief as possible. Convey necessary information by reworking and revising all parts of your object's, description. Don't pack everything into responsibilities. Record details in ways that let you remember them without creating clutter. Responsibilities come from examining relationships between candidates. Examining relationships between candidates can identity additional responsiblties. Objects can be related in complex ways: “composed of," "uses," ‘owns,” "knows about,” and "has" have very imprecise meanings in the English language. However, objects we tag as ‘structurers” nearly always have responsibilities for "maintaining" or "managing" objects they organize, whether we think of them as being "composed of,” "owning," "knowing," or “aggregating” those objects. UML has two very precise ways of modeling complex object structures: as composition or aggregation relations. Elements of a composite are stable, existing together over time; aggregates have somewhat looser tles. These are very precise distinctions that don't give us a clue as to responsibiities! What we want to determine is what related object Is responsible for knowing and doing on behalf of that relation. We say an object "has" another when it needs to exhibit some property related to having that object. Does a meeting have attendees? Yes. It so, what do we know about the meeting? Answer: the number of attendees. This begs the question, should we give a meeting responsibilty for knowing the attendees, or the attendees responsibilty for knowing thelr meetings, or both? Viewing a meeting as "representing a gathering of attendees at a location for a specific agenda” (a structuring role), we assign a Meeting object responsibilty for knowing all these things. Attendees dont seem to have much responsibilty on behalf of their relationship to a meeting, and they shouldn't! Attendees may keep a calendar (another relationship between the attendee and a calendar object) that notes meetings to which they have been Invited. We speak of *having a meeting” to go to, but that isnt fundamental to our behavior. When an object plays the role of a structurer, it organizes groups of objects. Because of this role, it likely has responsibiities for answering questions about the things it knows of. To make specific responsibilly assessments, we need to understand why a structurer exists and how its responsibilities change as its composition changes. Responsibilities may be associated with Important events during an object's lifetime. Some objects! responsiblilies are largely shaped by how they react. These objects are spurred to action by specific events. Controllers and coordinators fit this profile: most of the work they do Is in response to stimulus they Interpret. In the online banking application, a UserSession object was responsible for coordinating user requests. It walted for requests it could delegate to others, Most of its responsibilities were tied to these requests and the passage of time: © Know the users and thelr accounts Time user session activity Handle user requests by delegating them to appropriate service providers Report results back to the users Maintain a session summary Like clockwork, whenever a user request was recalved, the UserSession object would spring to action. I /would instantiate the appropriate service provider, ask it to do its work, report its results, and then idle, ‘waiting to be spurred by another request or the passage of time. If too much time elapsed before a request was received, It would drop the user session. Not all objects are so externally driven. Some react to internal changes. When an object is created and when itis no longer used are common places to find responsibilities for gracefully entering and leaving the scene. In most object-oriented languages, objects are notified of their Impending exit with a "finalize" notice, allowing them to release resources before leaving, ‘Amark of skilled designers who use a specific software environment is that they know about al the responsibiities that can be customized. Responsibilities may be assumed when an object fits into its technical environment. The responsibilities we hhave identified up to this point have been in support of required system behavior. We mention this source last because it yields responsibilities of a different nature: those required for an object to fit into its software context. As a designer, you don't invent these responsibilities but you must understand their implications. Quite simply, your objects won't function properly unless they take on these /mplementation-speaific responsibilities. Inheritance provides a mechanism for letting a form be customized in specified ways to fit with its environment: Superclasses can provide default implementations of responsibilities that can be freely overridden or extended by subclasses. Let's look at a Java class library example. Object is the name of the root class in the inheritance hierarchy. All classes are subclasses of Object, and thus all objects “get for free" implementations of responsibilities defined by Object. The Object class provides reasonable default implementations of these responsibilities. Some are expected to be overridden, To be compared to others of its kind or stored in a structurer, classes must support two responsibilities: answer whether one object is equal to another, and produce a value that can be used as an index into a structure that will store the object. Many more responsiblities could be redefined. Implementation-specific responsibilities shouldn't be your first concer. But if you know where your objects are headed, plan for them. iow rsa [revo |e] ive es in Strategies for Assigning Responsibilities We've presented you ways to search for responsibilties. Although all responsibilities are necessary, they are not of equal significance. It's best to spend time and energy assigning responsibilities to those candidates who will have the most dramatic effects. Although some objects may be central, they may not have interesting responsibilities. They may be important to begin with, but their importance quickly fades. Consider objects that are responsible for handing out work assignments to others. Although they are important, after they make work assignments they don't have much to do. thers may have intricate responsibilities that, although called on infrequently, are of critical importance. These objects need to be well designed for our application to be credible. ‘As you think through your design, what seems important may shift. Take a broad pass over the key aspects of your design and those important objects before assigning more detalled responsibilties. ‘Several points determine an object's stature and relevance: © What position does it play in the application architecture? (Objects that bridge between layers or coordinate others’ work have important responsibilties that knit our system together.) © How visible Is ito its surrounding neighbors? How visible is it to others outside its immediate neighborhood? (Visible objects may be important.) © Is ita central concept in the domain? (Objects that model the real world or that represent the work of our system can be important.) © Ave its services complex? (Complex responsibilities take time to pin down and may impact others.) © Does it make many decisions that affect others in its community? (itso, understanding these decision-making responsbiliies Is key to understanding how others will be affected.) © How many steps away from key decision makers is it? (The farther away, the less likely it Is to be a central player.) © Does it structure and manage relationships between others? (This Is important to know when you follow paths that lead to information and other objects’ services.) © How many others use and are aware of Its services? (This Is an Indicator of relevancy but not importance.) Look for high-impact objects, and assign them responsibilities that make them fit with their context. While you assign responsibiities to individuals, these assignments will Impact close neighbors. A responsibilty given to one object lessens the work of others. One division of labor may mean additional collaborations; another, fewer. No object is ever designed in Isolation. When deciding what an object's primary obligations are, ask the following: © What does each object offer as services to others? What information does It provide to others? (These are its public responsibilities.) © What actions does it take in support of these public responsibilities? (These are its private responsibilities.) Recording Responsibilities AAs we stated ear, we create a CRC card for each candidate (see Figure 4-1). When you do this, write the name ot each candidate on the cards, one per card. On the unlined side of the card, state the candidate's purpose and stereotypes. Note anything else you think may be Important to remember about that candidate: questions, concerns, or ideas, Figure 4-1. The unlined side of a CRC card Is for listing the candidate's name, purpose, stereotypes, and other Important notes. a specialized destination ~ EmailAddvess 7 Forpoce: An E-mailAdldrecs aggregates two of the elements of an STMP e-mail meccage header: the to address, and the from address, It algo knows information abovt both the gender and the receiver tb ues luring. guessing. Role: Destination shaved! Patterns: Compocitelesf application specific role Stereotapes: Information Holder, Service Frovider different stereotypes its role in the Composite pattern Keep a working list of unassigned responsibilities. Periodically work at assigning them to existing or new candidates. Keep a running list of unassigned responsibilities so that they don't have to stop and figure out everything at once. (On the lined side, again write the name ofthe candidate (see Figure 4-2). Draw a horizontal line that divides the card into two uneven parts: responsibilities on the left, and collaborators on the right. Figure 4-2. The lined side of a CRC card Is divided roughly two-thirds for responsibilities and one-third for collaborators. EmailAddress Knows alias of receiver Mailer Knows signature. of sender UcerFrofile Knows SMTP address info Sende a message, what it knows what it does collaborators Figure 4-3. Write unassigned responsibilities on Post-it notes that can be “assigned” when you Identity the appropriate candidat Notify administrator of mescazes that conuct be. cout Corn t vE eT If you insist on using a computer, don't be lulled into thinking your candidates are well formed because typed responsibilities look neater. At this stage, exploring options should be fun, easy, and low-cost. Making Initial Assignments Choose those objects you deem central players and concentrate on them firs. Expect to work on more than one object ata time. Here are some ways to selec a cluster of candidates to work on. We expect that you'll march through your candidates several times, tackling one group at a time: © Candidates that represent domain concepts Candidates that participate in a certain use case Candidates that support an application theme Candidates that interface to the outside world Look for responsibilities that fit each candidate's primary role. A well-formed responsibil is a high-level statement of what an object knows or does. Make broad, encompassing general statements of responsibilities. Don't express responsibilities as Individual attributes or operations. To start, state responsibilities generally. Responsibilities are best stated at a level above Individual attributes or operations. Don't get overly specific in your statements. A statement of responsibilty, if worded generally, can encompass many specific requests. There may be 10 ways to ask for tax calculations that are covered by the statement "Calculate all taxes based on locale.” There isn't enough room on a CRC card to record very many detalls. These lower-level details belong in an information model or some other, more precise description, Use CRC cards for high-level descriptions. For example, say a Customer object has a name. That name may comprise a first name, sumame, middle name, and maiden name; there may be aliases or nicknames. Dont state each of these as Individual responsibilities. Write one general statement that covers all cases: Say that a Customer "knows its name and preferred ways of being addressed." Don't say that a Customer "knows first name," ‘nows last name,” "knows nickname,” "knows tile,” and so on. Besides overflowing the card, this is far {too much detail If you are worried you'll forget detals, jot down hints on the card that will help you remember them as you work: "Knows its name and preferred ways of being addressed (e.g., ttl, nicknames, etc.)". Space on cards is limited, so use it wisely Find the right level of description. How many responsibilities do you need to shape an object's character? Responsibilities can be tersely worded or slightly more descriptive. Its a matter of personal and team style. You can bbe more or lass brief, ust as long as you and your teammates understand one another. ‘The more broadly you state responsibilities, the fewer statements you need, Your statements of responsibilities should be understandable with only a small amount of context setting. Let's look at the responsibilities for the Model-View-Controller roles as presented in the book Pattern-Oriented Software Architecture (John Wiley, 1996), or POSA to see how they are worded, |The Model-View-Controller framework was first introduced in the Smalltalk-80 programming environment. MVC divides an application into three areas: the Model, which represents something in the| ‘domain; a View that displays information to the user; and a Controller, which receives input, usually as, events. Events are transiated to service requests to either the model or view. An application can be constructed with many different objects playing model, view or controller roles. To be displayed in a View and manipulated via a Controller, an application-specific object needs to assume the responsiblities of a Model object. One Model object can be displayed in multiple views, Let's now look at statements of responsibilities for each of these roles: Model ‘© Represents an application-specific object that can be changed or viewed © Registers dependent views and controllers, © ‘Notifies dependent components about changes in state View © Creates and initializes its associated controller © Displays information to the user © Implements the update procedure © Retrieves displayable information from the model Controller © Accepts user input as events © Translates events to service requests for the model or to display requests for the view © Implements the update procedure, If required These responsibility statements are fairly broad. They don't state the detalls of update notification, how or what kind of information is displayed, or the pattems of collaboration between these roles. Responsibilty statements in POSA are chattier than those found in Designing Object-Oriented Software (DOS) (Rebecca, Wirts-Brock, Prentice Hall, 1990), the earllest book in which responsibilities were extensively used. Here Is an example from It: Here are how the responsibilities of a Document (a kind of model that holds onto the contents of an editable document) and a Display Frame (a view on a portion of a document) were stated: Document © Access and modify elements © change the attributes of the elements © Copy portions of itself © Maintain the style ofthe first page © Knows its views © Knows its target © Knows its name © Inform views of changes DisplayFrame © Displays itsett © composes itseit © Knows its contents © Knows its bounding box ‘The POSA descriptions are complete statements; the DOOS responsibilities are terse, and more specific. Model-View-Controller responsibilities are more broadly stated because they describe roles that can be taken on and ‘adapted by application-specitic objects. The responsibilities of a Model are general: in contrast, the responsibilities of ‘a Document (which assumes the role of a Model) are specific to its distinct purpose. We expect objects, such as Document and DisplayFrame, to be explained more concretely than generalized roles. This brings up an important consideration. The more concretely you've been thinking about your design, the more likely you are to make specific responsiblity statements, When describing a general role that can be assumed by many different kinds of objects, you can't get very specific. The more general a concept, the more general its responsibilities. The more specific a concept, the more specific its duties. Use strong descriptions. An object can seem Il defined if Its responsiblties seem hazy. Behind a wall of vagueness can lie details that should not be ignored. Avoid weakly stated responsibilities if you can find stronger, more explicit descriptions, Daryl Kulak and Eamonn Guiney, in their book Use Cases: Requirements in Context (Addison-Wesley, 2000), caution against giving use cases weak names. They suggest that more concrete verbs make for less vague use case names. If you use weak verbs, it may be because you are unsure of exactly what your use case should accomplish. The same principle applies to naming responsibilities for actions. The more strongly you can state a responsiblity, the less you are fudging, In|Table 4-1 contrast the stronger verbs with the weaker ones. Table 4-1. Use strong verbs to state responsibilities. Strong Verbs Weak Verbs remove, merge, calculate, credit, register, _ organize, record, find, process, maintain, debit, activate list, accept Of course, there are always exceptions to the rule. A weak-sounding phrase may have specific meaning in a certain context, In this case, don't look for a stronger term, Listing a property has a very specific meaning in the real estate business: It means to put a property on the market for sale, Be opportunistic. Thinking about one object leads to thinking about others. When considering an object's public responsibiities, you think about why its clients need to call on these services and what they are ultimately responsible for accomplishing. When you look at a single responsibilty, you think about how it might be accomplished. This shift of focus is good (as well as hard to avoid). You test the fit of an object to its context by looking at both its use and its effects on others. If you hop around too much, however, you might leave an object before you have a firm grasp of its responsiblities. To avold this, take a first pass at an object's major responsibilities before moving too far away from it. Decide how an object will divide or share the work of a large or complex responsibility. An object has three options for fulling any responsibilty. It can either © Doall the work itself © Ask others for help doing portions of the work (collaborate with others) © Delegate the entire request to a helper object. When you're faced with a complex job, ask whether an object is up to this responsibilty or whether itis taking on too much. A responsibilty that fs too complex to be Implemented by a single object essentially introduces a new sub design problem. You need to design a set of objects that will colaborate to Implement this complex responsibilty. These objects will have roles and responsibilities that contribute to the implementation of the larger responsibilty. At this point we're not asking you to make detailed decisions about how to design specific collaborations between these objects, only that you think through your options for assigning subresponsibilies. I a responsibilty seems too big for one object, speculate on how you might break that responsibiliy into smaller logical chunks. These can be given as work assignments to other objects. Pursuing this line of thinking may lead you to new candidates with smaller, more tightly focused roles. ‘Make sure an object isn't doing too much. If you find an abject with a long laundry list of responsibilities, this could Indicate one of two problems: Either you are stating its responsibilities in too much detall, or itis taking on too much. It Is easy to rewrite responsiblities at a higher level. ‘An extreme example of a "big object doing too much" would be a design in which a single object Implemented all responsibilties of an application. This Is obviously a poorly factored design! However, if your object is too busy, consider spilting it into several smaller ones that will work together on the problem. Expect these objects to collaborate with one another. Although it may require more study before you obtain an overall understanding of this new system of objects, distributing the work among a number of objects allows each object to know about relatively fewer things. It results in a system that Is more flexible and easier to modity. Keep behavior with related Information. if an object is responsible for maintaining certain information, tis logical to assign it responsibiltias for performing any operations on that information. This makes the object smarter; not only does it know things, but also it can do things with what it knows. Conversely, if an object requires certain information to do its job, itis logical (other things being equal) to assign it the responsibilty for maintaining that information. In this \ay, If the information changes, no update messages need to be sent between objects. In banking, Account objects can have more or less behavior. By giving them responsibilties for knowing {the rules of adjusting thelr balances, we turn them from simple information holders to hybrid information holder/service providers. I these resposibilties were assigned to some controller object, such as a FundsTransterTransaction object, it would mean separating the rules for changing account balances {rom the Accounts themselves Distribute system intelligence. A system can be thought of as having a certain amount of inteligence. The sum of a system's inteligence is what it knows, the actions it can perform, and the impact it has on other systems and its Users. Given their roles within a system, some objects can be viewed as being relatively "smart," whereas others ‘seem less so. An object incorporates more or less intelligence according to how much it knows or can do and how ‘many other objects It affects. For example, structuring objects such as sets or arrays are usually not viewed as particularly intelligent: They store and retrieve objects but have relatively litle Impact on the objects they store or any other parts of the system, Other structurers can be more intelligent. They have responsibilities not only for ‘maintaining their contents but also for answering questions about them collectively. Objects with responsibilities for controling activity can be more or less inteligent, depending on how much work they delegate and how much they know about the work of those they manage. Guard against the tendency to make controllers too intelligent. We prefer to give the collaborating objects as much responsibilty as they can handle. The ‘more intelligent controllers are, the less intelligent are those that surround them. If you place too much responsibilty Ina controller, you lose design flexibility. Our goal isn't to evenly distribute inteligence but to give objects those responsibiities they can handle. (Our decision to make Account objects know the rules for adjusting their balances lets us design a FundsTransferTransaction control object that fs concemed only with coordinating the transfer, handling errors, and reporting results. Keep information about one thing in one place. In general, meeting the responsibilty for maintaining specific Information is easier if that information isn’t shared, Sharing implies a duplication that can lead to inconsistency. Part of making software easier to maintain Is eliminating potential discrepancies. if more than one object must know the same information to perform an action, three possible solutions exist: © Anew object could be created with the responsibilty for being the sole repository of this information. This Information holder would be shared among those who have a "need to know." © ttmay be thatthe information "its" with the existing responsiblites of one of the existing objects. In that cease, It could assume the added responsibilty of maintaining the information. Others could request this Information when they need I © It may be appropriate to collapse various objects that require the same information into a single object. This ‘means encapsulating the behavior that requires the information into a single object and obliterating the distinction between the collapsed objects. Sometimes we go overboard, factoring out responsibilities into roles that are too small. In that case itis better to pull them back into a single, more responsible object. ‘Just because a customer's name appears on an invoice doesn't mean that the Invoice should "know the ‘customer name.” When it comes time to print, it can "know the customer" and collaborate with it by asking for the name. ‘Make an object's responsibilities coherent. They should all relate in some way to the overall role of the object. An object as a whole should be the sum of its responsibilities. These responsibilities should complement one another. Everything an object knows or does should contribute to its purpose or ft into your design model. If certain responsibiities seem unrelated, they need to be reassigned, Especially insidious are responsibiities that seem slightly tangential to an object's purpose. Restrict an object's responsibilities to a single domain. Mellir Page-Jones inFundamentals of Object-Oriented Design in UML (Addison-Wesley, 1999) introduces a way of dividing a software system (and the objects that live within it) Into domains. Domains are Page-Jones's way of dividing the machinery of an application into different contexts. According to Page-Jones, objects that live in lower domains shouldn't have responsibilities that tle them to objects in a higher domain. The more you tie objects in a lower domain to a higher one, the harder itis to reuse them In different contexts, Page-Jones's divisions (from higher to lower level domains) are as follows: © Application: objects valuable for one application © Business: objects valuable for one industry or company © Architectural: objects valuable for one implementation architecture © Foundation: objects valuable across all business and architectures Foundation objects are further divided into three categories or subdomains: © Fundamental: objects so basic that many programming languages include them as primitive data types, such as integers or reals © Structural: objects that organize others, such as sets, collections, hashtables, or queues © Semantic objects: objects that represent basic concepts with specific meaning, such as date, time, or money To test whether two different objects are in the same domain, ask, "Can one object be built without any knowledge of the other?” If so, these two objects aren't likely to be in the same domain. But there are stil places where you could tangle domains if you aren't careful—for example, when you need to convert from one type of object to another. Typically you are not free to add responsibilities to foundation libraries, They come from the vendor with all kinds of warnings and prohibitions. You are prevented from tinkering with them. But you may be able to extend these classes by creating new subclasses. Where should you place responsibilties for converting a temperature reading into a measurement or {trom one geometric shape to another? Measurements are readings (of temperatures, among other things) recorded at a particular time and for a particular instrument and location. A Temperature represents a degree of heat or cold on a definite scale. We can envision Temperatures existing without Measurements, so Temperatures are in a lower domain. It is OK for Measurements to have the responsibilty for "knowing their temperature." But don't give Temperatures the ability to conver to highet lite forms. This doesn't overburden Temperatures with higher-level duties. If you follow this advice, Temperatures can readily be used in other contexts. If they did know about Measurements, you'd have {to drag along Measurements to any new context. Avoid taking on nonessential responsibilities. Avold diluting an object's purpose by having It take on responsibiities that aren't central to its main purpose. Taking on responsibilities is easy to do, especially when you're deciding who should be responsible for maintaining a relationship. The obvious first answer Is to make one or the other, or both, related objects be responsible Reuse isnt our only concer. For maintenance reasons, clear intent is paramount: Objects shouldn't take on responsibilities that go above and beyond thelr specific purpose. When an object does favors" for others, its role becomes obscured. ‘Consider adding the responsibilty to a Person object to know how many dogs It owns. If we're building ‘an application that handles dog show registrations, this might be reasonable. But f our Person could own cats, birds, gerbils, treasury bills, automobiles, life insurance policies, and so on, we could quick’y pile on responsibilities for "knowing" all these things. This multiowner Person isnt useful in any other context because It is encumbered with a varlety of responsibilities and links to al those other objects. |The Person object becomes the pathway to these other objects and tends to pile on responsiblity after responsibilty after responsibilty. In one design we reviewed, a Person object had more than 500 methods (and way too many responsibilities)! A better solution Is to factor those responsibilities that aren't intrinsic to a Person into distinct objects. The easy frst answer isnt always the best. Each new responsibilty needs to be considered carefully. Itis easy to "slip one in’ as an easy solution and avoid thinking through the consequences. An object that has a lot of links to thers will be harder to maintain and move to a new context. Even if you are building only one application, avoid big, fat objects. There are always reasonable alternatives. Instead of burdening elther object in a relationship, consider creating a new object that is, responsible for structuring the relation. Consider creating a new object that is responsible for structuring the relation between people and dogs, another for people and valued property, and so on. Each of these new objects knows of a specific relationship. Instead of one big object knowing many others, the net result is a few simpler objects, each knowing some specitc relationship. This is one way to “straddle” objects in separate domains. It results in a trimmer Person, unburdened with responsibilties that aren't intrinsic to its nature. Of course, this, too, can be carried to extremes. Too many objects with responsibiities to "glue" others together can also make a design britie and hard to understand. Decide what relations. are intrinsic to an object in the context of your application and which are not. Assign responsibilities for maintaining ‘nonessential relations to new structurers. Don't overlap responsibilities. Sometimes you aren't sure which object should check, guarantee, or ensure that things are done the right way. Who should ultimately be responsible? If you want a robust system, you must make your objects and neighborhoods resistant to careless mistakes and errors. ‘Should you make the client check before it calls on the services of another? Should you give service providers responsibilities for checking that thelr requests are properly formed? If you're not sure whom the clients are or under what situations a responsibilty will be carried out, you might be inclined to putin safety checks everywhere, If we followed this strategy in the design of physical objects and systems, we would design teakettles ‘with responsibilities for notifying when their contents boll, we'd give monitors responsibilty for checking ‘water contents of the teakettle, we'd ask the person who filled the teakettle to determine whether the kettle is boiling, and we'd put safeguards into a stove burner so that when it detects the kettle whistling {or a period of time, itd reduce its temperature. This line of reasoning leads to overly zealous objects, all of them fretting about the state of the system. It can be extremely costly to maintain such a complex system of objects. You are better off developing a simple, consistent strategy for checking and recovering, and sticking with that. Not everyone needs to be involved or "share in an Important responsiblity.” It you want an object to be impervious to malicious requests, give it responsibilities for detecting and deflecting them. (Once you've given an object that responsibilty, design its clients to be more cavalier; they need only react to bounced requests, not prevent them. We will return to this topic when we design collaborations. But for now, consider that when you give one object a responsibilty, you are potentially relieving the workload of another. Itisn't necessary to bulld in overlapping responsibilities unless your system explicitly demands redundancy. Getting Unstuck Even with the best of intentions, you can spin your wheels, unable to come up with convincing responsibilty assignments, Relax and take a deep cleansing breath. Here are some common “sticky problems" and ways to move beyond them. Problem: You have a big responsibility that doesn't seem to belong to any candidate. Who shouldbe responsible for solving world peace or ending world hunger? There aren't simple answers because these are extremely broad problems. If you really wanted to tackle world peace or hunger, you'd have to break these enormous problems into smaller factors that, i solved, might contribute to lessening friction or reducing hunger. Divide a big problem into smaller problems, and solve those. Big software responsibilities can seem equally daunting to those tasked with solving them. What object should be responsible for “interacting with the user" or "performing business functions" or "managing resources" or “doing the work"? If a responsibilty seems too big or too vague, break it into smaller, more specific ones that can be assigned to Individual objects. Treat the “big responsiblity" as a problem statement and reiterate through identiying specific objects with smaller responsibilities that add up to the larger responsibilty Problem: You don't know what to do with a vague responsibility. if you can't get more concrete, perhaps you are trying to add precision to a statement that Is so general that you can’t get any traction. You don't know enough to break it down into subparts, Before you can design a solution, you may need further definition from someone who knows more about the problem than you do. I's always fair to ask, "Can you be more specific about what you mean by performing business functions?" If you are lucky, your statement may not really be a problem at all. You may already have assigned specific responsibilities that are subsumed by a broad unapproachable statement. "Interacting with the user” may simply not be something you have to deal with if you know where responsibilities for “redisplay up-to-date chart information on a periodic basis,” "know chart viewing parameters,” and "perform request to ..,” "calculate..." “display archived charts ...," responsibilities are covered. I so, relax. You've assigned specific responsibilities; your job is finished. Problem: You can't decide between one of several likely candidates. Sometimes it isnt obvious which candidate should be assigned a specific responsibilty. When you're choosing which of several objects to assign a responsibilty, ask, "What are all my options for assignment? I | choose this possibilty, what does that imply for its surrounding neighbors?" If you have trouble assigning a particular responsibilty, the solution is simple: Make an arbitrary assignment and walk through the system to see how it feels. There isn't necessarily a single “right” answer. Don't get Ina jam thinking that you must optimally solve the problem or that there Is only one optimal assignment. There may be several, or none. Assign a responsibilty to one object, and then follow through with how this affects others. Ifit seems reasonable, stick with it. Feel free to play out several options before making a final decision. You can always change your mind, Assignments will be revised and adjusted as you get deeper into design. ‘Should a Session be responsible for timing itself, or should the SessionManager do so? There may be reasons for both alternatives. The SessionManager could adjust the session times based on overall system performance. Well, each Session could react to changing system performance characteristics ‘querying the SessionManager before deciding to time out. Well, sure. Both seem workable. How can jyou decide? You can try several different approaches to distributing responsibilities. Look at how different responsibility assignments impact objects in the neighborhood. Problem: You have trouble assigning a specific responsibility. You may get stuck on a responsibilty that seems to be reasonably stated but has nowhere to go. This could mean that you are covering new territory and may need to invent a new candidate. Great! This is progress. Or it could be that even though the responsibilty is specific, your existing candidates’ responsiblities are stated at a higher level of detall. If so, remember that responsibilities are general statements; what you think of as a specific responsibilty you have trouble assigning may actually be an Implementation detall that doesn't really belong on a CRC card, If so, save It for later. Problem: You are worried about how a responsibility Is actually going to be accomplished. You've stated responsibiities generally, but you have nagging doubts. How will each object carry out its duties? Are you concerned because you suspect that something is missing? If so, follow your instincts and figure that out. Are you a stickler for details? Until you see running code, you never believe a design will work. If so, relax. Your design Isn't finished quite yet. And it will change as you design collaborations, too. Once you are comfortable with how you've arranged responsibiities among a set of collaborators, then you can pin down responsibilties to a specific implementation. A responsiblily for maintaining knowledge could mean that © The object holds on to the fact directly. © ‘It could derive it from other information sources. © When asked, it tums around and collaborates with another that can compute (and Is responsible for reporting the results to others). Responsibilities do not dictate any specific Implementation. When we say that an object maintains certain knowledge, we aren't stating that it stores it directly as data {At this point, all your options are open. Stating that a Monetary-Transaction "knows its applicable taxes" could mean that it stores its taxes directly in variables or that, when asked, it turns around and delegates this request to a tax calculator object that does all the work. We don't have to decide these things just yet. In fact, until we know our candidates and all the dimensions of the problem better, we don't know enough to make informed decisions about how "knowing" responsibilities are best implemented, ‘eis nn ive es in Implementing Objects and Responsibilities ‘Sure, we're fudging a bit. We have written responsibilities on index cards, but we haven't yet decided on an Implementation—although we may have a pretty good idea. So far, we have Identified candidate objects or roles (or both). We have also characterized our objects and stereotyped thelr role. We have made no Implementation decisions. This shift between objects and their possible implementation in classes and interface specifications Is an important one. When you make this shift, you have options. There isn't necessarily a one-to-one correspondence between a candidate and a class. An Object Can Play Multiple Roles Let's review how objects and roles are related. This will help us specify Implementation classes and interfaces. An object can take on one or more different roles. We distinguish roles as being one of the following: © Primary: comprising of responsibiities that clearly define an object's main purpose and its character © ‘Secondary: comprising of responsibilties that are incidental to an object's purpose but necessary for it to fit Into its environment of technical libraries, frameworks, and application-specific conventions When you make the transition from candidates to an implementation specification, you will create abstract and concrete classes that implement your objects’ responsibilities. An abstract class provides a partial Implementation. It leaves Its subclasses with the obligation to implement specific responsibilties. A concrete class provides a complete Implementation. You are also likely to specify interfaces for responsibilities that can be implemented by different classes. An interface specifies method signatures without specifying an implementation. It defines the vocabulary clients use to invoke responsibilities, regardless of their implementation. Abstract and concrete classes are the bullding blocks we use to specify an implementation. Declaring Interfaces is one means to make It more flexible and extensible. Implicit in the dectaration of an interface Is the design idea that a single role can be carried out by several types of objects, regardless of their implementation. When you suspect that a role might be played by different kinds of objects, declare an interface. Do so even if you intend to implement a number of classes belonging to the same Inheritance hierarchy. This makes it clear that your abstract and concrete classes are just one possible Implementation and that others may be declared in the future without being constrained to a specific ancestry. It makes clients who use objects that support this interface more flexible, too, They needn't know about specific classes In order to use objects that share a common role declared in an interface. Certain object-oriented languages, such as C++ or Smalltalk, do not support the construct of an Interface. For these languages, you are likely to declare the common methods in a class that can be Inherited from, in lieu of defining a common interface. ‘An object can have multiple roles. But f you've kept your candidates on the narrow path, each most likely only one role, Each is what itis and does what It does. The mapping from candidate to Implementation is. straightforward: You define a class to Implement each candidate that supports a single primary role. Following this guideline, we'd declare a BankAccount class to implement our BankAccount candidate, ‘with these responsible: © Maintain its balance © Know its customer © Know is unique ID © Know recent iransaction history © Know a printable representation of its 1D |The BankAccount class may pick up additional Implementation responsibilities to fit into its software context. If we implement a BankAccount class in the Enterprise Java Beans framework, our BankAccount might take on the responsibilties required of EntityBeans: © Know its context © Initialize itselt © Retrieve and store itself from a database © Activateipassivate itself when asked to by the container These are deciared in the EntityBean interface that our BankAccount class implements. We also might alter our class's name from BankAccount to BankAccountBean, just to make it clear that it fits into the: J2EE framework, [The roles an object can play can be framework- and technology-based or domain-specific. Interfaces ican also be domain-specific or technology-based abstractions. For example, if we wanted fo push a bank account object in another, domain-speoitic direction, we might declare it to be a FinancialAsset. A FinancialAsset is a role that represents something held by the bank that has a projected and current valuation. CertiticatesOtDeposit and MoneyMarket Accounts are other examples of FinancialAssets. We| could declare our BankAccount candidate to assume this secondary role and adjust its implementation represents accordingly. A class implements responsibilities that are intrinsic to the roles its objects play (see Elqures 4-4 andi These can be application-specifc or technical. Consider technical roles after you're confidant about your application-specific design and have decided on an implementation strategy. Figure 4-4. A BankAccount candidate Is the sum of Its one primary and multiple secondary roles. Financialccet BankAccount Knows rts customer Knows its wigue ID Knows its transaction history Maintains its balance three roles Figure 4-5. TheBankAccountBean class represents three roles. To sharpen your role modeling skills, go to your favorite class libraries and reverse-engineer some Interfaces and classes into one or more roles, each with clusters of responsibilities. Designing Methods and Signatures That Support Responsibilities Objects may know and do similar things, but because they do them differently, they require different interfaces and Implementations. When you look for what is in common, you need to look below the surface. You want to discriminate among that which is in common and will be implemented identically, that which is common but requires a different implementation, and that which appears to be in common but isnt. ‘Sharpen your focus and ask, "Are these really the same responsibilty? Do they mean the same to clients?" Let's look ata simple example to see how responsibilities that seem common might be implemented, (Consider these two candidates and their responsibilities: Rectangle © Knows how to draw itself © Knows its dimensions Circle © Knows how to draw itself © Knows its dimensions We expect circles and rectangles and other graphic shapes to be asked to draw in the same way (their clients can draw them interchangeably if this is the case, even though the way they draw themselves differs). But what about their dimensions? A circle can be described by Its radius; a rectangle, by its |width and height. Both kinds of objects know their dimensions. But they have different ways of defining them, We expect clients to change and inquire about them differently. Circle and rectangle will have distinct methods that implement this responsibilty We could restate each responsibilty to be explicit: A rectangle "knows its width and height," or a circle "knows its radius.” But we won't. As a natural consequence of getting more precise, you create different Interfaces and implementations. Instead of patching up cards with this new precision, leave this to \detailed design and to class and interface specttications. At one level of abstraction, circles and rectangles do share a common responsibilty to "know their dimensions.” Because they do so differently, different classes will Implement them. iowa an ive es in Testing Your Candidates’ Quality Responsibilities are general statements that describe software objects and the actions they take, the information they ‘manage, and the decisions they make. When you spread responsibilities around among object neighborhoods, make sure that each object keeps to its task and doesn't demand too much or take on responsibilities better assigned to others. The quality of a form can be tested by how well it it into its context. Here are some ways to test whether an object is well formed: © Does it stick to its purpose? © Are its responsibilties clearly stated? © Dots responsibilities match its role? © Is itof value to other objects in its neighborhood? Itis relatively easy to remedy one object's flaws and make it a better fit. It you have created an all-knowing, all-doing object with too many responsibiities, carve it up into several cooperating ones. If an object Is responsible for ‘maintaining information, reassign it the responsibilty for performing any operations on that information. if you've dispersed responsibilities, consider consolidating them, Itis somewhat more difficult to adjust the responsibilities of several objects. If you have scattered related information across several objects, you may want to integrate this information in a single object. When you design a software application, you are inventing systems of objects. Not only should each ft with its software context, but also objects within natural partitions should work well together. You are bringing communities of objects into existence. The quality of a design can be proved only by how well it stands up to its complex requirements over time. Some designs are better than others. If every part Is connected, then itis hard to limit the effects of change. So itis better to Isolate parts—to identity subsystems of objects—and establish patterns of communication between them. Each subpart should have a coherent role; obligations shouldn't spill across different areas. This speaks to the heart of encapsulation, which states that ike things belong together. Although each object has a distinct part to play, object neighborhoods collectively take on larger, related responsibiities. They, too, have larger roles to play in the application. They, too, should be coherent wholes. You need to consciously organize and design how objecs i lfferent parts of your system interact. nfohapter | we discuss how to develop a model of objects and their collaborations. Tews [rss |e ive es in Summary Objects do things, know things, and make decisions. In this sense, they are responsible. Their responsibilities come from your ideas about how your software machinery should work. Objects shouldn't do too much or too little. They should stay in character. A good test of whether an object is well formed Is that its responsibilities form a cohesive Unit, Does it stick to its purpose? Are its responsiblities clearly stated? Do they match its role? Whether an object primarily knows things, does things, or controls and decides is based on its role stereotype. Exploring an object’s character will lead to an intial set of responsibilities. Information holders answer questions and. are responsible for maintaining specific information. Coordinators have specific duties for managing cooperative work. ‘Service providers fleld requests from others. Requests can be restated as responsibilities for performing specific services, To come up with responsibilities, you will need to reformulate software descriptions into responsibilty statements, This process can be more or less direct. Most of the time you will need to get more specific and concrete to identity responsibiities that can be assigned to individual objects. When responsibilty statements seem too broad, create ‘smaller duties that fit with an object's role. As you find and assign responsibilities, you will make choices about how individual objects contribute to the overall working of your application. Although each object has a distinct part to play, it full its responsibiities by interacting with others. So your model won't be complete until you understand how objects collaborate. iow rsa [revo |e]

You might also like