I like this. Now I have a fancy sounding name that I can throw around to counter some of the other fancy ideas that lead us to scatter logic all over the place.
In my opinion, which often seems like a minority opinion on the teams I've worked in, these questions should be (made) easy to answer:
- Where is this thing defined? For example a method. Surprisingly often it's hidden in a concern, behind a wall of indirections, or even generated by some clever metaprogramming.
- What happens when this thing runs? Hidden side-effects, nested method calls 17 layers deep, operator overloading, and interfaces can all make this harder.
- Why did this code run? Seems like it should be an easy thing to answer, but imagine that the stack trace is truncated because of some creative use of exception handling as control flow, that the call was made from a different process, or that it's in a callback that's been passed around like a hot potato.
I have a hunch that these kind of problems often pops up when you treat state and logic as two separate things. Then the way your code is organized won't match how state is managed. State transitions can happen anywhere, and the customer won't be reassured to know you used a great design pattern if it still takes you a week to figure out why their account balance turned negative, why their bill was sent twice, or why some users suddenly have access to things they shouldn't.
Some solutions I can think of:
- State machines, since they make state transitions very explicit.
- Functional programming to some extent. Immutability and pure functions might force you to handle state explicitly. It's still easy to make the logic messy though.
- I believe reactive programming is mainly an attempt to solve this? Are there any good implementations for other uses than front-end apps? Does it go by a different name?
- Hexagonal architecture?
What are some nice solutions that you've seen to these things? Patterns that take you in the direction of making critical things easy or even trivial to understand.
In my opinion, which often seems like a minority opinion on the teams I've worked in, these questions should be (made) easy to answer:
- Where is this thing defined? For example a method. Surprisingly often it's hidden in a concern, behind a wall of indirections, or even generated by some clever metaprogramming.
- What happens when this thing runs? Hidden side-effects, nested method calls 17 layers deep, operator overloading, and interfaces can all make this harder.
- Why did this code run? Seems like it should be an easy thing to answer, but imagine that the stack trace is truncated because of some creative use of exception handling as control flow, that the call was made from a different process, or that it's in a callback that's been passed around like a hot potato.
I have a hunch that these kind of problems often pops up when you treat state and logic as two separate things. Then the way your code is organized won't match how state is managed. State transitions can happen anywhere, and the customer won't be reassured to know you used a great design pattern if it still takes you a week to figure out why their account balance turned negative, why their bill was sent twice, or why some users suddenly have access to things they shouldn't.
Some solutions I can think of:
- State machines, since they make state transitions very explicit.
- Functional programming to some extent. Immutability and pure functions might force you to handle state explicitly. It's still easy to make the logic messy though.
- I believe reactive programming is mainly an attempt to solve this? Are there any good implementations for other uses than front-end apps? Does it go by a different name?
- Hexagonal architecture?
What are some nice solutions that you've seen to these things? Patterns that take you in the direction of making critical things easy or even trivial to understand.