Software Economics Tradeoffs of Decoupled Software
Software EconomicsTradeoffs of Decoupled Software
Luis Artola@artolamola @buntplanet
Guillermo Gutiérrez@ggalmazor @buntplanet
0.1About technology, tradeoffs and business needs
Business needs
Value, Cost, Risk & Debt
Iterative & incremental
Change & evolution Dependencies
Economy
Economy is about making decisions on limited goods
You don’t need to invent anything. They have figured out
everything for you
Maybe you don’t make decisions about money
What about time? Time is money and it’s limited
and will let you use the same language from business
Developing an economic mindset will help you with your
decision making
Makes easier to achieve a common goal, a shared vision
Speaking the same language improves conversation and
trust
Economies of scale Cost of opportunityCost of acquisition
Marginal costTime to market
Return of InvestmentRiskDebt, loans, interest
Time Value of MoneyCash flowBalance sheetLiquidity
Throughput accountingCost accountingNet present value Real options
Business mindset
Value Cost
Economies of scale Cost of opportunityCost of acquisition
Marginal costTime to market
Return of InvestmentRiskDebt, loans, interest
Time Value of MoneyCash flowBalance sheetLiquidity
Throughput accountingCost accountingNet present value Real options
In this talk
Value Cost
Value, Cost, Risk
& DebtBusiness
needsIterative &
incrementalChange & evolution Dependencies
We are here to satisfy business needs
Early delivery of value,
What does business need?
ROIRisk reduction
Hypothesis validation Stakeholders shared vision
Early delivery of value, with the lowest possible cost,
What does business need?
Early delivery of value, with the lowest possible cost,
keeping options open,
What does business need?
So that risk is reduced To face uncertainty with better odds
Early delivery of value, with the lowest possible cost,
keeping options open, with debt under control
What does business need?
To avoid being unable to pay it off in the future
How are our coding strategies and practices aligned with
business needs?
We are biasedRefactoring a Good Thing™
Waterfall is a Bad Thing™
Business people don’t understand us™
Can you explain your coding strategies and practices in terms of value, cost, options, risk and
debt?
How to deal with technologyContext & Tradeoffs
Agile practice catalog
Refactoring to Patterns
Often forgetting to talk about when (context)
Software community is great writing articles about what & how
or how to combine other needs (tradeoffs)Often forgetting to talk about when (context)
Software community is great writing articles about what & how
How do we choose from the overwhelming list of things that
we should know?
How do we decide what’s the next thing to work on?
Are we professional about it?
You deal with technology applying context (when) and tradeoffs
(balance)
Value, Cost, Risk
& DebtBusiness
needsIterative &
incrementalChange & evolution Dependencies
Dependencies
Does business care about software dependencies?
Does business care about software dependencies?
No
Business focuses on visible costs
Invisible
Risk & DebtValue
CostQ
uant
ifiab
leU
nqua
ntifi
able
Visible
Cost is quantifiable and visible
Invisible
Risk & DebtValue
CostQ
uant
ifiab
leU
nqua
ntifi
able
Visible
Dependencies are risk and debt (difficult to see and quantify)
Dependencies be here
In an IT context, when you need to decrease the risk of delivering misunderstood needs (continuous feedback from stakeholders)
In a Start-up context, when you need to validate your hypothesis and discover your product
But costs are less important than value, risk or debt
Iterative & incremental
Business needs
Value, Cost, Risk & Debt
Change & evolution Dependencies
How do we deal with it?
Waterfall: Great for cost, if you forget about value, risk and
debt
time
time
RiskCost
Value
time
RiskCost
Value
time
RiskCost
Value
time
Cost
Value
time
Cost
Value
Value hits users for the first time
time
Risk
Iterative & incremental: The best possible option
time
time
Value hits users for the first time
time
time
time
time
Risk
Risk
Risk
Risk
time
Risk
Risk
Risk
Risk
Change & evolution
Business needs
Value, Cost, Risk & Debt
Iterative & incremental Dependencies
Better value risk and debt, but we have to deal with the cost
of change
First vertical feature hits production
We mean by vertical as the minimum amount of software that adds value,
gets feedback (deals with uncertainty) and can be shipped to
users
We get feedback
First set of changes hits production
Second set of changes hits production
Third set of changes hits production
Cost of development tends to zero
Cost of Software is the cost of evolving software
DependenciesBusiness needs
Value, Cost, Risk & Debt
Iterative & incremental
Change & evolution
0.2Recap: from Software economics to code dependencies
To satisfy business needs, we need to be aware of
economic implications of our development strategy,
expressed in terms of value, cost, options, risk and debt.
This implies an iterative, incremental development strategy of vertical slices
This brings to the table new challenges
One is supporting constant code evolution
This brings to the table new challenges
Tightly coupled software is hard to change
Dependencies have big impact in code evolution
Cost of Software
Extended version of Kent Beck’s Implementation patterns, page 19
Cost of Software
Discovering
Extended version of Kent Beck’s Implementation patterns, page 19
Cost of Software
DevelopingDiscovering
Extended version of Kent Beck’s Implementation patterns, page 19
Cost of Software
DevelopingDiscovering
Evolving
Extended version of Kent Beck’s Implementation patterns, page 19
Cost of Software
Delivering
DevelopingDiscovering
Evolving
Extended version of Kent Beck’s Implementation patterns, page 19
Cost of Software
Bug fixingDelivering
DevelopingDiscovering
Evolving
Extended version of Kent Beck’s Implementation patterns, page 19
Cost of evolving software
Cost of understanding Cost of changing
Cost of changing
Abstractions
Composition
Dependencies
Other
Dependencies
Non code Codeschedule dependenciesteam dependencies
This talkCodeNon code
Context Boundaries Dependency Injection by constructorInjection Container / Service LocatorStatic abuse / Implicit dependencies
Declarative styleLaw of Demeter
Extended SOLIDSOLIDGetters and setters are evilLocal retention / Encapsulation
ModularityAnemic modelHexagonal architectureVertical & horizontal mental model
Test harness and test doubles Parallel change refactoringMikado method Self similarity principle
Inversion of Control
Tools & topics about code dependency management
Context Boundaries Dependency Injection by constructorInjection Container / Service LocatorStatic abuse / Implicit dependencies
Declarative styleLaw of Demeter
Extended SOLIDSOLIDGetters and setters are evilLocal retention / Encapsulation
ModularityAnemic modelHexagonal architectureVertical & horizontal mental model
Test harness and test doubles Parallel change refactoringMikado method Self similarity principle
Inversion of Control
This talk
We need a holistic approach
Abstraction - composition - dependencies
cost to understand - change - evolve
Warning
Dependencies are just a lens from which to analyze software
There are other lenses
Warning
2
Reusing is creating dependencies
Good code supports Options
Stop thinking in individual classes
1
3
1Reusing is creating dependencies
This is our project
Our project has one feature
We need to deliver a new feature
We need something similar to the already existing feature
We copy & paste some code from other feature
The cost of change is now x2 more expensive
We extract that piece of code to a common place
We have decreased the cost of change by half
Now all our features have a new dependency
New features can reuse that code
We achieve economies of scale
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
reality
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
reality
New dependency is created
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
reality
New dependency is created theory
Economies of scale tell us that it should go down like this
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
theory
reality
Reality tells us a different story
We have a dependency mess
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
theory
reality
Our dependency mess pushes our costs up
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
We need to watch dependencies and manage them
Dependencies get messy
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
We need to watch dependencies and manage them
Dependencies get messy
Investment on dependency management
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
We need to watch dependencies and manage them
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
We need to watch dependencies and manage them
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
We need to watch dependencies and manage them
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
We need to watch dependencies and manage them
cost
of i
ntro
duci
ng
a ne
w fe
atur
e
time
We need to watch dependencies and manage them
Vertical-horizontal mindset
Vertical slice
Vertical slice
Vertical slice
Vertical slice
Horizontal slice
We need some rules to allow dependencies to exist
Vertical slice
Vertical slice
Vertical slice
Vertical slice
Horizontal slice
We allow dependencies on horizontal slices (common code)
Vertical slice
Vertical slice
Vertical slice
Vertical slice
Horizontal slice
We forbid to depend on vertical slices
Vertical slice
Vertical slice
Vertical slice
Vertical slice
Horizontal slice
We also forbid dependencies between vertical slices
Vertical slice
Vertical slice
Vertical slice
Horizontal slice
Self-similarity principle applies to vertical slices as well
Vertical slice
Vertical slice
Vertical slice
Horizontal slice
We can completely remove a Vertical slice and nothing gets broken
Vertical slice
How do we balance low dependencies with code reuse?
Under which circumstances do we allow ourselves to break our rules?
2Good code supports business options
Business Options
time
Our schedule
Start working today
time
Deploy next month
Our schedule
time
Our progress
time
Our progress
Business needs a demo!
Option 1: Not giving options
Option 1: Not giving optionsNot professional
Option 2: Deploy something smaller
Option 2: Deploy something smallerCan you do that?
Interfaces and Inversion of Control
NotificationPort
Our appNotification Component
When you’re implementing someone’s Interface, you’re bound by its API and dependencies
uses
NotificationPort
Our appNotification Component
When you own an Interface, you make the rules
extends
When dealing with external dependencies, you can switch the place of the
Interfaces involved
Switching interfaces’ places is Inversion of Control
This gives you freedom for new implementations
This gives you freedom for new Options
time
Original schedule
time
Our design includes IoC
Original schedule
IoC
We buy an option
time
We deploy a smaller version for the demo
IoC
Original schedule
time
We finish our work and deploy the final version, which uses Amazon SMS
IoC
Original schedule
Extra cost
time
We’ve payed an extra cost but we’ve made it to the demo
IoC
Original schedule
Hexagonal Architecture
Hexagonal architecture applies IoC across your design
We focus on what we need and then we write code that complies
Our needs are defined in Ports and the implementations are called Adapters
JavaX
Amazon
SMS
Notifications
Port
Adapters are interchangeable
JavaX
Amazon
SMS
Notifications
Port
JavaX
MailAmazon
SMS
Adapters are interchangeable
Notifications
Port
Ports are interfaces declared on our app’s
package system
com.programania.coolapp.NotificationsPort
Adapters use foreign package systems
javax.mail.*
com.programania.coolapp.NotificationsPort
Adapters extend our app’s Ports
javax.mail.*
com.programania.coolapp.NotificationsPort
Internals depend on internals
javax.mail.*
com.programania.coolapp.NotificationsPort
By doing this, we’re inverting the control
(IoC) in our app
javax.mail.*
How do we choose what’s inside the Hexagon and what lies outside?
Your design needs to support Options but how do you balance it with Y.A.G.N.I.?
How are you going to defer decisions?
3Stop thinking in individual classes
Module, component or hexagon. They’re the same: a cluster of classes
Remember those extended S.O.L.I.D. principles
Inside a component, classes and dependencies can be unstable
Outside the component, dependencies are few and stable
Single Responsibility Principle of a class
Single Responsibility Principle of a class module
Class Responsibility and Collaborators (dependencies)
Class Component Responsibility and Collaborators (dependencies)
Class Level Testing
Class Module Level Testing
Insights and take aways
An economic mindset lets you stay in sync with business and make better decisions
Cost of software is the cost of evolving software
Principles are greatWhat will you do when they contradict?
Context is primordial(search for it when reading the next success story)
Tradeoffs are not staticThey are in constant tension through a project
Reusing is creating dependencies
IoC is about switching interfaces’ places
Stop thinking about individual classesStart considering cluster of classes, seek cohesion and
analyze dependencies
Thanks!