Thursday, July 16, 2009

Refactoring for Agility

Some of you might have guessed from my recent posts on Emergent Design, Technical Debt, JEDI Programming, and 5S Qualities of Well Designed, Well-Factored Code, that I've been looking into trying to teach the fundamentals of refactoring and how it scales to larger projects. I've gathered some references and quotes and some ideas for slides that I wanted to bounce around on my blog.

Here is an outline and some thoughts for part I of some slides ...

PART I - REFACTORING FOR AGILITY

1. Overview of Refactoring
  • Identifies design-maintenance issues (“code smells”) that typically represent violations of known principles of good design.
  • Incrementally and iteratively applies a set of design improvement techniques (“refactorings”).
  • The goal is to minimize complexity & duplication in order to maximize simplicity & ease-of-change.
  • Encourages the “right” design details to emerge “just-in-time” with minimal guesswork/rework.
  • Scaling-up includes the use of periodic restructuring, initial & incremental design (“just enough”), and evolutionary architecture.

2. Refactoring Defined [cite definition(s)]

3. Refactoring Myths -- Refactoring is NOT …
  • “Rework” – redesigning things that could, and should, have been designed correctly in the first place.
  • Design “gold-plating” – work that adds no business value, and merely serves to stroke the egos of perfectionists who are out of touch with business reality.
  • Miscellaneous code “tidying” – the kind that is “nice to have,” but should only happen when the team has some slack-time, and is a luxury we can do without, without any serious consequences.
  • A license to “hack” – avoiding any and all initial design & analysis and instead jumping straight to coding with no “real” design.
  • Reengineering – large-scale restructuring that requires a concerted effort over the course of several weeks/months to re-write or re-architect significant parts of the system.
4. Refactoring IS …
  • A systematic approach to source-code “hygiene” that minimizes the chances of introducing bugs
  • Improving the design of the code after it has been written
  • A behavior-preserving transformation of source-code structure
  • The process of simplifying & consolidating a work-product by making several, small, successive revisions focused on: preserving correctness, removing redundancy, revealing thoughts & intentions, and improving clarity & conciseness.
  • A disciplined way of making changes while exposing the project to significantly less risk.
  • An effective means to address the economic reality of software growth/complexity by reducing & amortizing its cost throughout the daily business of code development & maintenance activities.
5. Why Refactor?
6. How to Refactor
7. Rules of Clean Code
8. Rules for Simple Code
9. The Steps of Refactoring
10. Code Smells
11. Categories of Refactorings
  • Small Refactorings
  • Larger Refactorings/Restructurings
  • Each category contains as many as a dozen or more refactorings, most of which are catalogued at http://refactoring.com/catalog/

12. Refactorings (Some refactorings from real projects)
  • See http://refactoring.com/catalog/ for an up-to-date list (and the “Refactoring to Patterns” catalog too)
13. What to do if …?
  • I spot a “smell” that is not already known or catalogued?
  • There is no specific known/catalogued “refactoring” for what I think I need?
14. When to Refactor?
  • While adding functionality
  • While fixing a bug
  • While reviewing code
  • After coding the same/similar thing for the third time (to “factor out” the duplication)
  • A.k.a.: The Rule of Three: 3 strikes and you refactor.
  • After the third time you deferred refactoring a change, for any reason [The Rule of Three, again]
  • Before the end of the iteration if you haven’t been following The Rule of Three
15. Refactor Continually
16. When NOT to Refactor?
  • When the build is broken or tests don’t pass
  • When it would compromise meeting an impending deadline or commitment
  • When the code in question really just needs to be re-written “from scratch”
  • When it would modify code/interfaces that could significantly impact/break other work (e.g.: Published/public interfaces and protocols, Database schemas/tables/operations)
  • Sometimes we must defer refactoring for later and/or plan for subsequent restructuring
17. Refactoring to Patterns & Principles
Software Design Principles and Design Patterns are the underlying foundation for Refactoring:
  • Code smells (a.k.a “code pathologies”): Signal a possible violation of design principles, Suggest which refactoring may be needed
  • Refactoring: Correct a design principle violation (at least partially), Converge toward common design patterns
  • Design Patterns: Reconcile forces among conflicting design concerns,Restore balance between competing design principles
  • Design Principles: Lead us to attain desired design qualities/attributes
18. Design Attributes/Code Qualities
Qualities of Highly Maintainable Software:
  • Loose Coupling & High Cohesion
  • Hierarchy (Structural Decomposition)
  • Abstraction, Encapsulation & Modularity
  • Sufficiency, Parsimony and Primitiveness
  • Readability
  • Testability
  • Modifiability
  • Serviceability
19. Design Principles: SOLID, SoC, DRY, Shy
  • The SOLID Principles of Object-Oriented Design (from Uncle Bob)
  • The SoC Principle: Separation of Concerns — separate interface from implementation, policy from mechanism, behavior from construction, commands from queries, ...
  • The DRY Principle: Don’t Repeat Yourself (Eliminate Duplication), Single Point of Truth
  • The “Structure-Shy” Principle: (“Tell, Don’t Ask!”), The Law of Demeter, Principle of Least Assumed Knowledge
20. Other Acronyms of Simple/Agile Design
  • OAOO – Say Things Once And Only Once (restatement of the DRY principle)
  • DTSTTCPW – Do The Simplest Thing That Could Possibly Work! (restatement of the KISS principle)
  • YAGNI – You Aren’t Gonna Need It!
  • The LRM Principle: Defer Commitment of Irreversible Decisions to the Last Responsible Moment!
  • BDUF – Big Design Up-Front! (vs. JEDI)
  • JEDI – Just Enough Design Initially/In-front!
  • DDD – Domain-Driven Design
21. Design Patterns
22. Summary: Refactoring for Agility
  • Successively applies small behavior-preserving transformations to eliminate code smells
  • Based on proven design principles and patterns for achieving maintainability & modifiability
  • Good automated testing is a prerequisite
  • Refactoring is not rewriting, rework or restructuring
  • With refactoring, we continuously invest nominal effort to reduce the risk & cycle-time of changes
  • The goal is to minimize complexity & duplication in order to maximize simplicity & ease-of-change.
  • Practiced in a highly disciplined manner, it promotes:
    • Sufficient functionality
    • Simple & clean code
    • Supple design
    • Serviceable software
    • Sustainable team velocity

23. Resources:
Code Smells:
Design Principles:
Design Patterns:
- Online Resources:
- Books:
Other Agile Design Slogans:

No comments: