In agile you want:
- ROI
Good enough design
make best design possible, but don’t spend years on it* flexible delivery options
customer doesn’t know what they want
- they learn as the project goes
- be able to make a complete turn in the code base
- move low priority features to the end – this can save a project* sustainable development through maintainable code
Do one thing at a time. Too much is overwhelming. The complexity is overwhelming. Build little and assemble the pieces.
Minimize wasted motion. Don’t work on the unnecessary. Don’t work on something that is never going to be built.
Enable change at all points of the process.
The faster the feedback loop, the more productive you can be. This is even true for developers.
Do the simplest thing that could possibly work.
- work means it can go to production. Handles edge cases. Has error handling.
- simple means it is minimal code repetition, elegant to a point
- simple means different things to different people. You need to take this into account when designing. Creating a common vision or dumbing it down.
YAGNI (You aren’t gonna need it)
- build what you need right now
- the simple solution may be enough
- easy to add complexity, but tough to remove it
- makes shipping faster
- “We are going to need it” counter this with “We’ll make code that is easy to change”
Design vertical slices of deliverable functionality. All design work should be traceable to immediate business needs. You have to keep one eye on the upcoming features while you work this way.
Minimize rework by integrating early. Test early. Get feedback from users early (37 Signals territory). Deploy early (does the server infrastructure work?). Ultimately you want to shorten time between doing and verifying.
Delay commitment until the last responsible moment. We all agree on this, but when is it?
- Utilize continuous learning
- Don’t act on speculative design
- Keep your options open
- Think ahead! Don’t act ahead!
Don’t go past the last responsible moment. Be aware of outstanding design decisions. Some of your decisions will need to be made earlier than others.
Abstractions can provide lots of reuse of code and development can be easier. They also can add unnecessary complexity and can make it so that your changes are more difficult. Make abstractions earn their keep.
Avoid “Architect Hubris” (defn. If we just build the framework upfront, coding will be easy.)
Things that are not related conceptually should not be related in the system (Pragmatic Programmer).
Separation of concerns, Cohesion, Coupling == Orthogonal Code
Always make sure you’re ready to have your code readable (font size). Bellware blurts out “MS sucks”. Miller responds “Or the guy driving does”.
JP and Woodsy are looking like a pretty cute couple sitting together on that chair.
Single Responsibility Principle. This is the most important design principle.
- “A class should have only one reason to change”
- One class, one responsibility
- An expression of cohesion
Keep each piece of code as simple as possible.
Don’t worry about the cyclomatic complexity of a class, look at the worst cyclomatic complexity for a method within the class.
If you open a class with a lot of usings, you definitely have too many responsibilities.
First step in refactoring to SRP is to create a class for each area of responsibility.
Using HTML to show C# is a tricky way to make syntax error go away.
Open Close Principle (OCP). “Software entities should be open for extension, but closed for modification.” – Robert C. Martin
The essence of OCP is to be able to add functionality by writing new code and not modifying existing code.
Depend on Abstractions
Dependency Inversion Principle
code to interface
- use mock objects to remove inconvenient dependency tests* Don’t let the abstraction leak
Testing seams are important for isolating the code so that you can write simple tests for small amounts of code.
I just realized that I’m sitting in a room (and a row of seats) with the Code Better crew (JP, Scott Bellware, Jeremy Miller and Rod Paddock) add to that Oren Eini.
State based testing and stateless testing argument breaks out between Oren and Jeremy. Woodsy jumps in the middle and gets a mock object to the head.
2nd quote from the Pragmatic Programmer. Top 5 on my list of must reads for developers.
Yesssss….the internet is back working.
Hot agilista report…..they’re not on the floor this session, but they’re still right in front of me.
“TDD gives you the 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
Make your code easy to test. You can cycle much quicker this way.
Testability is a first class quality in your code. Testability means your code has good cohesion and coupling.
Isolate the ugly stuff (stuff that’s inconvenient while unit testing) i.e. database, active directory, web services, messaging.
Dependency Inversion Principle: code to the interface not the implementation.
Hot agilista note! #2 (Wendy) has a compulsion to say “Bless you” to everyone in the room that sneezes.
When coding use Push, not Pull. For example, don’t code in DateTime.Now() if you need it. Instead, push in a date. If you want it to be Now(), great, if for testing you want something else, better.
Test small before you test big. Don’t get into analysis paralysis as a developer. Don’t think about the bigger code right off, work on a small piece and make it loosely coupled so that it can be rearranged as required after starting coding.
Agilista note: They’re writing notes to each other instead of speaking. I’m sure the last one said “Why are we sitting near those to cuddling developers?” Woodsy and JP don’t have a clue.
Keep a short tail. Make sure you don’t have to bring too much with you when you move a class somewhere else. i.e. moving a DTO shouldn’t require moving the DAL and the database. Also keeping a short tail allows you to test business logic by testing only the business logic. Don’t test due to a side effect of the business logic (i.e. the error message returned).
JP has deserted Woodsy for a seat closer to the action. I’m sure that Woodsy would have given him more action if he’d asked.
Don’t mock the children in a dependency chain. Only mock the level that you’re interacting with.
Don’t work on an integration test until you know that all the individual pieces work correctly.
Design together
- no time for misunderstanding
- socialize the design – this is a lot harder than making the design decision
- know the why
- collectively challenge the design every day
- talk about the design
- keep the team abreast of changing design strategies.
Freaking fantastic talk covering a whole lot of topics (as you can tell by the length of the post).