I'm not sure I agree.

My perfunctory reading is thus: first you couple your state representation to the business logic, and make some states unrepresentable (say every client is category A, B or C). Maybe you allow yourself some flexibility, like you can add more client types.

Then the business people come and tell you some new client is both A and B, and maybe Z as well, quickly now, type type type.

And that there's a tradeoff between:

- eliminating invalid states, leading to less errors, and

- inflexibility in changes to the business logic down the way.

Maybe I misunderstood, but if this is right, then it's a good point. And I would add: when modelling some business logic, ask yourself how likely it is to change. If it's something pretty concrete and immovable, feel free to make the representation rigid. But if not, and even if the business people insist otherwise, look for ways to retain flexibility down the line, even if it means some invalid states are indeed representable in code.

IMO, rather than focusing on flexibility vs inflexibility when deciding "tight domain model" or not, it's much better to think about whether your program requirement can tolerate some bugs or not.

Say we have a perfect "make illegal states unrepresentable" model. Like what you said, it's kind of inflexible when there are requirement changes. We need to change affected codes before you can even proceed to compile & run.

On the other hand, an untyped system is flexible. Just look at Javascript & Python ecosystem, a function might even contain a somewhat insane and gibberish statement, yet your program might still run but will throw some error at runtime.

Some bugs in programs like games or average webapp don't matter that much. We can fix it later when users report the bug.

While it's probably better to catch whether an user can withdraw a negative balance or not at compile time, as we don't want to introduce "infinite money glitch" bug.

Types are part of the picture, sure. But there's more. Essentially, I'd say, if your whole business logic representation needs a major refactor every time the underlying changes, then you better enjoy refactoring.