Live data from Hacker News

Hang your code out to DRY

johan.hal.se

11–20 of 82 posts

Re: Hang your code out to DRY

#11

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 over composition. The only value I see is libraries exposing base classes that enforce behavior on user-written subclasses, stuff like React's Component or Java's HttpServlet. Seems to me we can have polymorphism without subclassing as long as the programming language has a half-decent type system.

Re: Hang your code out to DRY

#12

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.

I think a lot of people have been burned by inheritance done wrong.

With a lot of other techniques, if the implementation isn't perfect and you don't own the library you're using you still have a lot of power available to patch things up and make everything play nicely together. Inheritance mixes implementation details with your type checking, so in a lot of languages that can make it extremely painful to turn a body of almost-good-enough code into something that's actually usable.

Re: Hang your code out to DRY

#13

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.

There's something to be said for preferring composition over inheritance, but in that case overly DRY code consists almost entirely of glue. As with almost anything it's a matter of choosing the right tool for the job.

The only code style advices that I've found to hold nigh universally are the following:

- The best code is no code

- Don't end classes in 'er' or 'or'

Coding paradigms are good when they let you do those things and are bad when they don't do both of those things (i.e. they result in more code or clases ending in 'er'; a class named 'Helper' is a code smell worse than sulfur dioxide)

Re: Hang your code out to DRY

#14
post #6

My 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.

Re: Hang your code out to DRY

#15

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.

You don't have to use OO though. We're using an OO-oriented language at work, but I do a lot of de-duplication of code by extracting common functions.

If needed I can delegate the specialization to an interface or in a function reference parameter (so anonymous functions can be passed) rather than in a subclass.

When implementing the interfaces I might use subclasses though, if I have some very similar variants.

Re: Hang your code out to DRY

#16

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.

I don't think people are necessarily against polymorphism or factoring out common logic, but they're definitely against big class hierarchies in the old "OO" style.

Plain data structures with polymorphism via traits/interfaces/protocols seems like it's becoming the more popular way to handle these problems (I have no way to prove this, of course), and I prefer that way as well.

It's just the worst though when a dev sees two chunks of code that happen to be "shaped" the same and decide to tie them together with one abstraction. It's like seeing two different cables in a building that carry radically different signals but happen to go along the same path for awhile, and someone comes along and zip ties them together. You may have wanted to be able to route one of them completely differently, or maybe you wanted to add one more of the same cable, and now you have to cut up all the zip ties and either re-apply them (shove it into the existing abstraction), or bundle them up some other new way.

Re: Hang your code out to DRY

#17

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.

I came to conclusion that very few people actually understand what a good OO design is and ever fewer have skills to implement it. All this talk about SOLID patterns and what is more likely to result in overengineered monstrosity than in something elegant and easy to maintain.

Re: Hang your code out to DRY

#18

I really like WET (write everything twice). It also fits nicely with the rule of 3.

I would only call code without proper abstractions WET (Winnow Everything Thrice). What acronym can we fit into "damp"?

DRY After Multiple Permutations

Re: Hang your code out to DRY

#19

I really like WET (write everything twice). It also fits nicely with the rule of 3.

I would only call code without proper abstractions WET (Winnow Everything Thrice). What acronym can we fit into "damp"?

Don't add multiple parameters.

Delete all multifunctional programs.

Don't AMPlify code.

Re: Hang your code out to DRY

#20

like many older developers, I have become less ideological about DRY over time, particularly as I have seen it motivate extremely abstract solutions that have proven difficult to understand and maintain i have coined the term "Locality of Behavior" (LoB) as a competing design principle to DRY (as well as Separation of Concerns, SoC) that advocates more inlining of (potentially repetitive) logic in the interest of cod…

Why does the "does it actually work" go down over time? I would expect to be the other way round: more experience, more chances your software "actually works", even if it's not following strict rules anymore.

There are multiple metrics to describe what “works” even means. You are right that battle tested code can be more stable and fulfill its goals more than new untested code or code written without a customer. At the same time it’s also true that any sizeable codebase, especially production code, will accumulate bugs over time, will almost always slow down over time, and will eventually once large enough become crufty and smelly and unfactorable and difficult and, maybe most importantly, expensive to maintain. Big systems are hard.
Post reply on HN