10 Comments

Not bad ideas here but I think there's some issues that need addressed. Don't confuse DRY with bad design. The idea behind DRY is to abstract and encapsulate in case you need code later, not create bad design trying to make the perfect function or class. The example provided actually breaks SOLID principles so it should never happen if DRY is applied correctly. You should also never setup local servers in unit tests. I don't care what Google says. Google has hundreds of developers that do nothing more than write internal tooling. Have you seen a large CI/CD pipeline with in-memory servers running? It can take up to 20 minutes for a deployment depending on the size of the project. Especially if you're a monorepo team taking advantage of GitOps, in-memory anything will be a nightmare to handle.

Expand full comment

PRY is more commonly known as Write Everything Twice (WET)

Expand full comment

I thought, its yet another post on SOLID but thanks for presenting new views.

Expand full comment

I'm sorry, but I'm a bit lost on your example in point 4. What is the link between cache and mutable state?

Expand full comment

I would also add YAGNI and SOLID to this list

Expand full comment

Thanks for the points! Agree with not overusing mocks. Best case is having a design that enables the testing pyramid with easy unit tests and integration tests for stuff with more dependencies. As you mentioned, boundaries can get blurry here.

Expand full comment

I once accidentally followed #4 to the letter. It was an API in PHP and every interaction started with a clean controller context and /v1/entity/{id} being pulled from the DB. 99% of the time my service wasn't to blame.

Expand full comment

I don't think you hit the nail on the head but I believe you're into something. Repetition, sync, single source of truth, and mutability/derivative data... They all intersect. Example: don't repeat yourself if it's, say, am upload path where one service writes and another reads from. But DO repeat yourself for one-liner ops that are as basic and common as a simple reduce on an array. It's when you need reliable consistency that DRY is important. I've seen so many hotshot devs in interviews write a "reusable react hook" just to demonstrate reliability when the operation is not ever possibly in a million years going to be anything more than a basic one-liner anyway. Why I took points off is because: they just turned 10 one-liners into ... 10 slightly different one-liners + 1 file with 5 lines that everyone has to study to determine what it's purpose is (because why does it exist)... and now everyone has to understand how to use YOUR code instead of just the framework or language itself. And you may have done that in purpose which has me thinking you are pathological. So don't do it. Overall, you just won't have many of these issues if you write small, SOLID, egoless code. Any issue you do encounter will be MUCH easier to deal with. Lastly, use a Sandbox for you apps. Just try it. It solves 80% (or more) of the problems everybody in every shop constantly always repeatedly painstakingly stumble on and faceplant on -- security, testing, coupling, scaffolding, reliability, consistency, readability, debugging, and my favorite -- developer experience :)

Expand full comment

To your #1 - what about operational data for analytical purposes? What about analytical data for machine learning models?

Expand full comment

I think in some ways 1 and 2 are related. You don't want to repeat your sources of truth (or, alternatively, "places where decisions are made"). But you do need to be sure that what you're trying to unify via DRY is actually the same thing. Semantics is key over syntax. Whether code actually looks the same ends up being irrelevant - I have "++i" all over my code. :) And you can have two pieces of code that are doing the same thing that don't actually look alike.

(I had a thought relating 1 to 4 - don't store state you can compute = single source of truth - but I went back and realized you had already addressed that.)

Great article, by the way!

Expand full comment