I find it fascinating that people are so against inheritance/polymorphism, these days. That's one of the absolute best ways to DRY. factoring out common base classes is a classic OO exercise. It's possible to drastically reduce the size of a codebase, and the potential error exposure, by doing some simple extractions.
To me, inheritance and polymorphism are two different things. Polymorphism is about different units implementing an interface or equivalent protocol and that rocks. Inheritance is, essentially, dumping a bunch of code into your new class, and most of the time just imposes constraints and breaks API boundaries for no good reason. After studying and doing OOP for about 5 years, I don't see the advantages of inheritance…
Hang your code out to DRY
31–40 of 82 posts
Re: Hang your code out to DRY
#32I really like WET (write everything twice). It also fits nicely with the rule of 3.
I find a mentality of _striving_ for DRY by default — even if end up choosing to duplicate for pragmatic reasons — to be beneficial in keeping programmers looking around for opportunities and refining the understanding of the context, with a better chance of incremental progress.
Re: Hang your code out to DRY
#33Earlier quoted context omitted.
I wish I saved the source, but I saw somewhere the term: "Don't repeat concepts" While it doesn't spell out a word, I think it's much better advice than DRY, and better aligns with your heuristics.
Related tangent: "AHA" (Avoid Hasty Abstractions) is a decent counter to the over-application of DRY. IME, people reach for DRY too quickly, at the expense of other worthy but more subtle principles.
Re: Hang your code out to DRY
#34Re: Hang your code out to DRY
#35My first heuristic is: If I change the code in block A, is it assured that I will need to change the code in block B? My second heuristic is: Can I name the method I wish to de-duplicate in a way that is honest for all cases I wish to cover, yet explains its business purpose? The more it deviates from these heuristics, the more likely I am to duplicate the code in object oriented programming.
I use, and teach juniors basically the same rule as your first one. I phrase it a little differently though: "if something happened in the future that required a change to function A, would the same requirement apply to function B as well?" I think your second heuristic is valid but a little dangerous, because being good at naming functions is somewhat orthogonal to being good at maintaining code.
However, in this case, I use it is an extension of the question "is this the same concept?" if it looks like useFloorWaxOrDessertTopping, it's a good clue that you may have the same lines of code but they are certainly not the same concept.
Re: Hang your code out to DRY
#36That's because the original article is so clearly about tearing down bad abstractions, but a large majority of programmers - based upon discussion about the article - seem to never get past the first part of it.
Given a long enough time horizon, all abstractions turn bad. The solution isn't to not abstract. The solution is to tear them down when they go bad. And if you don't learn to tear down bad abstractions, your codebase will devolve into shit regardless of what you do.
Re: Hang your code out to DRY
#37Earlier quoted context omitted.
I wish I saved the source, but I saw somewhere the term: "Don't repeat concepts" While it doesn't spell out a word, I think it's much better advice than DRY, and better aligns with your heuristics.
That's actually more or less how DRY is described in The Pragmatic Programmer (20th anniversary edition): > Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. Further on: > Dry is about the duplication of knowledge , of intent . It's about expressing the same thing in two different places, possibly in two totally different ways. [emphasis in original] And the next…
But that's the problem right there. Why is there more than one place to fix it?
(Now, sure, if you're using a function call wrong, you need to fix it everywhere you call that function, and it's fine that there are multiple such places. That's what functions are for. But if it's something like how a value is calculated... why is there more than one place that calculates the value?)
Re: Hang your code out to DRY
#38Earlier quoted context omitted.
I wish I saved the source, but I saw somewhere the term: "Don't repeat concepts" While it doesn't spell out a word, I think it's much better advice than DRY, and better aligns with your heuristics.
Exactly. I find it helps to also state that it doesn't mean "Don't Repeat Characters"
Re: Hang your code out to DRY
#39Earlier quoted context omitted.
Related tangent: "AHA" (Avoid Hasty Abstractions) is a decent counter to the over-application of DRY. IME, people reach for DRY too quickly, at the expense of other worthy but more subtle principles.
The opposite principle of DRY is WET. Write Everything Twice
First off, it excuses some really egregious behaviour like copying entire large chunks of code representing an identical concept just because "I haven't copied it twice yet". I've seen an entire controller and all related views copied wholesale because it needed to be placed in another area of the app (with identical visual and functional requirements)
Secondly, if the code is only incidentally identical, even 3 times isn't enough to say that you should apply DRY. 3 independent concepts that happen to currently share implementation still shouldn't be deduplicated. I think a great example of this is the inherited resources gem in rails that implements a "standard" interpretation of controller actions - which works well at first until your controllers need to do something other than basic CRUD. The fact that say, an update action handles parameters and saving in the same way as some other update action may currently be true, but is not at all guaranteed to be true in the future, even if you have 100 update actions in your app.
Re: Hang your code out to DRY
#40I find it fascinating that people are so against inheritance/polymorphism, these days. That's one of the absolute best ways to DRY. factoring out common base classes is a classic OO exercise. It's possible to drastically reduce the size of a codebase, and the potential error exposure, by doing some simple extractions.