https://fsharpforfunandprofit.com/series/designing-with-type...
Applying “make invalid states unrepresentable”
131–140 of 193 posts
Re: Applying “make invalid states unrepresentable”
#132While this is great if you know exactly what you want to achieve, it does “lock you in” those constraints on a more fundamental level. More times than I can count I’ve seen business requirements change to require those “unrepresentable” states, and since you’ve now designed you whole data model around it you need to add awful hacks to make it work. The timeline example is actually very telling. A lot of times you’d a…
Additionally, turning (startDate, endDate) into a set of dates will make the code more complex in some places. Before: SELECT event FROM events WHERE endDate After: Whatever additional complexity you add to your codebase to query end dates.
https://dbfiddle.uk/?rdbms=postgres_11&fiddle=50e6a963cd1db0...
(YMMV, obvs.)
Re: Applying “make invalid states unrepresentable”
#133Earlier quoted context omitted.
> Multiple times I've designed systems where I've reduced the representable states to the minimum, and when some requirements change I realize I have to re-design the full system. Yes, if requirements change, you change the design and code to support the new requirements. Compromising the consistency and maintainability of the current design to accommodate a hypothetical future requirement change is a bad trade-off I…
I like to call this, "speculative complexity". I've seen many cases where speculative complexity was added, and persisted for a long time, for reasons that fundamentally mispredicted the way the system would evolve and actually inhibited that evolution.
"Never think ahead" is obviously not good advice. There's no silver bullet here--we have to think about how likely future scenarios are, and plan for them based on the business context and needs. Many of them are unlikely or too costly to do anything about...and many of them aren't.
Re: Applying “make invalid states unrepresentable”
#134Earlier quoted context omitted.
> And how many integers should actually be strings, unless you're dead sure this is a number. I phrase this as: If it doesn't make sense to do math on it, it's not a number. What does adding one to a customer account number mean? Absolutely nothing -- you get a completely different account number. So it's not a number, but a numeric string.
It's not a string either though: in the same way integer addition (almost always) does not make sense, string concatenation (almost always) does not make sense either. The proper type would allow for equality check and explicit string (de)serialization only.
Re: Applying “make invalid states unrepresentable”
#135Earlier quoted context omitted.
> If this is part of your specification, have a DefaultContract entity of some kind somewhere. Yes, but not in the database table for contracts. That's how I read this part of the post. I would expect the assumption that if the customer doesn't have a fixed contract, they are on a default contract to be encoded in business logic somewhere in an application that uses this database.
> I would expect the assumption that if the customer doesn't have a fixed contract, they are on a default contract to be encoded in business logic somewhere in an application that uses this database. That's exactly the kind of harmful assumption I'm talking about. Harmful in that when people act on that assumption and actually implement it that way. How a default contract might be represented may vary, and of course…
But you're saying it does need to be represented somewhere in the database? That putting it anywhere else is harmful?
Can you elaborate? Why is it harmful?
Re: Applying “make invalid states unrepresentable”
#136Earlier quoted context omitted.
This is partly why I've found it helpful to wait until there are at least 3 identical (not nearly identical) implementations of something before trying to make a more generic/abstracted version of it.
I think these rules of thumb are... okay. But I think it's more helpful to go back to how DRY was initially defined ("Every piece of knowledge must have a single, unambiguous, authoritative representation within a system") and ask whether what I'm dealing with is actually "a piece of knowledge." There can be 10 identical copies, and if they just happen to be identical but they represent different things that might ch…
Re: Applying “make invalid states unrepresentable”
#137Earlier quoted context omitted.
> If this is part of your specification, have a DefaultContract entity of some kind somewhere. Yes, but not in the database table for contracts. That's how I read this part of the post. I would expect the assumption that if the customer doesn't have a fixed contract, they are on a default contract to be encoded in business logic somewhere in an application that uses this database.
> I would expect the assumption that if the customer doesn't have a fixed contract, they are on a default contract to be encoded in business logic somewhere in an application that uses this database. That's exactly the kind of harmful assumption I'm talking about. Harmful in that when people act on that assumption and actually implement it that way. How a default contract might be represented may vary, and of course…
The concept of a "contract" is a business logic concept to begin with. That concept is represented in the application already. How (or whether) the data associated with a particular contract is stored in the database is an implementation detail.
Re: Applying “make invalid states unrepresentable”
#138Re: Applying “make invalid states unrepresentable”
#139Software engineer here. Does anyone have any questions?
Re: Applying “make invalid states unrepresentable”
#140Keep the model sensible. Contracts belong to contracts. Add basic sanity to the model. The service that manages the data guards the data beyond basic data model sanity checks. Also, explicit is better than implicit.