Thinking in States
Thinking in States
Niclas Nilsson
PEOPLE IN THE REAL WORLD HAVE A WEIRD RELATIONSHIP WITH STATE.
This morning, I stopped by the local store to prepare for another day of con- verting caffeine to code. Since my favorite way of doing that is by drinking lattes, and I couldn’t find any milk, I asked the clerk.
“Sorry, we’re super-duper, mega–out of milk.”
To a programmer, that’s an odd statement. You’re either out of milk, or you’re not. There is no scale when it comes to being out of milk. Perhaps she was try- ing to tell me that they’d be out of milk for a week, but the outcome was the same—espresso day for me.
In most real-world situations, people’s relaxed attitude toward state is not an issue. Unfortunately, however, many programmers are quite vague about state, too—and that is a problem.
Consider a simple webshop that only accepts credit cards and does not invoice customers, with an Order class containing this method:
public boolean isComplete() {
return isPaid() && hasShipped();
}
Reasonable, right? Well, even if the expression is nicely extracted into a method instead of copy ’n’ pasted everywhere, the expression shouldn’t exist at all. The fact that it does highlights a problem. Why? Because an order can’t be shipped before it’s paid. Thereby, hasShipped can’t be true unless isPaid is true, which makes part of the expression redundant. You may still want isComplete for clarity in the code, but then it should look like this:
public boolean isComplete() {
return hasShipped();
}
168
97 Things Every Programmer Should Know

In my work, I see both missing checks and redundant checks all the time. This example is tiny, but when you add cancellation and repayment, it’ll become more complex, and the need for good state handling increases. In this case, an order can only be in one of three distinct states:
• In progress: Can add or remove items. Can’t ship.
• Paid: Can’t add or remove items. Can be shipped.
• Shipped: Done. No more changes accepted.
These states are important, and you need to check that you’re in the expected state before doing operations, and that you only move to a legal state from where you are. In short, you have to protect your objects carefully, in the right places.
But how do you begin thinking in states? Extracting expressions to meaningful methods is a very good start, but it is just a start. The foundation is to under- stand state machines. I know you may have bad memories from CS class, but leave them behind. State machines are not particularly hard. Visualize them to make them simple to understand and easy to talk about. Test-drive your code to unravel valid and invalid states and transitions and to keep them correct. Study the State pattern. When you feel comfortable, read up on Design by Contract. It helps you ensure a valid state by validating incoming data and the object itself on entry and exit of each public method.
If your state is incorrect, there’s a bug, and you risk trashing data if you don’t abort. If you find the state checks to be noise, learn how to use a tool, code generation, weaving, or aspects to hide them. Regardless of which approach you pick, thinking in states will make your code simpler and more robust.
Thinking in States的更多相关文章
- Life Cycle of Thread – Understanding Thread States in Java
Life Cycle of Thread – Understanding Thread States in Java 深入理解java线程生命周期. Understanding Life Cycle ...
- Hover States - 有趣的用户界面及交互设计
Hover States 一组新潮的和有趣的用户界面和交互设计的集合.Hover States 的目标是要成为设计师和开发人员灵感来源,向人们展示目前人们正在做的各种网站中令人惊奇的效果.他们认为交互 ...
- Channel States
Introduction A channel (a call) will go through many different states during its lifetime. Here we w ...
- flex4的s:states和mx:states的区别
http://help.adobe.com/en_US/Flex/4.0/UsingSDK/WS2db454920e96a9e51e63e3d11c0bf63611-7ffa.html#WS43468 ...
- How to Programmatically Switch between the HubTile Visual States
In this post I am going to talk about how to programmatically switch between different HubTile Visua ...
- PROCESS STATES
COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION To understand the ope ...
- [Angular2 Form] Understand the Angular 2 States of Inputs: Pristine and Untouched
Angular 2’s ngModel exposes more than just validity, it even gives you the states of whether the inp ...
- codeforces 590C C. Three States(bfs+连通块之间的最短距离)
题目链接: C. Three States time limit per test 5 seconds memory limit per test 512 megabytes input standa ...
- Codeforces Round #327 (Div. 2) E. Three States
题目链接: 题目 E. Three States time limit per test:5 seconds memory limit per test:512 megabytes 问题描述 The ...
- I.MX6 show battery states in commandLine
#/bin/sh # I.MX6 show battery states in commandLine # 声明: # 在命令行下自动显示电池状态的信息. # # -- # set battery r ...
随机推荐
- React和Vue中,是如何监听变量变化的
React 中事件监听 本地调试React代码的方法 先将React代码下载到本地,进入项目文件夹后yarn build 利用create-react-app创建一个自己的项目 把react源码和自己 ...
- axios统一拦截配置
在vue项目中,和后台进行数据交互使用axios.要想统一处理所有的http请求和响应,就需要使用axios的拦截器.通过配置http response inteceptor 统一拦截后台的接口数据, ...
- python基础,函数,面向对象,模块练习
---恢复内容开始--- python基础,函数,面向对象,模块练习 1,简述python中基本数据类型中表示False的数据有哪些? # [] {} () None 0 2,位和字节的关系? # ...
- springboot的几个缓存相关注解
@Cacheable:查询 几个属性: cacheNames/value:指定缓存组件的名字: key:缓存数据使用的key,可以用来指定.默认即使用方法参数的值 keyGenerator ...
- 【BZOJ 1305】[CQOI2009]dance跳舞
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 男生和女生每个人都分身成两个节点 即x[1],x[2]和y[1],y[2] 然后如果i和j不相互喜欢 那么add(x[i][2],y ...
- 【codeforces 747E】Comments
[题目链接]:http://codeforces.com/problemset/problem/747/E [题意] 给你一个类似递归的结构; 让你把每一层的字符串按照层,一层层地输出出来; 并输出层 ...
- shiro + maven 的web配置(不整合spring)
本文采用的是1.4.0版本的shiro 官方中说的1.2之前,和之后的shiro配置分别为: 1.2之前: <filter> <filter-name>iniShiroFilt ...
- [Hyperapp] Render Text with JSX in Hyperapp
Hyperapp is an ultra lightweight (1kb), minimal, functional, JavaScript library for building UIs. It ...
- Knockout源代码精析-怎样解析demo元素,获取到bindings(二)?
接上文这里開始分析applyBindingsToNodeInternal.applyBindingsToNodeInternal方法例如以下: function applyBindingsToNode ...
- JDBC创建mysql连接池代码
1.底层实现类(DBConnection) package JDBC.JDBCPool.MyJDBCPool; import java.sql.Connection; import java.sql. ...