2

DRY & the Wrong Abstraction

 2 years ago
source link: https://dev.to/nickytonline/dry-the-wrong-abstraction-33i8
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Cover image for DRY & the Wrong Abstraction
Nick Taylor

Posted on Apr 22

DRY & the Wrong Abstraction

I was chatting with someone in my Virtual Coffee community today, and they were talking about acronyms, because we love to create acronyms in tech. DRY came up, a.k.a. Don't Repeat Yourself, and then we got to talking about sometimes it's fine not to be DRY. I referenced Sandi Metz's great post, The Wrong Abstraction and a great talk by Sebastien Markbage (former React core team member), Minimal API Surface Area at JSConf 2014.

So with all that set up, let's hear from you, the community, on when to maybe DRY it up and maybe when not to. It'd be great to hear about real world examples to help others in their developer journey.

Photo by Jr Korpa on Unsplash

Discussion (20)

pic

Collapse

Expand

I agree and have been pretending I'm in support of DRY all the time, I don't always think it's good to put all your eggs in one basket abstraction. When do you stop, is this overdone? Just more problems sometimes

Comment button Reply

Collapse

Expand

ECSS covers an interesting anti dry concept because it's more decoupled and easier to remove

Comment button Reply

Collapse

Expand

Author

Apr 23

What’s ECSS?

Thread

Thread

It's a little known and a little old theory of how to work with CSS

It's also a book and a style guide.

ecss.benfrain.com/

Even if you don't use it, it's worth a read particularly the bits about DRY and the strength of duplication

Comment button Reply

Collapse

Expand

As is always the problem with popular catch phrases, they get overused. For me, DRY pertains primarily to business logic, i.e. you don't want to duplicate knowledge of a certain business process in more than one place, because of the potential for drift. But if you want to duplicate some lines of code here or there, be my guest.

Comment button Reply

Collapse

Expand

Copy paste is okay. I remember when a junior dev from a different team reused my view, by reference not copy paste.

Later, I updated my view which broke his page. Guess who got blamed for breaking the dev server? Me!

DRY is best but often it is done the wrong way, like my story or too much time is waste to DRY up code that doesn't really need it. We're not always working on the next Google.

Comment button Reply

Collapse

Expand

Author

Apr 23

Blaming folks is never really a good idea, but it sounds like it could possibly be a good teaching moment and/or improving communication with the team.

Comment button Reply

Collapse

Expand

Agreed. It was just dev but the business people freaked out.

Thread

Thread

What can I say, I explained business analysts that development environment is not QA/UAT so many times that I forgot the count.

They always say sorry and that it's just in case we didn't noticed 😂🤷🏻‍♀️

Thread

Thread

Right? I've bad business in dev meetings telling me I'm doing my job wrong 😂. They can't even code.

Thread

Thread

The ones I work with in the current project are good people, It's a bi-directional professional relationship, it must be. As tech lead/ lead dev, I try to explain them the concepts, the big picture about the architecture, the nuances of some features, what needs to be done to reach a given feature and so on.
They try to get better deadlines with that information and they try to understand whether something that is wrong in develop is due to a current development or if it's a flaw "Yes yes we know, it's develop, we don't want to bother you guys". 😆

Comment button Reply

Collapse

Expand

For a mediocre developer, it takes discipline to be dry and it takes iron balls to justify the dry (=longer) way to bosses.

For talented autistic hackers loving their craft, it takes discipline to not be dry when necessary and it takes iron balls to justify the “wet” way to themselves.

Dry can be different, as well as context for it. That’s why it’s definitely not something that’s cut in stone. But in general, it’s a nice practice. The smaller the team/project, the nicer it is.

Comment button Reply

Collapse

Expand

My thought process to decide to go with DRY is simple - Does applying DRY makes my code more manageable or more speghetti?

If applying DRY is making your code complex and less manageable, it is not worth it🤷

Comment button Reply

Collapse

Expand

DRY, like most of the guiding principles, is best though of as a guideline rather than a rule. There are always tradeoffs, good architecture practice is mostly a matter of understanding the tradeoffs and making deliberate informed decisions.

Sometimes it is better to duplicate a block of code if it cuts across multiple bounded contexts or presents difficult ownership & synchronization questions.

Database normalization somewhat parallels the DRY concept and helps illustrate the point. The early forms of normalization greatly improve the structure of the data but the highest levels of normalization will start to incurr additional database server overhead and application complexity. There is a middle ground that works best for any application but the exact balance is always a bit fuzzy, imprecise and moving.

The real value of the principles is to provide a language framework for discussing the work so we can make cooperative decisions acknowledging the tradeoffs we make for any given decision.

Comment button Reply

Collapse

Expand

The issue is that there always is more nuance than the slogan suggests.

Point: Don't Repeat Yourself

"every piece of knowledge must have a single, unambiguous, authoritative representation within a system."

Just because there are two similar representations doesn't necessarily mean they refer to the same piece of knowledge. It's likely but in some cases the resemblance simply reflects the current incomplete understanding of the problem and its solution.

Counterpoint: Beware the Share (see also Fate-sharing).

Implementations sharing a common dependency are inherently coupled. If the implementations have slightly different requirements the common dependency absorbs complexity to accommodate that variation in order to be more "generic". When the requirements of one of the implementations change, the commonality has to adapt-often taking on complexity that doesn't benefit the other implementations, sometimes leading to a breaking change for the other implementations. So at times maintaining multiple distinct but much simpler dependencies can make maintenance simpler (Used Three Times).

Look at Bounded Context ("Beware the share. Check your context."):

  • The Customer to get work done inside the Sales context
  • The Customer to get work done inside the Support context
  • The Customer necessary for the the Support context and Sales context to communicate/collaborate.

Superficially there is repetition across the three Customers but they serve very different roles and more importantly neither context should let implementation details about the their internal handling of a Customer leak out.

Comment button Reply

Collapse

Expand

The place I have ended up with respect to DRY after many years, is that repeating yourself is okay, but multiple sources of truth is a very bad thing, both for data and for business logic. Anything that isn't a source of truth for important data or logic, I don't care as much about being pragmatic.

Comment button Reply

Collapse

Expand

My guideline is once, sometimes twice but never three times.

Single Responsibility principal is king and applies to functional programing too.

Comment button Reply

Collapse

Expand

I was thinking about having maybe a getUserById and then a getUserByEmail, if you gonna DRY you can join both together in a getUserBySomething so you avoid repeating most of the query, but then you will have a conditional inside your function that makes the function more complex and it also breaks the Single Responsibility principle and it's worse IMHO.

Comment button Reply

Collapse

Expand

Single Responsibility does not mean all functions must only do one thing.

For example if we need new behavior, we simply write a new method whose name indicates that single responsibility. It then allows for parameters to change behaviors. It can contain calls to many other functions but strictly only does what the name implies.

I call this a decorator pattern because it adds functionality by use of optional parameters. Allows parts to be added at will, but never departs from what the name implies. It only does that one thing.

The decorated function prefers use of reusable SRP functions because that code is already done and bullet proof. They are closed for modification.

The Concept is so simple but often confuses pepple.

Doing more than one thing in a function composed of SRP Functions is only more fragile if tests prove it.

Comment button Reply

Collapse

Expand

Its a balance act (like most of the time). The drawback in getting DRY is that the code will have reduced flexibility. If parts of the application need to be refactored, that is much more work in a DRY application because you either need to extend the parts and need to be super careful not to affect other parts of the program. Or you need to break up again and create near-copies of some structures.

On the other hand, being DRY reduces the surface for bugs. More code = more surface for bugs, simple as that.

I think its a good rule of thumb to not trying to get into too DRY code too fast. Stay flexible until the overall architecture of some modules got settled and with refactoring and the use of unit tests it will be easier to DRY the code part by part.

Comment button Reply


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK