O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Adaptive Code: Agile coding with design patterns and SOLID principles, Second Edition

Book Description

Write code that can adapt to changes.

By applying this book’s principles, you can create code that accommodates new requirements and unforeseen scenarios without significant rewrites. Gary McLean Hall describes Agile best practices, principles, and patterns for designing and writing code that can evolve more quickly and easily, with fewer errors, because it doesn’t impede change.

Now revised, updated, and expanded, Adaptive Code, Second Edition adds indispensable practical insights on Kanban, dependency inversion, and creating reusable abstractions. Drawing on over a decade of Agile consulting and development experience, McLean Hall has updated his best-seller with deeper coverage of unit testing, refactoring, pure dependency injection, and more.

Master powerful new ways to:

• Write code that enables and complements Scrum, Kanban, or any other Agile framework

• Develop code that can survive major changes in requirements

• Plan for adaptability by using dependencies, layering, interfaces, and design patterns

• Perform unit testing and refactoring in tandem, gaining more value from both

• Use the “golden master” technique to make legacy code adaptive

• Build SOLID code with single-responsibility, open/closed, and Liskov substitution principles

• Create smaller interfaces to support more-diverse client and architectural needs

• Leverage dependency injection best practices to improve code adaptability

• Apply dependency inversion with the Stairway pattern, and avoid related anti-patterns

About You

This book is for programmers of all skill levels seeking more-practical insight into design patterns, SOLID principles, unit testing, refactoring, and related topics. Most readers will have programmed in C#, Java, C++, or similar object-oriented languages, and will be familiar with core procedural programming techniques.

Table of Contents

  1. Title Page
  2. Copyright Page
  3. Dedication Page
  4. Contents at a glance
  5. Contents
  6. Introduction
  7. Part I: An Agile foundation
    1. Chapter 1. Introduction to Scrum
      1. Scrum versus waterfall
      2. Roles and responsibilities
        1. Product owner
        2. Scrum master
        3. Development team
      3. Artifacts
        1. The Scrum board
        2. Charts and metrics
        3. Backlogs
      4. The sprint
        1. Release planning
        2. Sprint planning
        3. Daily Scrum
        4. Sprint demo
        5. Sprint retrospective
        6. Scrum calendar
      5. Agile in the real world
        1. Rigidity
        2. Untestability
        3. Metrics
      6. Conclusion
    2. Chapter 2. Introduction to Kanban
      1. Kanban quickstart
        1. The information radiator
      2. Limiting work in progress
        1. Protecting against change
        2. Defining “done”
      3. Event-driven ceremonies
      4. Classes of service
        1. Service level agreements
        2. Class WIP limits
        3. People as a class of service
      5. Analysis
        1. Lead time and cycle time
        2. Cumulative flow diagrams
      6. Conclusion
  8. Part II Foundations of adaptive code
    1. Chapter 3. Dependencies and layering
      1. Dependencies
        1. A simple example
        2. Framework dependencies
        3. Third-party dependencies
        4. Modeling dependencies in a directed graph
      2. Managing dependencies
        1. Implementations versus interfaces
        2. The new code smell
        3. Alternatives to object construction
        4. Resolving dependencies
        5. Dependency management with NuGet
      3. Layering
        1. Common layering patterns
        2. Cross-cutting concerns
        3. Asymmetric layering
      4. Conclusion
    2. Chapter 4. Interfaces and design patterns
      1. What is an interface?
        1. Syntax
        2. Explicit implementation
        3. Polymorphism
      2. Adaptive design patterns
        1. The Null Object pattern
        2. The Adapter pattern
        3. The Strategy pattern
      3. Further versatility
        1. Duck-typing
        2. Mixins
        3. Fluent interfaces
      4. Conclusion
    3. Chapter 5. Testing
      1. Unit testing
        1. Arrange, Act, Assert
        2. Test-driven development
        3. More complex tests
      2. Unit-testing patterns
        1. Writing maintainable tests
      3. The Builder pattern for tests
        1. The Builder pattern
        2. Clarifying unit test intent
      4. Writing tests first
        1. What is TDD?
        2. Test-driven design
        3. Test-first development
      5. Further testing
        1. The testing pyramid
        2. Testing pyramid anti-patterns
        3. The testing quadrant
      6. Testing for prevention and cure
        1. How do you decrease MTTR?
      7. Conclusion
    4. Chapter 6. Refactoring
      1. Introduction to refactoring
        1. Changing existing code
        2. A new account type
      2. Aggressive refactoring
        1. Red, green, refactor…redesign
      3. Making legacy code adaptive
        1. The golden master technique
      4. Conclusion
  9. Part III: SOLID code
    1. Chapter 7. The single responsibility principle
      1. Problem statement
        1. Refactoring for clarity
        2. Refactoring for abstraction
      2. SRP and the Decorator pattern
        1. The Composite pattern
        2. Predicate decorators
        3. Branching decorators
        4. Lazy decorators
        5. Logging decorators
        6. Profiling decorators
        7. Decorating properties and events
      3. Conclusion
    2. Chapter 8. The open/closed principle
      1. Introduction to the open/closed principle
        1. The Meyer definition
        2. The Martin definition
        3. Bug fixes
        4. Client awareness
      2. Extension points
        1. Code without extension points
        2. Virtual methods
        3. Abstract methods
        4. Interface inheritance
        5. “Design for inheritance or prohibit it”
      3. Protected variation
        1. Predicted variation
        2. A stable interface
        3. Just enough adaptability
        4. Predicted variation versus speculative generality
        5. Do you need so many interfaces?
      4. Conclusion
    3. Chapter 9. The Liskov substitution principle
      1. Introduction to the Liskov substitution principle
        1. Formal definition
        2. LSP rules
      2. Contracts
        1. Preconditions
        2. Postconditions
        3. Data invariants
        4. Liskov contract rules
        5. Code contracts
      3. Covariance and contravariance
        1. Definitions
        2. Liskov type system rules
      4. Conclusion
    4. Chapter 10. Interface segregation
      1. A segregation example
        1. A simple CRUD interface
        2. Caching
        3. Multiple interface decoration
      2. Client construction
        1. Multiple implementations, multiple instances
        2. Single implementation, single instance
        3. The Interface Soup anti-pattern
      3. Splitting interfaces
        1. Client need
        2. Architectural need
        3. Single-method interfaces
      4. Conclusion
    5. Chapter 11. Dependency inversion
      1. Structuring dependencies
        1. The Entourage anti-pattern
        2. The Stairway pattern
      2. An example of abstraction design
        1. Abstractions
        2. Concretions
        3. Abstracting capabilities
        4. The improved client
        5. Abstracting queries
        6. Further abstraction
      3. Conclusion
  10. Part IV: Applying adaptive code
    1. Chapter 12. Dependency injection
      1. Humble beginnings
        1. The Task List application
        2. Constructing the object graph
      2. Beyond simple injection
        1. The Service Locator anti-pattern
        2. Illegitimate Injection
        3. The composition root
        4. Convention over configuration
      3. Conclusion
    2. Chapter 13. Coupling, cohesion, and connascence
      1. Coupling and cohesion
        1. Coupling
        2. Cohesion
      2. Connascence
        1. Name
        2. Type
        3. Meaning
        4. Algorithm
        5. Position
        6. Execution order
        7. Timing
        8. Value
        9. Identity
        10. Measuring connascence
        11. Locality
        12. Unofficial connascence
        13. Static vs. dynamic connascence
      3. Conclusion
  11. Adaptive tools
    1. Source control with Git
      1. Cloning a repository
      2. Switching to a different branch
    2. Continuous integration
  12. Index
  13. About the author
  14. Code Snippets