DRY = Don’t repeat yourself

  • JonC@programming.dev
    link
    fedilink
    English
    arrow-up
    60
    ·
    10 days ago

    I’ve always understood DRY to be about not duplicating concepts rather than not duplicating code.

    In the example here, you have separate concepts that happen to use very similar code right now. It’s not repeating yourself as the concepts are not the same. The real key is understanding that, which to be fair, is mentioned in the article.

    IMO, this is where techniques like Domain-Driven Design really shine as they put the business concepts at the forefront of things.

    • magic_lobster_party@fedia.io
      link
      fedilink
      arrow-up
      8
      ·
      10 days ago

      That’s how DRY is described in Pragmatic Programmer, where DRY was first coined. They’re clear that just because code look similar, doesn’t necessarily mean it’s the same.

    • hono4kami@piefed.socialOP
      link
      fedilink
      English
      arrow-up
      6
      ·
      10 days ago

      IMO, this is where techniques like Domain-Driven Design really shine as they put the business concepts at the forefront of things.

      Do you have a resource on where to learn DDD? I feel like I never understood the concept well.

      • JonC@programming.dev
        link
        fedilink
        English
        arrow-up
        5
        ·
        10 days ago

        As already mentioned, the blue book by Evic Evans is a good reference, but it’s a ittle dry. Vaughn Vernon has a book, “Implementing Domain-Driven Design” that is a little easier to get into.

        Personally, I found that I only really grokked it when I worked on a project that used event-sourcing a few years back. When you don’t have the crutch of just doing CRUD with a relational database, you’re forced to think about business workflows - and that’s really the key to properly understanding Domain-Driven Design.

        • vulture_god@lemmy.dbzer0.com
          link
          fedilink
          arrow-up
          2
          ·
          10 days ago

          Yeah for me the understanding really came when working in a federated GraphQL API. Each team had us own little slice of overall object graph, and overlap / duplication / confusing objects across the whole domain were a lot easier to see in that environment.

      • Dunstabzugshaubitze@feddit.org
        link
        fedilink
        arrow-up
        4
        ·
        10 days ago

        “Domain Driven Design” by Eric Evans, aka the blue book. It’s very dense however and very object oriented, but concepts apply even if you dont work with object oriented languages, you might have to do more footwork to get from a domain model to services that adhere to the model.

        “Head first Software Architecture” might be an easier on ramp and touches on simmiliar concepts.

    • Dunstabzugshaubitze@feddit.org
      link
      fedilink
      arrow-up
      4
      ·
      10 days ago

      yes, this is exactly what you have to think about. the left example even aknowledges that deadlines for “tasks” might be different from deadlines for “payments”, which suggests that the abstraction is not “clean”.

    • Dark Arc@social.packetloss.gg
      link
      fedilink
      English
      arrow-up
      1
      ·
      10 days ago

      It should be about concepts but it’s more often applied to duplicate algorithms by inexperienced people (which is a huge mistake).

  • PieMePlenty@lemmy.world
    link
    fedilink
    arrow-up
    25
    ·
    9 days ago

    Ultimate DRY: just keep refactoring the one method to accept hundreds of parameters and do everything.

    Add two numbers? DoIt(1, 2);

    Subtract? DoIt(null, null, 3, 1);

    Etc.

  • William@lemmy.world
    link
    fedilink
    arrow-up
    17
    arrow-down
    3
    ·
    10 days ago

    First off, I generally don’t worry about DRY until there are 3 instances, not 2. With only 2, it’s really easy to over-generalize or have a bad structure for the abstraction.

    But otherwise, I disagree with the article. If it’s complicated enough to bother abstracting the logic, the worst that can happen in the above situation is that you just duplicate that whole class once you discover that it’s not the same. And if that never happens, you only have 1 copy to maintain.

    The code in the article isn’t complicated enough that I’d bother. It even ends up with about the same number of lines of code, hinting that you probably haven’t simplified things much.

    • Dark Arc@social.packetloss.gg
      link
      fedilink
      English
      arrow-up
      7
      arrow-down
      1
      ·
      10 days ago

      The code in the article isn’t complicated enough that I’d bother. It even ends up with about the same number of lines of code, hinting that you probably haven’t simplified things much.

      I think it’s a good example of the problem though. People take that same idea and apply it too liberally. The point isn’t that specific code, it’s about not apply DRY to code that’s coincidentally identical.

      But otherwise, I disagree with the article. If it’s complicated enough to bother abstracting the logic, the worst that can happen in the above situation is that you just duplicate that whole class once you discover that it’s not the same. And if that never happens, you only have 1 copy to maintain.

      That’s… Not at all true in practice. What often happens with these “DRY” abstractions when they’ve been improperly applied is you end up with an inheritance hierarchy or a crazy template or some other thing. You’re really lucky if you can just copy some code and find your way out of the weeds.

      There are plenty of bad abstractions in the wild and novices applying DRY is a common source of them.

      • MajorHavoc@programming.dev
        link
        fedilink
        arrow-up
        3
        arrow-down
        2
        ·
        10 days ago

        There are plenty of bad abstractions in the wild and novices applying DRY is a common source of them.

        You’re both saying the same thing though. Novices aggressively apply DRY the moment a second bit of identical code appears, while experienced developers often wait for a third copy and then think about whether DRY fits.

        That said, I think "don’t apply DRY too aggressively is the whole point of this discussion, and the person you’re replying to was kind of needlessly disagreeing.

        • Dark Arc@social.packetloss.gg
          link
          fedilink
          English
          arrow-up
          2
          arrow-down
          1
          ·
          edit-2
          10 days ago

          You’re both saying the same thing though.

          We’re not quite saying the same thing though because …

          It’s not a 2 vs 3 issue. You can have an infinite number of instances of the same logic and it still not be a case for generalization because it’s not actually general … it’s just an infinitely large program. You can also have two copies of the same code that should be reduced because they are general (e.g. you have the exact same algorithm for generating a UUID copied into two different spots). If you’re thinking about it in terms of quantity you’re already doing it wrong.

          It’s not fixable by “just” copying something.

          Those two points are really important points.

          • MajorHavoc@programming.dev
            link
            fedilink
            arrow-up
            3
            arrow-down
            1
            ·
            edit-2
            10 days ago

            If you’re thinking about it in terms of quantity you’re already doing it wrong.

            You’re ignoring that simple principles make great guidelines for not overthinking things.

            And you’re doing so in the context of an article about the dangers of overthinking things.

            You’ve over thought an article about the dangers of overthinking, while alienating potential collaborators with a condescending tone.

            You’re coming across like one of the rookies who need this warning.

            Consider counting to three, before applying DRY. It works.

            • Dark Arc@social.packetloss.gg
              link
              fedilink
              English
              arrow-up
              4
              arrow-down
              1
              ·
              edit-2
              10 days ago

              You’re ignoring that simple principles make great guidelines for not overthinking things.

              Name some great “simple principles;” everything has nuance and trying to distill things into “well it’s just this simple principle…” is a great way to get catastrophic mistakes.

              And you’re doing so in the context of an article about the dangers of overthinking things.

              You did not understand the point of that article if you think it’s about the dangers of over thinking. The issue with DRY is that it leads to making refractors without thinking about whether or not the refractor makes sense. That’s the exact issue the author is warning about, think about whether or not dry makes sense.

              That has ABSOLUTELY NOTHING to do with how many times the code has been repeated. It has everything to do with why it’s repeated.

              You’re coming across like one of the rookies who need this warning.

              I’ll toss that right back at you bud. You don’t seem to understand the actual problem.

              Consider counting to three, before applying DRY. It works.

              It does not. I literally fixed a bug today because the same algorithm, doing the same job, was used in two different places formatted differently, exactly two, and they got out of sync resulting in memory corruption.

              That’s what DRY is intended to fix. Not “I have three [or whatever number] things doing the same thing so now I should DRY this code up”, I’ve seen HORRIBLE refractors from DRY applied to 3 things; absolute spaghetti inheritance hierarchies that were “DRY.”

              I hate talking about DRY because it’s this principle that so many people think “oh I’m doing it correctly; I’m doing good things!” and they actually make the code SO MUCH worse.

              EDIT: Here’s exact quotes from the article (emphasis theirs):

              Applying DRY principles too rigidly leads to premature abstractions that make future changes more complex than necessary. Consider carefully if code is truly redundant or just superficially similar. While functions or classes may look the same, they may also serve different contexts and business requirements that evolve differently over time. Think about how the functions’ purpose holds with time, not just about making the code shorter.

    • robinm@programming.dev
      link
      fedilink
      arrow-up
      3
      ·
      8 days ago

      I personally factorize as soon as there are two copies, but do not hesitate to inline the code and redo the abstraction when there is a 3rd use if it doesn’t fit. I find it much easier to inline and re-abstact a bad abstraction, than check if two copies are indeed identical.

      The exception is business logic. Usually I want all of them to be dupplicates because there is a very high chance that it’s just accidental that part of the logic is similar. I take great care to have good primitives but the actual business logic that glue those primitives together is written as many time as needed.

    • esa@discuss.tchncs.de
      link
      fedilink
      arrow-up
      1
      ·
      9 days ago

      Yeah, I’m reminded of how Germanic languages used to have singular, dual and plural. If we’d still had dual, we’d probably also be talking about not abstracting until we actually have a plural.

  • AnyOldName3@lemmy.world
    link
    fedilink
    arrow-up
    4
    arrow-down
    1
    ·
    9 days ago

    This is silly. Everyone knows that DRY is telling you that if you do the same sequence of mouse clicks three times in a row, you should spend the day writing a script to automate the task instead of quickly finishing what you were doing by doing the same sequence of clicks a fourth time. If you are supposed to apply it to the code you write, then there’d never be boilerplate-heavy languages like Java.