Share utilities, not flow

Share utilities, not flow

Sometimes a program you're working on have multiple flows that look very similar.

It could be something like this:

  1. Fetch the data.
  2. Parse the data.
  3. Save the data.

You write each flow separately at first but then notice the repetitiveness. So, remembering "clean" code and the DRY principle you start to combine the flows into one. You feel all smart and smug about it.

But then you run it and it works for one flow and fails for the others. Ah, it seems that data request for Flow 1 requires a bearer token while Flow 2 requires a client ID and a client secret. And Flow 3 doesn't have any authentication at all.

You add some conditions inside of your generic flow.

Then you notice that the JSON parsing fails sometimes. Right, one of the APIs doesn't support JSON and returns to you some weird format called EDN. You add more if statements. Maybe you even get some of the code chunks into separate functions. At this point this is more like sweeping dust under the bed and admiring the clean floor.

You're trapped in this local minimum of keeping one flow to rule them all. Even though it's starting to look like a food experiment left in the fridge for too long.

The best part? Now you get to maintain this code forever or until you quit. Or until you refactor it...

An alternative

I propose a different solution: keep the flows separate but find the parts that are not specific to any one flow.

These are things like network (or IO in general), parsing of common data formats, date and time handling, auth mechanism, etc. Basically, things that don't know and don't care anything about your business logic. I call them utilities. Kinda like electricity, water, gas, internet connection. The electricity doesn't care if you're using it to boil some water for tea or to solder some stuff together.

So you keep your flows separate, each describing a business process for example, but you notice things that are truly generic and then share those. You can now fix a bug in one flow without breaking the others. Each flow's code is easy to read and understand. There are no branches. The data just flows from top to bottom.

There's some duplication but that's fine. That may be a good thing. That may just be familiarity. You know how flows work in your system so, of course, they resemble each other.

Conclusion

DRY is not some law of physics. It's not an absolute. You don't have to eliminate all and every repetition possible. It's a tool to help you spot things that could be utilities: context independent, useful, extremely shareable. Use it with care.


Erik Assum

Wearer of many hats

10 个月

I like this. I’m also seeing this through the lens of top down vs bottom up design. The one flow to rule them all can be seen as a top down design, but the other way can be seen as bottom up.

要查看或添加评论,请登录

Evgheni Kondratenko的更多文章

  • With or without str

    With or without str

    There are useful functions in Clojure that do not return anything but print text to out (usually the REPL, the log, or…

  • Clj-kondo in a monorepo

    Clj-kondo in a monorepo

    This season monorepos are back on the streets. You can see monorepos everywhere: in a startup, in a scale up, in a…

  • A book about Hackers

    A book about Hackers

    The last episode of the CoRecursive podcast has a story about a veteran game developer and designer Mick West…

  • Your desk is not a mess it's a playground

    Your desk is not a mess it's a playground

    Software engineers' work desks used to be interesting and fun. They looked like chaos at a first glance, but if you…

  • Single-header file libraries

    Single-header file libraries

    When I've started writing C/C++ programs twenty years ago I've learned that there are two types of files in my program:…

  • Source code is the ultimate documentation

    Source code is the ultimate documentation

    So I've been coding a custom Sentry SDK. While developing a Sentry SDK they recommend you to run a Sentry Relay - the…

  • Life before LSP

    Life before LSP

    You know, there was a time when LSP didn't exist. Yeah, I know.

  • Flatten with caution

    Flatten with caution

    In one of my previous Clojure posts I've used flatten in my examples to concatenate collection of collections after a…

    3 条评论
  • There is more than one way

    There is more than one way

    In one of my recent Clojure posts Dave Liepmann has commented: ..

  • Batching in Clojure is boring

    Batching in Clojure is boring

    Sometimes you need to process data. And sometimes it's a lot of data so you want to do the processing in batches.

    1 条评论

社区洞察

其他会员也浏览了