2. Architecture that supports guided,
incremental change as a first
principle across multiple
dimensions.
A DEFINITION
NEAL FORD, PATRICK KUA, REBECCA PARSONS
9. Guided
Fitness Functions
An Architectural Fitness Function provides a Guided and
Objective Assessment of some Architectural Characteristic(s)
aka
Y ~ F(x)
Where
Y = Characteristic, F(x) = Objective Assessment
11. Atomic (e.g. Unit Test)
Holistic (e.g. System Security)
Triggered (e.g. Based on event like on check-in)
Continuous (e.g. Runs like cron job or continually like A/B test)
Static FF (e.g. Pure functions, same input, same state, same result)
Dynamic (e.g. Perf tests will give different results for each run)
Automated (Preferable)
Manual (e.g. when a lawyer is needed to check software licenses)
Temporal (e.g. Reminder for upgrading OS, tools etc.)
Domain Specific (e.g. Regulation related, Financial transactions etc.)
Intentional (Decided at the inception of project)
Emergent (In response to new requirements or change in situation. E.g. When laws change)
Types of Fitness Functions
13. describe "Performance" do
it "completes a transaction under 10 seconds" do
expect(transaction.check_transaction_round_tr
ip_time()).to < 10
end
it "has less than 10% error rate for 10000
transactions" do
expect(transaction.check_error_rate_for_trans
actions(10000)).to < .1
end
end
describe "Observability" do
it "streams metrics" do
expect(service.has_metrics(
)).to be(true)
end
it "has parseable logs" do
expect(service.has_logs_in_
aggregator()).to be(true)
end
end
Examples
describe "Performance" do
it "completes a transaction under 10
seconds" do
expect(transaction.check_transactio
n_round_trip_time()).to < 10
end
it "has less than 10% error rate for 10000
transactions" do
expect(transaction.check_error_rate
_for_transactions(10000)).to < .1
end
end
describe "Compliance Standards" do
describe "PII Compliance" do
it "should not have PII in the logs"
do
expect(logs.has_pii_content())
.to_not be(true)
end
end
describe "GDPR Compliance" do
it "should report types of personal
information processed" do
expect(gdpr.reports_PII_types(
)).to be(true)
end
it "should have been audited in the
past year" do
expect(gdpr.audit_age()).to <
365
end
end
end
describe "Operability
Standards" do
describe "Operations
Check" do
it "should
have a service runbook" do
expect(
service.has_runbook()).to
be(true)
end
it "should
have a README" do
expect(
service.has_readme()).to
be(true)
end
it "should
have alerts" do
end
end
SOURCE:
https://www.thoughtworks.com/insights/articles/fitness-function-driven-
development
14. Incremental
Small steps in right direction. Reduces scope for errors.
Steps should consider operational aspects:
Deployment, infra etc.
Steps should consider Dev processes: Programming,
Dev activities etc.
15. Versioning the Database
❖ No DBA. Script all DB changes
incrementally in smallest possible
steps.
❖ It should allow Refactoring in small
chunks, just like code refactoring. No
big bang changes.
❖ Decoupling between app and DB
migration.
❖ E.g. DBDeploy Pattern - CI for DBs
➢ DBDeploy Tool / Flyway.
➢ DB updates are code.
➢ Large updates are broken to
small changes.
➢ Metadata in database.
❖ In a test environment, start with clean
DB for Integration and Acceptance
TEsts.
❖ Roll forward is better than Roll back.
❖ E.g. Expand Contract Pattern
Incremental (Example)
Migrate
Trigger or Async