Skip to content

Commit

Permalink
Finished payoff edits
Browse files Browse the repository at this point in the history
  • Loading branch information
robmoffat committed Mar 26, 2024
1 parent 52fe6ab commit 28fcc7f
Show file tree
Hide file tree
Showing 12 changed files with 2,339 additions and 23 deletions.
1 change: 1 addition & 0 deletions dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,4 @@ organization
silos
outreach
lifecycle
accrual
25 changes: 24 additions & 1 deletion docs/practices/Glossary-Of-Practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,14 @@ See:
- [Development Process](../thinking/Development-Process.md#a-toy-process)_
- [Production (Cadence)](../thinking/Cadence.md#production)

### Beta Test

Beta testing is the process of testing an unreleased piece of software with a portion of its intended audience.

See:

- [Consider Payoff](../thinking/Consider-Payoff.md)

### User Acceptance Testing (UAT)

Completing a [Feedback Loop](../thinking/Cadence.md) in order to ascertain whether [Feature Risk](../risks/Feature-Risk.md) has been correctly addressed by new features. Also called _verification_, _user feedback_ or _manual testing_.
Expand Down Expand Up @@ -316,4 +324,19 @@ See:

- [Operations Management](../risks/Operational-Risk.md#operations-management)
- [Planning](../risks/Operational-Risk.md#planning)


### Dog-Fooding

_Eating your own dog food_ is the process by which you use your product or service internally in order to get more feedback about how well it works.

See:

- [Consider Payoff](../thinking/Consider-Payoff.md)

### Feature Toggle

A condition within the code enables or disables a feature during runtime, perhaps for a certain group of users.

See:

- [Consider Payoff](../thinking/Consider-Payoff.md)
36 changes: 23 additions & 13 deletions docs/thinking/Consider-Payoff.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ Sometimes, there will be multiple _actions_ you could take on a project and you
- And, making a decision takes time, which could add risk to your schedule.
- And what's the risk if the decision doesn't get made?

We can't know in advance how well any action we take will work out. Therefore, [Taking Action](../thinking/Glossary.md#taking-action) is a lot like placing a bet.
We can't know in advance how well any action we take will work out. Therefore, [Taking Action](../thinking/Glossary.md#taking-action) is a lot like placing a [bet](/bets/Start).

[Payoff](../thinking/Glossary.md#payoff) then is our judgement about whether we expect an action to be worthwhile: are the risks we escape _worth_ the attendant risks we will encounter? We should be able to _weigh these separate risks in our hands_ and judge whether the [Payoff](../thinking/Glossary.md#payoff) makes a given [Action](../thinking/Glossary.md#taking-action) worthwhile.

The fruits of this gambling are revealed when we [meet reality](../thinking/Glossary.md#meet-reality) and we can see whether our bets were worthwhile.
The fruits of this gambling are revealed when we [meet reality](../thinking/Glossary.md#meet-reality) and we can see whether our bets were worthwhile.

Very occasionally, you'll be in a place where your hand is forced and you have to take one of only a handful of actions, or there is a binary decision. A so called "rock and a hard place". But as we'll see in the third example below, even here you can usually change the action (and therefore the payoff) in your favour.

## Considering Payoff: Examples

Expand All @@ -44,17 +46,15 @@ As a flavour of what's to come, let's look at YAGNI, an acronym for "You Aren't

> YAGNI originally is an acronym that stands for "You Aren't Gonna Need It". It is a mantra from Extreme Programming that's often used generally in agile software teams. It's a statement that some capability we presume our software needs in the future should not be built now because "you aren't gonna need it". - [YAGNI, _Martin Fowler_](https://www.martinfowler.com/bliki/Yagni.html)
The idea makes sense: if you take on extra work that you don't need, _of course_ you'll be accreting risk - you're taking time away from sorting out the real problems!
The idea makes sense: if you take on extra work that you don't need, _of course_ you'll be accreting risk - you're taking time away from sorting out the real problems! You'll also have a greater body of code to manage, which is [also a risk](../risks/Complexity-Risk.md).

But, there is always the opposite opinion: [You _Are_ Gonna Need It](http://wiki.c2.com/?YouAreGonnaNeedIt). As a simple example, we often add log statements in our code as we write it (so we can trace what happened when things go wrong), though following YAGNI strictly says we shouldn't.

#### Which is right?

Now, we can say: do the work _if there is a worthwhile [Payoff](../thinking/Glossary.md#payoff)_.
So which is right? We should conclude that we do the work _if there is a worthwhile [Payoff](../thinking/Glossary.md#payoff)_.

- Logging statements are _good_, because otherwise, you're increasing the risk that in production, no one will be able to understand _how the software went wrong_.
- Logging statements are _good_, because otherwise, you're increasing the risk that in production, no one will be able to understand [how the software went wrong](../risks/Dependency-Risk#invisibility-risk).
- However, adding them takes time, which might [risk us not hitting our schedule](../risks/Scarcity-Risk.md#schedule-risk).
- Also, we have to manage larger log files on our production systems. _Too much logging_ is just noise, and makes it harder to figure out what went wrong.
- Also, we have to manage larger log files on our production systems. _Too much logging_ is just noise, and makes it harder to figure out what went wrong. This increases the risk that our software is [less transparent in how it works](../risks/Complexity-Risk.md).

So, it's a trade-off: continue adding logging statements so long as you feel that overall, the activity [pays off](../thinking/Glossary.md#payoff) reducing overall risk.

Expand All @@ -74,7 +74,13 @@ Our risk-centric view of this strategy would be:

So, "Do The Simplest Thing That Could Possibly Work" is really a helpful guideline for Navigating the [Risk Landscape](../risks/Risk-Landscape.md), but this analysis shows clearly where it's left wanting:

- _Don't_ do the simplest thing if there are other things with a better [Payoff](../thinking/Glossary.md#payoff) available.
- _Don't_ do the simplest thing if there are other things with a better [Payoff](../thinking/Glossary.md#payoff) available.

An example of where this might be the case, think about how you might write a big, complex function (I'm thinking of a function to process interest accrual), but pick your own example). The _simplest thing_ might be to just write a single function and a few unit tests for it. However, a slightly _less simple thing_ that would work might be to decompose the function into multiple steps, each with its own unit tests. Perhaps you might have a step which calculates the number of days where interest is due (working days, avoiding bank holidays), another step that considers repayments, a step that works out different interest rates and so on.

![Different payoff for doing the simplest thing vs something slightly less simple with more effort](/img/generated/introduction/risk_landscape_4_simplest.png)

Functional decomposition and extra testing might not be the _simplest thing_, but it might reduce risks in other ways - making the code easier to understand, easier to test and easier to modify in the future. So deciding up-front to accept this extra complexity and effort in exchange for the other benefits might seem like a better [Payoff](../thinking/Glossary.md#payoff) than the simplest thing.

### Example 3: Continue Testing or Release?

Expand All @@ -89,14 +95,18 @@ Obviously, in the ideal world, we want to get to the place on the [Risk Landscap

This is (a simplification of) the dilemma of lots of software projects - _test further_, to reduce the risk of users discovering bugs ([Implementation Risk](../risks/Feature-Risk.md#implementation-risk)) which would cause us reputational damage, or _get the release done_ and reduce our [Funding Risk](../risks/Scarcity-Risk.md#funding-risk) by getting paying clients sooner.

In the above table, it _appears_ to be better to do the "Go Live" action, as there is a greater [Payoff](../thinking/Glossary.md#payoff). The problem is, actions are not _commutative_, i.e. the order you do them in counts.
Lots of software projects end up in a phase of "release paralysis" - wanting things to be perfect before you show them to customers. But sometimes this places too much emphasis on preserving reputation over getting paying customers. Also, getting real customers is [meeting reality](Glossary.md#meet-reality) and will probably surface new [hidden risks](Glossary.md#hidden-risk) that are missing from the analysis.

The important take-away here is that you don't have to accept the dilemma as stated. You can change the actions to improve the payoff, and [meet reality more gradually](Meeting-Reality#the-cost-of-meeting-reality):

![UAT or Go Live: where will you end up?](/img/generated/introduction/risk_landscape_3_moves.png)
- Start a closed [beta test](../practices/Glossary-Of-Practices.md#beta-test) with a group of friendly customers
- Use [feature toggles](../practices/Glossary-Of-Practices.md#feature-toggle) to release only some components of the software
- [Dog-food](../practices/Glossary-Of-Practices.md#dog-fooding) the software internally so you can find out whether it's useful in its current state.

The diagram above shows our decision as _moves on the [Risk Landscape](../thinking/Glossary.md#risk-landscape)_. Whether you "Go Live" first, or "UAT" first makes a difference to where you will end up. Is there a further action you can take to get you from the "Dead End" to the "Goal"? Perhaps.

## What To Do?

As a concept, payoff is made more tricky because often the actions you take might depend on each other, and the payoff might not be immediate.
In reality, payoff is made more tricky because often the actions you take might depend on each other, the payoff might not be immediate and (unlike making a bet in the real world) you can't be certain what the payoff will be in advance. Nevertheless, this is a really useful concept in software engineering because it clarifies the decision you're making.

So, first things first, you need to make sure you're [Tracking Risk](Track-Risk.md) properly.
In order to make the most of payoff, first you need to make sure you're [Tracking Risk](Track-Risk.md) properly.
2 changes: 1 addition & 1 deletion docs/thinking/Just-Risk.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ In the previous sections, we introduced something of a "diagram language" of ris

![Risk-First Diagram Language](/img/generated/introduction/all_risk_management_language.png)

[Goals](../thinking/Glossary.md#goal) live inside our [Internal Model](../thinking/Glossary.md#internal-model), just like Risks. It turns out, that functionally, Goals and Risks are equivalent. For example, The Goal of "Implementing Feature X" is equivalent to mitigating "Risk of Feature X not being present".
[Goals](../thinking/Glossary.md#goal) live inside our [Internal Model](../thinking/Glossary.md#internal-model), just like Risks. Functionally, Goals and Risks are equivalent. For example, the Goal of "Implementing Feature X" is equivalent to mitigating "Risk of Feature X not being present".

Let's try and back up that assertion with a few more examples:

Expand Down
48 changes: 48 additions & 0 deletions src/images/generated/introduction/risk_landscape_4_simplest.adl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<diagram xmlns="http://www.kite9.org/schema/adl"
xmlns:xslt="http://www.kite9.org/schema/xslt" id="dia"
style="--kite9-min-width: 900pt;"
xslt:template="/public/templates/risk-first/risk-first-template.xsl">
<container id="start"
style="--kite9-connection-align: 50%; --kite9-traversal: none; ">
<risk class="goal" id="id_0">Interest Calculation</risk>
<label id="id_16">
Current Internal Model
</label>
</container>
<group style="--kite9-layout: down; ">
<group style="--kite9-layout: right;">
<action id="gl">
Single Function, Unit Tests
</action>
<container id="one"
style="--kite9-traversal: none; --kite9-layout: right; ">
<risk class="attendant" id="a">Harder
to understand
</risk>
<risk class="attendant" id="b">Harder
to test
</risk>
<risk class="attendant" id="c">Less
maintainable
</risk>
<label id="id_16-ux">
Future Internal Model 1
</label>
</container>
</group>
<group id="sdf"
style="--kite9-layout: right; --kite9-horizontal-sizing: maximize; ">
<action id="gl" style="--kite9-horizontal-align: left; ">
Decompose Steps, Separate Unit Tests
</action>
<container id="two"
style="--kite9-horizontal-sizing: maximise; --kite9-horizontal-align: right; ">
<risk class="attendant" id="e">More effort /
schedule used</risk>
<label id="id_16-ng">
Future Internal Model 2
</label>
</container>
</group>
</group>
</diagram>
4 changes: 3 additions & 1 deletion src/images/generated/principles/payoff.adl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@
<page-summary class="principle">
Is the balance in your favour?
</page-summary>

<page-summary class="principle">
If not, look for alternative actions.
</page-summary>
</group>
</group>
</group>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 28fcc7f

Please sign in to comment.