SlideShare a Scribd company logo
1 of 45
Download to read offline
WHEN BOOLEANS
ARE NOT ENOUGH...
STATE MACHINES?
TWITTER / GITHUB: @harph
SAN JOSE, CA
2
HARRINGTON JOSEPH
SR. SOFTWARE ENGINEER
EXPECTATIONS
WHY, HOW AND WHEN TO USE STATE MACHINES
ANALOGY
● is_active
● active
● is_enabled
● enabled
● is_disabled
● disabled
● has_expired
● expired
● is_published
● published
● is_deleted
● deleted
● is_archived
● archived
● is_visible
● visible
● is_hidden
● hidden
● is_ready
● ready
● is_valid
● valid
● is_blocked
● blocked
● failed
● succeeded
● is_positive
● ...
THE PROBLEM
USING BOOLEANS TO REPRESENT STATES AND
ENFORCE BUSINESS RULES
CODE
class Video:
def __init__(self, source):
self.source = source
self.is_playing = False
def pause(self):
# Make the call to pause the video
self.is_playing = False
def play(self):
# Make the call to play the video
self.is_playing = True
def stop(self):
# Make the call to stop the video
self.is_playing = False
video = Video('s3://video/storage/demo.mov')
video.play()
video.pause()
video.stop()
video.is_playing
video.is_playing
WHAT
DOES IT
REALLY
MEAN?
video.is_playing True
Video is playing
video.is_playing False
Is it paused?
Is it stopped?
class Video:
def __init__(self, source):
self.source = source
self.is_playing = False
self.is_paused = False
def pause(self):
# Make the call to pause the video
self.is_playing = False
self.is_paused = True
def play(self):
# Make the call to play the video
self.is_playing = True
self.is_paused = False
def stop(self):
# Make the call to stop the video
self.is_playing = False
self.is_paused = False
Is the video playing?
video.is_playing
Is the video paused?
video.is_paused
Is the video stopped?
not video.is_playing and not video.is_paused
BUSINESS RULES
1. A video can only be played when is paused or stopped.
2. A video can only be paused when is playing.
3. A video can only be stopped when is playing or paused.
class Video:
...
def play(self):
if not self.is_playing or self.is_paused:
# Make the call to play the video
self.is_playing = True
self.is_paused = False
else:
raise Exception(
'Cannot play a video that is '
'already playing.'
)
1. A video can only be played when is paused or stopped.
class Video:
...
def pause(self):
if self.is_playing:
# Make the call to pause the video
self.is_playing = False
self.is_paused = True
else:
raise Exception(
'Cannot pause a video that is '
'not playing.'
)
2. A video can only be paused when is playing.
class Video:
...
def stop(self):
if self.is_playing or self.is_paused:
# Make the call to stop the video
self.is_playing = False
self.is_paused = False
else:
raise Exception(
'Cannot stop a video that is '
'not playing or paused.'
)
3. A video can only be stopped when is playing or
paused.
THE
CODE IS
RAPIDLY
BECOMING
● Complex.
● Bloated.
● Repetitive.
● Hard to test.
class Video:
# States
PLAYING = 'playing'
PAUSED = 'paused'
STOPPED = 'stopped'
def __init__(self, source):
self.source = source
self.state = self.STOPPED
class Video:
...
def play(self):
if self.state != self.PLAYING:
# Make the call to play the video
self.state = self.PLAYING
else:
raise Exception(
'Cannot play a video that is '
'already playing.'
)
1. A video can only be played when is paused or stopped.
class Video:
...
def pause(self):
if self.state == self.PLAYING:
# Make the call to pause the video
self.state = self.PAUSED
else:
raise Exception(
'Cannot pause a video that is '
'not playing.'
)
2. A video can only be paused when is playing.
class Video:
...
def stop(self):
if self.state != self.STOP:
# Make the call to stop the video
self.state = self.STOPPED
else:
raise Exception(
'Cannot stop a video that is '
'not playing or paused.'
)
3. A video can only be stopped when is playing or
paused.
STATE MACHINES
WHAT'S A
STATE
MACHINE?
● Finite number of states.
Mathematical model of
computation.
● Transitions between states.
● Machine. Can only be in one
state at a given time.
USER
LOGIN
STATE
MACHINE
DESIGNING A
STATE MACHINE
1. Define a finite number of states.
2. Lay down the transitions between states.
3. Select the initial state.
1. Define a finite number of states.
2. Lay down the transitions between states.
3. Select the initial state.
CODE
pip install transitions
github.com/pytransitions/transitions
from transitions import Machine
class Video:
# Define the states
PLAYING = 'playing'
PAUSED = 'paused'
STOPPED = 'stopped'
from transitions import Machine
class Video:
# Define the states
PLAYING = 'playing'
PAUSED = 'paused'
STOPPED = 'stopped'
def __init__(self, source):
self.source = source
# Define the transitions
transitions = [
# 1. A video can only be played when is paused or stopped.
{'trigger': 'play', 'source': self.PAUSED, 'dest': self.PLAYING},
{'trigger': 'play', 'source': self.STOPPED, 'dest': self.PLAYING},
# 2. A video can only be paused when is playing.
{'trigger': 'pause', 'source': self.PLAYING, 'dest': self.PAUSED},
# 3. A video can only be stopped when is playing or paused.
{'trigger': 'stop', 'source': self.PLAYING, 'dest': self.STOPPED},
{'trigger': 'stop', 'source': self.PAUSED, 'dest': self.STOPPED},
]
from transitions import Machine
class Video:
...
def __init__(self, source):
self.source = source
# Define the transitions
transitions = [
# 1. A video can only be played when is paused or stopped.
{'trigger': 'play', 'source': self.PAUSED, 'dest': self.PLAYING},
{'trigger': 'play', 'source': self.STOPPED, 'dest': self.PLAYING},
# 2. A video can only be paused when is playing.
{'trigger': 'pause', 'source': self.PLAYING, 'dest': self.PAUSED},
# 3. A video can only be stopped when is playing or paused.
{'trigger': 'stop', 'source': self.PLAYING, 'dest': self.STOPPED},
{'trigger': 'stop', 'source': self.PAUSED, 'dest': self.STOPPED},
]
# Create the state machine
self.machine = Machine(
model=self,
transitions=transitions,
initial=self.STOPPED
)
class Video:
...
def pause(self):
# Make the call to pause the video
...
def play(self):
# Make the call to play the video
...
def stop(self):
# Make the call to stop the video
...
video = Video('s3://video/storage/demo.mov')
video.play() # State is 'playing'
video.state # 'playing'
video.pause() # State is 'paused'
video.stop() # State is 'stopped'
video.pause() # ???
MachineError: "Can't trigger event pause from
state stopped!"
TESTING
HOW DO WE TEST THIS?
1. We don't.
2. Machine is initialized with the expected transitions and initial state.
3. Actual functionality ( play, pause and stop ).
ADDING
A NEW
STATE
RULES
1. A video can only be played when is
paused, stopped or rewinding.
2. A video can only be paused when is
playing or rewinding.
3. A video can only be stopped when is
playing, paused or rewinding.
4. A video can only be rewinded when is
playing or paused.
from transitions import Machine
class Video:
...
REWINDING = 'rewinding'
def __init__(self, source):
...
transitions = [
# 1. A video can only be played when is paused, stopped or rewinding.
{'trigger': 'play', 'source': self.PAUSED, 'dest': self.PLAYING},
{'trigger': 'play', 'source': self.STOPPED, 'dest': self.PLAYING},
{'trigger': 'play', 'source': self.REWINDING, 'dest': self.PLAYING},
# 2. A video can only be paused when is playing or rewinding.
{'trigger': 'pause', 'source': self.PLAYING, 'dest': self.PAUSED},
{'trigger': 'pause', 'source': self.REWINDING, 'dest': self.PAUSED},
# 3. A video can only be stopped when is playing, paused or rewinding.
{'trigger': 'stop', 'source': self.PLAYING, 'dest': self.STOPPED},
{'trigger': 'stop', 'source': self.PAUSED, 'dest': self.STOPPED},
{'trigger': 'stop', 'source': self.REWINDING, 'dest': self.STOPPED},
# 4. A video can only be rewinded when is playing or paused.
{'trigger': 'rewind', 'source': self.PLAYING, 'dest': self.REWINDING},
{'trigger': 'rewind', 'source': self.PAUSED, 'dest': self.REWINDING},
]
...
WHEN ARE
BOOLEANS
NOT
ENOUGH?
● When multiple booleans
represent a single state.
● When business rules are
enforced by multiple
booleans.
WHEN TO
USE
STATE
MACHINES?
● When states are not binary.
● When you have to account
for future states.
● When you have to enforce a
complex set of business
rules.
TAKEAWAYS
● Using booleans to represent states can get messy quite
fast.
● Enforcing business rules by inferring the state from a
set of booleans leads to unreadable, unmaintainable
and hard to test code.
● State machines are not a silver bullet.
● State machines remove the complexity of testing
business rules.
THANK YOU
@harph

More Related Content

Recently uploaded

EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 

Recently uploaded (20)

EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 

Featured

How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...DevGAMM Conference
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationErica Santiago
 
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them wellGood Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them wellSaba Software
 
Introduction to C Programming Language
Introduction to C Programming LanguageIntroduction to C Programming Language
Introduction to C Programming LanguageSimplilearn
 

Featured (20)

How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy Presentation
 
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them wellGood Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
 
Introduction to C Programming Language
Introduction to C Programming LanguageIntroduction to C Programming Language
Introduction to C Programming Language
 

When booleans are not enough... State Machines?

  • 1. WHEN BOOLEANS ARE NOT ENOUGH... STATE MACHINES?
  • 2. TWITTER / GITHUB: @harph SAN JOSE, CA 2 HARRINGTON JOSEPH SR. SOFTWARE ENGINEER
  • 3. EXPECTATIONS WHY, HOW AND WHEN TO USE STATE MACHINES
  • 5. ● is_active ● active ● is_enabled ● enabled ● is_disabled ● disabled ● has_expired ● expired ● is_published ● published ● is_deleted ● deleted ● is_archived ● archived ● is_visible ● visible ● is_hidden ● hidden ● is_ready ● ready ● is_valid ● valid ● is_blocked ● blocked ● failed ● succeeded ● is_positive ● ...
  • 6. THE PROBLEM USING BOOLEANS TO REPRESENT STATES AND ENFORCE BUSINESS RULES
  • 8. class Video: def __init__(self, source): self.source = source self.is_playing = False def pause(self): # Make the call to pause the video self.is_playing = False def play(self): # Make the call to play the video self.is_playing = True def stop(self): # Make the call to stop the video self.is_playing = False
  • 12. video.is_playing False Is it paused? Is it stopped?
  • 13. class Video: def __init__(self, source): self.source = source self.is_playing = False self.is_paused = False def pause(self): # Make the call to pause the video self.is_playing = False self.is_paused = True def play(self): # Make the call to play the video self.is_playing = True self.is_paused = False def stop(self): # Make the call to stop the video self.is_playing = False self.is_paused = False
  • 14. Is the video playing? video.is_playing Is the video paused? video.is_paused Is the video stopped? not video.is_playing and not video.is_paused
  • 15. BUSINESS RULES 1. A video can only be played when is paused or stopped. 2. A video can only be paused when is playing. 3. A video can only be stopped when is playing or paused.
  • 16. class Video: ... def play(self): if not self.is_playing or self.is_paused: # Make the call to play the video self.is_playing = True self.is_paused = False else: raise Exception( 'Cannot play a video that is ' 'already playing.' ) 1. A video can only be played when is paused or stopped.
  • 17. class Video: ... def pause(self): if self.is_playing: # Make the call to pause the video self.is_playing = False self.is_paused = True else: raise Exception( 'Cannot pause a video that is ' 'not playing.' ) 2. A video can only be paused when is playing.
  • 18. class Video: ... def stop(self): if self.is_playing or self.is_paused: # Make the call to stop the video self.is_playing = False self.is_paused = False else: raise Exception( 'Cannot stop a video that is ' 'not playing or paused.' ) 3. A video can only be stopped when is playing or paused.
  • 19. THE CODE IS RAPIDLY BECOMING ● Complex. ● Bloated. ● Repetitive. ● Hard to test.
  • 20. class Video: # States PLAYING = 'playing' PAUSED = 'paused' STOPPED = 'stopped' def __init__(self, source): self.source = source self.state = self.STOPPED
  • 21. class Video: ... def play(self): if self.state != self.PLAYING: # Make the call to play the video self.state = self.PLAYING else: raise Exception( 'Cannot play a video that is ' 'already playing.' ) 1. A video can only be played when is paused or stopped.
  • 22. class Video: ... def pause(self): if self.state == self.PLAYING: # Make the call to pause the video self.state = self.PAUSED else: raise Exception( 'Cannot pause a video that is ' 'not playing.' ) 2. A video can only be paused when is playing.
  • 23. class Video: ... def stop(self): if self.state != self.STOP: # Make the call to stop the video self.state = self.STOPPED else: raise Exception( 'Cannot stop a video that is ' 'not playing or paused.' ) 3. A video can only be stopped when is playing or paused.
  • 25. WHAT'S A STATE MACHINE? ● Finite number of states. Mathematical model of computation. ● Transitions between states. ● Machine. Can only be in one state at a given time.
  • 27. DESIGNING A STATE MACHINE 1. Define a finite number of states. 2. Lay down the transitions between states. 3. Select the initial state.
  • 28. 1. Define a finite number of states.
  • 29. 2. Lay down the transitions between states.
  • 30. 3. Select the initial state.
  • 31. CODE
  • 33. from transitions import Machine class Video: # Define the states PLAYING = 'playing' PAUSED = 'paused' STOPPED = 'stopped'
  • 34. from transitions import Machine class Video: # Define the states PLAYING = 'playing' PAUSED = 'paused' STOPPED = 'stopped' def __init__(self, source): self.source = source # Define the transitions transitions = [ # 1. A video can only be played when is paused or stopped. {'trigger': 'play', 'source': self.PAUSED, 'dest': self.PLAYING}, {'trigger': 'play', 'source': self.STOPPED, 'dest': self.PLAYING}, # 2. A video can only be paused when is playing. {'trigger': 'pause', 'source': self.PLAYING, 'dest': self.PAUSED}, # 3. A video can only be stopped when is playing or paused. {'trigger': 'stop', 'source': self.PLAYING, 'dest': self.STOPPED}, {'trigger': 'stop', 'source': self.PAUSED, 'dest': self.STOPPED}, ]
  • 35. from transitions import Machine class Video: ... def __init__(self, source): self.source = source # Define the transitions transitions = [ # 1. A video can only be played when is paused or stopped. {'trigger': 'play', 'source': self.PAUSED, 'dest': self.PLAYING}, {'trigger': 'play', 'source': self.STOPPED, 'dest': self.PLAYING}, # 2. A video can only be paused when is playing. {'trigger': 'pause', 'source': self.PLAYING, 'dest': self.PAUSED}, # 3. A video can only be stopped when is playing or paused. {'trigger': 'stop', 'source': self.PLAYING, 'dest': self.STOPPED}, {'trigger': 'stop', 'source': self.PAUSED, 'dest': self.STOPPED}, ] # Create the state machine self.machine = Machine( model=self, transitions=transitions, initial=self.STOPPED )
  • 36. class Video: ... def pause(self): # Make the call to pause the video ... def play(self): # Make the call to play the video ... def stop(self): # Make the call to stop the video ...
  • 37. video = Video('s3://video/storage/demo.mov') video.play() # State is 'playing' video.state # 'playing' video.pause() # State is 'paused' video.stop() # State is 'stopped' video.pause() # ??? MachineError: "Can't trigger event pause from state stopped!"
  • 38. TESTING HOW DO WE TEST THIS? 1. We don't. 2. Machine is initialized with the expected transitions and initial state. 3. Actual functionality ( play, pause and stop ).
  • 40. RULES 1. A video can only be played when is paused, stopped or rewinding. 2. A video can only be paused when is playing or rewinding. 3. A video can only be stopped when is playing, paused or rewinding. 4. A video can only be rewinded when is playing or paused.
  • 41. from transitions import Machine class Video: ... REWINDING = 'rewinding' def __init__(self, source): ... transitions = [ # 1. A video can only be played when is paused, stopped or rewinding. {'trigger': 'play', 'source': self.PAUSED, 'dest': self.PLAYING}, {'trigger': 'play', 'source': self.STOPPED, 'dest': self.PLAYING}, {'trigger': 'play', 'source': self.REWINDING, 'dest': self.PLAYING}, # 2. A video can only be paused when is playing or rewinding. {'trigger': 'pause', 'source': self.PLAYING, 'dest': self.PAUSED}, {'trigger': 'pause', 'source': self.REWINDING, 'dest': self.PAUSED}, # 3. A video can only be stopped when is playing, paused or rewinding. {'trigger': 'stop', 'source': self.PLAYING, 'dest': self.STOPPED}, {'trigger': 'stop', 'source': self.PAUSED, 'dest': self.STOPPED}, {'trigger': 'stop', 'source': self.REWINDING, 'dest': self.STOPPED}, # 4. A video can only be rewinded when is playing or paused. {'trigger': 'rewind', 'source': self.PLAYING, 'dest': self.REWINDING}, {'trigger': 'rewind', 'source': self.PAUSED, 'dest': self.REWINDING}, ] ...
  • 42. WHEN ARE BOOLEANS NOT ENOUGH? ● When multiple booleans represent a single state. ● When business rules are enforced by multiple booleans.
  • 43. WHEN TO USE STATE MACHINES? ● When states are not binary. ● When you have to account for future states. ● When you have to enforce a complex set of business rules.
  • 44. TAKEAWAYS ● Using booleans to represent states can get messy quite fast. ● Enforcing business rules by inferring the state from a set of booleans leads to unreadable, unmaintainable and hard to test code. ● State machines are not a silver bullet. ● State machines remove the complexity of testing business rules.