News for hackers. Stuff that matters.
Re:Goodbye, Clean Code by BeetleB on Saturday January 11, 2020 @05:54PM (#22022958)
The first thing I did when I read this was come to the HN comments and search for people complaining about DRY:

https://news.ycombinator.com/item?id=22022599

https://news.ycombinator.com/item?id=22022842

https://news.ycombinator.com/item?id=22022896

https://news.ycombinator.com/item?id=22022836

The author of this piece was not engaging in a DRY activity even if he thought he was. He (perhaps unwittingly) admits to it himself:

> My code traded the ability to change requirements for reduced duplication, and it was not a good trade.

The acronym DRY was coined in The Pragmatic Programmer, and the author of that book makes it clear that DRY is about not repeating requirements in code. You definitely don't want to deduplicate similar code if it involves multiple requirements because then you entangle yourself, which is what the author of this piece did.

Re:Goodbye, Clean Code by brabel on Saturday January 11, 2020 @06:52PM (#22023320)
> DRY is about not repeating requirements in code.

Exactly! A lot of developers, even experienced (and I would include the OP, even after his supposed lesson) seem to not get this: duplication is only bad when what is being duplicated MUST behave the same by definition (i.e. if you change one but not the other, the other would've become broken as its definition would still be the same as the changed one). Otherwise, two similar or identical codes are NOT duplicated in a way that violates DRY, they are just coincidental - as they might become different later - so the "duplication" in this case must NOT be removed (but perhaps a smaller portion of the code might be duplication of definition, which should be then extracted and de-duplicated). It really isn't that hard.

Re:Goodbye, Clean Code by bagacrap on Saturday January 11, 2020 @09:33PM (#22024071)
Problem is, it's hard to tell the difference in advance. In this case, it only became apparent to OP some time down the line.
Re:Goodbye, Clean Code by jrochkind1 on Saturday January 11, 2020 @08:07PM (#22023664)
In my experience, it's often non-obvious when you have multiple "requirements" and when you don't. Except in retrospect when you realize you painted yourself into a corner.

Your experience is different, you always know when you have multiple requirements and should DRY, and when instead you have "incidental [or accidental] duplication" and de-duplciation would not be advisable and thus not be called "DRY"?

If so, I wonder what leads to our different experiences.

Re:Goodbye, Clean Code by isaachier on Saturday January 11, 2020 @09:26PM (#22024037)
The Pragmatic Programmer is pretty zealous about DRY. For instance, the authors describe how they inserted sample code snippets into the book using specialized scripts developed for that purpose. A simple copy paste wasn't good enough (see p. 100-101). Granted, they had wanted to make sure the code snippets were tested and updated as needed, but repeating code anywhere seems to be a bad practice according this definition.
Re:Goodbye, Clean Code by leoc on Saturday January 11, 2020 @06:44PM (#22023272)
Wasn't it the case that the requirements were the same at the time the code was written? TextBlock.resizeTopLeft(...) and Rectangle.resizeTopLeft(...) did the same thing for the same reason, not by coincidence. The issue was the possiblity (and eventually the reality) of future divergence.
Re:Goodbye, Clean Code by thefifthsetpin on Saturday January 11, 2020 @08:11PM (#22023690)
The issue wasn't divergence. The issue was that there was no requirement that TextBlocks should behave like rectangles.

It's very possible that DRY could apply even where divergence is expected. Suppose we had a requirement that "A user should not be able to resize a TextBlock if they are not allowed to read the text." At the outset, the read & resize permission logic might be identical & DRY is easy to apply. Nobody would be surprised if eventually resizing permissions became more restrictive. Even at that point, DRY applies. If you repeated the shared logic, and later you add new restrictions to the read permissions, it'd be easy to introduce a bug where you forget to restrict resizing permissions accordingly.

Re:Goodbye, Clean Code by mattkrause on Saturday January 11, 2020 @09:38PM (#22024093)
> The issue was that there was no requirement that TextBlocks should behave like rectangles.

Sure, though that’s not quite what the new code did.

Instead, it added a new abstraction (createBox), and then used that to incidentally assign the same behavior to TextBlocks and Rectangles. Your change could easily be accomplished by changing the last line to check the permissions and call createBox or something else, depending. I’d guess that createBox would also be useful for many other shapes, but if you wanted to do something totally different, like a star with handles at each point, you could just....not call createBox, and write a totally independent “let star()” function that does its own thing; it doesn’t seem like a base class constructor is forcing you to call createBox or anything.

So....this code doesn’t actually seem that bad to me. What am I missing?

Re:Goodbye, Clean Code by dragonwriter on Saturday January 11, 2020 @09:35PM (#22024080)
> The issue wasn't divergence. The issue was that there was no requirement that TextBlocks should behave like rectangles.

But they had the same current requirements. So, ideally, the implementation of the common behavior should have been shared but shared in a way which didn't tightly couple the two consumers with each other, so that it would be simple for either to stop using the shared code.

Re:Goodbye, Clean Code by BeetleB on Saturday January 11, 2020 @07:45PM (#22023560)
I disagree.

If they had separate classes for TextBlock and Rectangle, then likely there are separate requirements involved. It may have been that at the time they needed separate classes the requirements for resizeTopLeft was identical, but they are still two separate requirements.

I suggest everyone take a minicourse or read a book on systems engineering - at least the part where they discuss requirements. The fact that two distinct entities have an identical requirement for something does not mean there is one requirement. It means there are two requirements which (for now) happen to be identical.

The key phrase is happen to be. You do not apply DRY to separate requirements even if they are the same/similar.

Look at it from a testing perspective[1], which is similar to how a systems engineer will look at it. If you would write a separate test for it, it is a distinct requirement. (Actually, the ordering should be the opposite: If it is a separate requirement, it should have a separate test).

[1] And not from a TDD perspective!

Re:Goodbye, Clean Code by _____s on Saturday January 11, 2020 @11:14PM (#22024429)
> I suggest everyone take a minicourse or read a book on systems engineering - at least the part where they discuss requirements. The fact that two distinct entities have an identical requirement for something does not mean there is one requirement. It means there are two requirements which (for now) happen to be identical.

I'd love to do this -- do you have any recommendations for a book like this?

Re:Goodbye, Clean Code by BeetleB on Saturday January 11, 2020 @11:35PM (#22024503)
Not really. I took it as part of an inhouse training at work.
Re:Goodbye, Clean Code by monksy on Saturday January 11, 2020 @05:55PM (#22022964)
Are you saying that they're repeating themselves?