5 ms·
I actually agree with the Author's issues around hidden mutable state. Luke Galea introduced me to the term "Candy Machine Interface" for this, where you keep p
by raganwald 17y ago
I actually agree with the Author's issues around hidden mutable state. Luke Galea introduced me to the term "Candy Machine Interface" for this, where you keep pulling levers and pushing buttons and you have no idea how to get the candy you want out of the machine.
I also agree that the "real world" does this some times, but there is a difference between writing simulations of the real world and writing programs. I'm not disturbed by the idea of objects encapsulating hidden state, but rather the idea that objects have static, invariant interfaces.
One of the nicer ideas for dealing with this is to write explicit state machines and where (if your language allows) the interface actually changes as the state changes. If o.a(); o.b(); is different than o.b(); o.a();, you can write a state machine that makes this inspectable and explicit. If o.b() makes no sense until you call o.a(), you can simply not have o.b() be part of o's API/interface until you call o.a().
I won't suggest this is a general programming heuristic, but my experience in the last couple of years is that every business object modeling a real-world business entity ought to be implemented as a state machine until you discover a compelling reason to do something else. Ad-hoc state machines, like having the logic for whether o.b() does x or y based on the contents of fields _a and _b be embedded in the method b() are the stateful equivalent of spaghetti-coding with GOTO.
I credit Pete Forde for shaking me out of the complacent belief that I'm smart enough to embed everything in methods.
- gdp 17y agoThat's quite a nice idea! I certainly hadn't thought of that. I would upvote this several million times if I could. Another thing that sometimes makes sense is Model-Based Testing (I was involved in the ModelJUnit project - http://www.cs.waikato.ac.nz/~marku/mbt/modeljunit/ http://www.cs.waikato.ac.nz/~marku/mbt/modeljunit/ - for example). It can sometimes catch these kinds of subtle API misuse issues. Finally, I did some work on a tool that will statically analyse a program and that will attempt to ensure that action a() never occurs before action b(), for example. I wrote a blog post about it a few days ago: http://www.plsadventures.com/2009/08/prototype-static-analysis-tool-for.html http://www.plsadventures.com/2009/08/prototype-static-analys... So it's not like it's an insurmountable problem (people manage to produce software!), but I definitely like your suggestion of using explicit state machines whenever you insist on using mutable state.
- pchristensen 17y agorags, I wish you still wrote your blog. There was no better place to find mind-blowing stuff like that. You talk about different things because they're important, not because you were trying to be contrarian to get attention.
- chipsy 17y agoI find that a lot of my programming problems break down to a few of the same categories: State manipulation Data introspection Data formats Concurrent operations Basically, things are hunky-dory so long as I have a simple data structure that every part of my program can use in the exact same way without destroying performance or entangling its operations with the rest of the program's state. It almost never quite works out like that for a non-trivial program. Hence I end up writing more complex data structures that can generate appropriate views and manipulations of data, state machines to formalize the order of operations and the resource management, and DSLs to generate functionality from data rather than repetitive code. I think a big improvement would result just from building a convenient state machine syntax into the language.
- wwalker3 17y agoThis is a mind-blowing and cool idea as others have said, but the idea of an object whose methods change depending on their internal state is a bit counter-intuitive. Real-world objects don't have this property -- it would be like the gas tank hatch disappearing from my car after I fill it up, and reappearing once I drive around for a minute.
- raganwald 17y agoReal world objects don't have this property? Some do. When the gear shift lever on my Mazda is in one of the automatic slots, you can't upshift or downshift manually. In business this is even more obvious. Contracts might have states: proposed, drafted, agreed, signed, and so forth. You can't sign a draft, it has no meaning. That's part of the business process.
- wwalker3 17y agoNot quite the same. Your Mazda shift lever's manual slot doesn't disappear when you're in automatic. You can still sign a draft contract, it's just not binding. In the software case you explained, the interface changes so you can't even try to do the wrong thing. On real-world objects, you can always try to do the wrong thing, it just doesn't work.
- raganwald 17y agoYou cannot sign a draft, signing is a legal thing, not just a putting your name on a piece of paper thing. Imagine you're a manager and you call your EA: "Henderson, get me the YC contract to sign!" Henderson replies back on the squack box: "Sorry sir, it's still a draft, it has to be approved by legal before you can sign it." > Your Mazda shift lever's manual slot doesn't disappear when you're in automatic No it doesn't, but you can't actually move the lever there without changing the gearbox's state from Drive to Manual. So, we can say that it has an interface including the messages "+" and "-" at all times (The slot), but there's no way to send it a "+" or a "-" message unless the gearbox state is "M."
- dasil003 17y ago
- joe_the_user 17y agoThe smartness required to implement and/use a language feature which could catch some given error such as this at compile/parse time would be much greater than the smartest that today's OO has/requires. I agree that encapsulation and full object-orientation are pretty much ideological - an object encapsulating what would otherwise be a two-member structure but with twenty members is an example of OO's horror. But if you avoid Bondage and Discipline Languages (java, c#), OO doesn't have to be that. I've gone from Ruby back to c++ with Qt, and I find c++ nearly as good IF I let myself be comfortable with public member variable since I have access to easy, flexible list/hash object via Qt. The simple approach - small objects that interface in an ad-hoc way with each PLUS big, well defined, flexible interfaces between real, functional divisions of the code. It does require a thought-out design separate from the immediate implementation but a little thinking is good. Not all the "big, upfront design" stuff was bad.
- raganwald 17y ago> an object encapsulating what would otherwise be a two-member structure but with twenty members is an example of OO's horror. Reminds me of: If you have a procedure with ten parameters, you probably missed some. http://www.cs.yale.edu/quotes.html http://www.cs.yale.edu/quotes.html