DEV Community 👩‍💻👨‍💻

Cover image for The Use/Reuse paradox explained
Coding Unicorn 🦄
Coding Unicorn 🦄

Posted on

The Use/Reuse paradox explained

The Use/Reuse Paradox

When designing code, it's important to understand who will consume it. Do you design it for a single specific use-case? Or do you want to cover many different use cases?

✅ You can pluralise English words with a single loc:

function pluralize(amount, item) {
  return amount === 1 ? item : `${item}s`
}
Enter fullscreen mode Exit fullscreen mode

The solution is short and straightforward, because it's optimized for your specific use case – English pluratization.

Now, let's try to implement English pluratization using Intl.PluralRules. It's a JavaScript API, designed to support different languages and pluratization rules.

❌ The code becomes more complicated:

function pluralize(amount, item) {
  const suffixes = new Map([
    ['one',   item],
    ['other', item + 's'],
  ]);
  const rules = new Intl.PluralRules('en-US');
  const rule = rules.select(amount);
  const suffix = suffixes.get(rule);
  return suffix;
}
Enter fullscreen mode Exit fullscreen mode

See the difference? English-only code is easy to use. Reusable code is hard to use, because flexibility breeds complexity. This is the main idea of "The Use/Reuse Paradox":

What's easy to reuse is hard to use; what's easy to use is hard too reuse.

I recommend thinking about this principle for a while, because it's one of the most important principles of software architecture and design: with rare exceptions, simplicity and flexibility are opposing forces.

Alt Text

Agree/disagree? 🦄

Top comments (3)

Collapse
 
gklijs profile image
Gerard Klijs

Totally agree, especially for libraries it's hard, since you don't really know how they will be used. Ones sensible defaults might not me the same as ones others sensible default.

In the middle of adding functionality to a library now..

Collapse
 
judgegroovyman profile image
JudgeGroovyman

I've never written a library but I'm sure you are right. You are probably done already but my gut says to trust yourself and in this case trusting yourself would look like designing the library to be opinionated toward your sensible defaults and your use cases and then later letting generalizations come one by one so you can evaluate: do these add broadly valuable capability with low baggage? those are my two cents.

Collapse
 
judgegroovyman profile image
JudgeGroovyman • Edited on

I was just thinking about this yesterday when I found this cool programming language called 'Cuis' which is a variant of Smalltalk. On their website they take this paradox seriously (although they dont refer to it explicitly) saying:

"Unbound complexity growth, together with development strategies focused only in the short term, are the worst long term enemies of all software systems. As systems grow older, they usually become more complex. New features are added as layers on top of whatever is below, sometimes without really understanding it, and almost always without modifying it. Complexity and size grow without control. Evolution slows down. Understanding the system becomes harder every day. Bugs are harder to fix. Codebases become huge for no clear reason. At some point, the system can't evolve anymore and becomes legacy code.Complexity puts a limit to the level of understanding of the system a person might reach, and therefore limits the things that can be done with it"
(that was from github.com/Cuis-Smalltalk/Cuis-Sma...)

🌚 Browsing with dark mode makes you a better developer.

It's a scientific fact.