4 ms·
> 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-desi
by goto11 6y ago
> 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 IMHO, since you can't predict the future. A requirement change may happen in a completely different direction than the one you anticipated, and then you have the worst of both worlds.
It is better to make code maintainable than making it flexible.
- tonyarkles 6y ago> since you can't predict the future That's one of those statements that makes sense, but is often not true. Very rarely does a client comes to me with a feature request that does require a pretty significant design change, but most of the time they're changes that were foreseen. Using this current article as an example, I love the way that they're storing the intervals to guarantee that they can't overlap. That's awesome! What I would likely end up doing, though, is use that as the underlying representation but still return individual interval objects through the query API with a start and end date on each interval. That way, if the "only one at a time" rule changes, the changes required are localized.
- philwelch 6y ago> Using this current article as an example, I love the way that they're storing the intervals to guarantee that they can't overlap. That's awesome! What I would likely end up doing, though, is use that as the underlying representation but still return individual interval objects through the query API with a start and end date on each interval. The article addresses that concept: > It is sometimes still useful to represent the periods as a sequence of start and end dates. It is trivial to project the set of dates in to this form. As long as the canonical representation is the set, the constraints will still hold.
- hondo77 6y ago> What I would likely end up doing, though, is use that as the underlying representation but still return individual interval objects through the query API with a start and end date on each interval. How the model you present to the user is represented in the database is an implementation detail.
- judofyr 6y ago> Yes, if requirements change, you change the design and code to support the new requirements. Code and representation (i.e. schema) are vastly different. In my experience it's takes an order of magnitude longer to change a representation than to change code. Once there are multiple services/tools which works with a representation you typically have to support both the new and the old representation at the same time (since you can't rollout everything simultaneously). > Compromising the consistency and maintainability of the current design to accommodate a hypothetical future requirement change is a bad trade-off IMHO Designing a representation which can handle possible requirement changes does not necessarily mean "compromising the consistency and maintainability". We have great tools for ensuring consistency (e.g. transactions and constraints in SQL databases), and I don't exactly see how this new representation is more "maintainable" than the old one (although we don't have all the information in this article).
- skybrian 6y agoGetting good at data migrations (with tools and processes to do this) can pay off. It's a more general way of preparing for the future than attempting to anticipate specific changes. On the other hand, some may say YAGNI.
- philwelch 6y agoI 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.
- cle 6y agoI've seen this too. And I've also seen the converse--complexity that was added because engineers refused anything but the most myopic designs, using thought-terminating cliches like "YAGNI" or "that's hypothetical". "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.
- goto11 6y agoUnder what circumstances did following YAGNI lead to added complexity?
- tsimionescu 6y agoA common pattern is writing code as a series of isolated cases, when taking some time to design the general case would greatly reduce the amount of code. You add a bool parameter to a function to modify one small bit of what it does, then another one, and you add some new return value, and before long, you've got a class with several getters and instance variables represented as code in a single function, with parameters controlling which actual method is run.
- goto11 6y agoWhat you describe a development style where the first iteration is well-designed but subsequent modifications are applied as a series of hacks and kludges. This way any code will turn into a big ball of mud over time. This is a problem. But trying to anticipate everything in the first iteration is not the solution. The solution is to write maintainable code and apply each change with the same discipline and thought which was used when in the initial iteration. Follow the boy scout rule: After any change, the code should be in a better state than before.