Graduate Program KB

Clean Architecture

Chapter 8 - OCP: The Open-Closed Principle

  • OCP states that "a software artifact should be open for extension but closed for modification"
    • Software should be extendible without modifying existing code

A Thought Experiment

  • Scenario: System displaying financial summary on a web page
  • Goal: Extend the system to print the financial summary as a report
  • Ideally, the amount of changed code to implement the solution should be close to zero
    • Separate things changing for different reasons (SRP)
    • Organise dependencies between those things (DIP)
  • With SRP:
    • Inspect financial data
    • Produce reportable data
    • Formatted by either a web reporter process or print reporter process
  • With DIP:
    • Uni-directional relationship between components protects a component from changes in the other component
    • Forms a hierarchy of protection, higher-level components (Interactors) are protected from changes made in lower-level components (View)
    • Architects separate functionality based on how, why and when a component changes

Directional Control

  • The complexity in these diagrams are usually from added interfaces to ensure dependencies between components point in the right direction
  • Ex. FinancialDataGateway interface between the FinancialReportGenerator and FinancialDataMapper exists to invert dependency between the Interactor and Database components

Information Hiding

  • Ex. FinancialReportRequester interface exists to protect FinancialReportController from knowing too much about the internals of the Interactor
    • Otherwise, Controller would have transitive dependencies on the FinancialEntities
  • Transitive dependencies are a violation of the principle: "Software entities should not depend on things they don't directly use"
  • We want to protect the Interactor from changes to the Controller, but also protect the Controller from changes to the Interactor (both directions)

Conclusion

  • Goal of OCP is to make systems extendible without incurring a high impact of change
  • Achieved by partitioning the system into components and arranging them into a dependency hierarchy
    • Protects higher-level components from changes in lower-level components