How does Design get done on an Agile Project? Jeremy D. Miller Nov 27, 2007 Agile and Software Design • • • • • • • • No Big Design Upfront! Is Design Dead? You’re coding without knowing where you’re going? How is this “Agile” stuff responsible? What does it mean to “design continuously?” How does Agile impact the makeup of the team? How do we make this work? When do we have to design upfront? Scenario 1 A Software team is building a new ASP.NET application with substantial business logic and processing. Do you: 1. Create a web service for the business logic and make the web application call this web service 2. Build and deploy the business logic in process with the web application Value Proposition of Agile (or Lean) • • • • • Return on Investment Early and continuous feedback Capitalize on learning Flexible delivery options Sustainable development Work Vertically by Feature • Design vertical slices of deliverable functionality • All design work should be traceable to immediate business need Includes architectural infrastructure “Pull” Design versus “Push” Design • Minimize rework by integrating early Test early User feedback early Deployment feedback early Shorten the time between doing and verifying Keep It Simple • The Simplest Thing that could Possibly Work What does “work” mean? What does “simple” mean? • YAGNI – “You aren’t gonna need it” Build only what you need right now The simple solution may be enough Easy to add complexity, hard to remove it Scenario 2 The new software system requires access to a set of reference data. This data is fairly static and small to begin with, but will grow much larger in 9 months. Do you: 1. Build in caching right now 2. Make the access directly to the database 3. Just store this data in a file The Last Responsible Moment “…delay commitment until the last responsible moment, that is, the moment at which failing to make a decision eliminates an important alternative. “ – Mary Poppendieck Decide when to Decide • Make decisions at the right time • Utilize continuous learning • Think ahead, yes! Act ahead, no! Don’t act on speculative design Keep a queue of design ideas and possible refactorings • Don’t go past the Last Responsible Moment Be cognizant of outstanding design decisions Some decisions have to be made earlier than others Delay commitment and complexity • Simplicity is hard • Possible effects of abstractions Reuse of code and easier development Unnecessary complexity Changes are more difficult • Avoid “Architect Hubris” If we just build the framework upfront, coding will be easy… • Harvest Abstraction Make any abstraction earn its existence Reversibility “If you can easily change your decisions, this means it's less important to get them right - which makes your life much simpler. ” - Martin Fowler The Limits of Reversibility • Dependencies on external teams or external experts • Publicly published interfaces • Again, decide when to decide! Designing for Reversibility • Orthogonal Code Separation of Concerns Cohesion Coupling • The Single Responsibility Principle “A class should have only one reason to change” • Open Closed Principle • Don’t Repeat Yourself Principle (DRY) • Testability Maximizing Evolutionary Design • If possible, only divide teams by feature Externally facing API’s are NOT reversible • • • • Be Cautious when building Frameworks Persistence Ignorant Domain Models Delay the Database Model Presentation / Behavior Separation in the User Interface Design Together • • • • • • Socialize the design Know the why Collectively challenge the design every day Talk about the design Keep the team abreast of changing design strategies The “This is the way we do it” moment What do I use for Design? • • • • • • • • • • Design Principles Design Patterns Test/Behavior Driven Development Responsibility Driven Design (CRC cards) Code Smells Refactoring Pair Programming Whiteboard UML Design Notebook Say yes to modeling, but… • • • • Travel light Don’t create any incentive to keep a bad design Do it together Expand your intellectual toolbox UML CRC cards ERD ??? • Use precise terminology • Stop modeling the second you stop learning Feedback • • • • Any Design is theory until proven “Bubbles don’t crash” Analysis/Paralysis If you don’t know what to do next, Spike It! Refactor Relentlessly • Design reflectively • The quality of a design is largely the accumulative sum of many small decisions • Clean the dishes after cooking Bad names Duplication Big classes or long methods • Software entropy is the enemy! Think and Do • • • • • • • Code’n Go == Chaos The Design Hat never comes off The Will to Design Design and coding are conjoined twins Use solid design principles as you code Put design strength at the point of attack Sustainable efforts require good designs Questions and Discussion • The Shade Tree Developer – http://codebetter.com/blogs/jeremy.miller • jeremydmiller@yahoo.com Do One Thing at a Time • The Single Responsibility Principle “A class should have only one reason to change” One class, one responsibility An expression of cohesion Example: The Blob Class Example: SingleResponsibilityPrinciple Open Closed Principle "Software entities should be open for extension, but closed for modification.“ - Robert C. Martin “…the essence of the Open/Closed Principle is being able to add new functionality to an existing codebase by writing completely new code with minimal modification of existing code. ” Don’t Repeat Yourself “…every piece of system knowledge should have one authoritative, unambiguous representation. Every piece of knowledge in the development of something should have a single representation.” The Pragmatic Programmers • • • • Eliminate duplication Improve cohesion I only want to tell you this once! Example: DRY out Session Test Driven Development “[Test Driven Development] gives you this sense of keeping just one ball in the air at once, so you can concentrate on that ball properly and do a really good job with it.” - Martin Fowler on TDD Make your code easy to test “I don't care how good you think your design is. If I can't walk in and write a test for an arbitrary method of yours in five minutes, it’s not as good as you think it is, and whether you know it or not, you're paying a price for it.” Michael Feathers Isolate the Ugly Stuff • Some things are hard to test • Ugly Stuff == Inconvenient while unit testing The Database Active Directory Web Services Messaging • Model View Presenter as an example The actual user interface is hard to test Use Model View Presenter to decouple code from the user interface machinery • Dependency Inversion Principle Code to the interface, not the implementation Expand the Creamy Center Graphic from Jay Flowers Push, Don’t Pull • Example: When is now? • Inversion of Control Don’t call me, I’ll call you Example: The Translator Database Mapper • Dependency Injection “new()” is a form of tight coupling Example: Constructor Injection Test Small Before Testing Big • Code from the bottom up • Oh no! How do all these pieces fit together? Don’t care (for now) What do you know how to do? • Short term value proposition of TDD: Save more time in debugging than you spend in unit testing Example: Supply Chain Routing • Determine the best way to route requests from the factory lines for parts • Correlate data from three different sources of information into “shelves” • Apply a complex series of business rules against the data to select the best part channel (part, inventory source, and factory line destination) Keep a Short Tail • Can you get there from here? • Aerosmith and Roadies • Test by Measuring What You are Trying to Test! Example: InvoiceScreenCreator • Isolate the Churn • Whenever you can, keep the database on the sidelines Establish a Maintainable Software Ecosystem • • • • Change enablers Feedback loops Test automation Continuous Integration