Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)

Architectural fitness functions

An overview of architectural fitness functions as a way to check if your architecture matches your needs

Basic idea

Architectural fitness functions:

  • Allow us to evaluate to what extent our architecture has the properties we want it to have
  • Assess goals like performance, reliability, security, operability, coding standards, ...
    • Focus on what is really important for the specific system based on business requirements, technical capabilities, scale, ...
      • This also means not spending time and money on things that are not really important!
    • For every system, a crucial early architecture decision is to define the most important dimensions (scalability, performance, security, ...) to take into account
      • Can help to prioritize riskier work to get the risky stuff out of the way as soon as possible
      • Can lead to an architecture that makes certain concerns explicit instead of having them scattered across the codebase
      • This can still evolve! some fitness functions will emerge during development of the system
  • Provide guidance in evolving our architecture
    • Help finding areas that need improvement
    • Evaluate how certain changes affect how well the architecture satisfies our goals
    • Allow us to make tradeoffs between different goals if needed

Important building block of evolutionary architectures

  • "An evolutionary architecture supports guided, incremental change as a first principle across multiple dimensions"
  • Guidance is provided by fitness functions

Categorizing fitness functions

Atomic versus holistic

Atomic fitness functions:

  • Test one particular aspect of the architecture
  • Example: unit test checking for cyclic dependencies in a certain package

Holistic fitness functions:

  • Test a combination of architectural aspects
  • Useful for assessing the interactions between different architectural concerns
  • Lots of combinations possible, need to focus on most important ones
  • Example:
    • Data freshness
    • Scalability: number of concurrent users within a certainly latency range
      • Developers make this work by implementing caching, but this influences freshness of data
    • Very helpful to have a fitness function that tests for freshness of data with the caching enabled

Triggered (batch) versus continuous

Triggered fitness functions:

  • Executed in response to some particular event
  • Examples:
    • A developer executing a unit test
    • A QA person performing exploratory testing

Continuous fitness functions:

Static versus dynamic

Static fitness function:

  • Fixed predefined acceptable values: binary, a certain number range, ...
  • Example: binary pass/fail of a unit test

Dynamic fitness function:

  • Acceptable values depend on context
  • Example: acceptable latency might depend on actual scale of the system

Automated versus manual

Automated fitness function:

  • Automated unit tests, deployment pipelines, stress tests, ...
  • Ideally as much automation as possible!

Manual fitness functions:

  • Some things impossible to automate, for example when certain changes need manual approval for legal reasons
  • Some things may not be properly automated yet, for example QA
  • For some tests, it might be more efficient to determine success/failure manually

Temporal

Temporal fitness functions:

  • Have a particular time component
  • Example: temporal fitness function as a reminder to check to see if important security updates have been performed

Example fitness functions

Atomic and triggered

Typically run by developers and in deployment pipeline

See also Static analysis

Holistic and triggered

Typically run by developers and in deployment pipeline

Example: testing what kind of impact tighter security has on scalability

Atomic and continuous

Run as part of the deployed architecture

Example: monitoring

Example: logging

Holistic and continuous

Run as part of the deployed architecture

Example: Netflix's Chaos Monkey

  • Designed to test resilience to instance failures
  • Runs in production and randomly terminates instances
  • Forces teams to build resilient services while still taking into account other architectural goals

Resources

  • Building Evolutionary Architectures (book by Neal Ford, Rebecca Parsons and Patrick Kua) (summary slides )