• Skip to main content
  • Skip to primary sidebar
BMA

BeMyAficionado

Inspire Affection

Freedom From Redundancy Is A Trade-off

January 26, 2022 by varunshrivastava Leave a Comment

Code reusability is the holy grail for software development. You might have heard that developers should write code once and reuse it everywhere. Or, never write the same code twice… and a lot of things on similar lines.

But have you ever questioned this?

Is redundancy such a bad thing after all?

Don’t you think these statements are subjective? Applied to specific use cases.

In this article, I want to share my thoughts on code redundancy and what I have seen in my career so far that worked well and well, not worked well 😀

Let’s try to pin down the drawbacks of having code reusability.

Table of Contents

  • A Closer View On Redundant Code
  • Bundle Common Code Into A Library Creates Dependency
  • Eric Evans – Domain Driven Design
    • Quick Example To Explain Where I Like To Use Interfaces
      • If/else – switch-case
      • Abstraction
  • Conclusion

A Closer View On Redundant Code

Don’t you think common code creates dependency? When we write the same code in two places and extract it out into a separate function, then two places are dependent on that code. That code that was flexible to change before is now incapable of that without breaking something.

Making code reusable will introduce unnecessary/necessary coupling and dependencies that if not married wisely will be problematic.

You see whenever you use a code in more than two places, you create a dependency on that code. Now, that common piece of code cannot change freely. It has to take care of all the dependent modules. That’s why all sorts of different design patterns come into the picture. If you look at all the different design patterns, what do they do? They all just try to make code less coupled, less dependent, less fragile.

Let’s say you have a common code that is being consumed from 4 different places:

Excuse my pretty handwriting.

And then requirements changed for component D. It needs a change of logic on the dependent code. Then some smart person stepped in and introduced interfaces or abstract classes. The role of this glue is to keep the contract same but enable different components to inject different implementations based on the requirement. Now we all know this as the inversion of dependency.

If you look closely. This is not a very elegant way. You need some kind of factory/injector that would hold the logic for creating the required object and providing it to the downstream components. Since this was getting nasty, smart people had to interject again and provide a framework for this.

Spring which is the best framework I think is the best framework for Java for creating mostly web applications provides a simple means of doing this injection. At some level, all it does is the injection of dependencies to classes. Called as Autowiring. The term is so fancy that it took me a day to understand what is this magic keyword. But it’s just that Spring creates a middle layer that provides the dependency to the required classes.

After some time the testing became difficult because developers simply started using @Autowire everywhere in the code. Okay, spring will provide the dependency at runtime for you, but how are you going to provide the dependency while writing unit tests. Then I have seen power mockito and all sorts of stuff to mock objects and do whitebox and what not to mock private methods and perform testing 🤮

Then came different ways to Autowire this object.

  • Autowire via constructor
  • Autowire by type
  • Autowire by name

Which is nothing but ways to inject dependency into the class. And finally, developers united on autowire by constructor as the best way to autowire dependency because then it allows for injecting dependencies via test classes without requiring additional mocking framework.

Oh, I just realized we started just by decoupling a simple piece of code… ended with types of autowiring. So, you see a lot goes into removing redundancy.

And while we are on the topic, I want to tell you that I have seen code that introduced 6 classes with all sorts of abstractions just to remove the 4 lines of redundant code in classes that doesn’t even share the same context. Well, I could live with redundancy as long as they are never going to cross the boundaries.

I learned to not have a mindset that says – “copying code from one place to another is redundant therefore introduce abstraction”.

Read the situation. Sometimes it’s a lot better to be redundant. From my experience, redundancy is a lot better than introducing complicated abstraction that makes the code hard to read and difficult to modify. Again, read the situation.

Bundle Common Code Into A Library Creates Dependency

Another thing that I have seen is the bundling of the common code into one package.

I have literally seen big massive jars starting by the prefix common-{}. These massive jars had nothing in common rather specific stuff from all the different projects across the organization. So, let’s say you are working on a module that has a piece of code or class that is required from more than one place in your module. Then it was added to the common jar/package.

Then this introduces another problem of supporting different versions. It could happen that one team introduced new “common” functionality, then they generate a new bundle and increment the version. Now, all teams in the organization start using their own version of “common-{}” jar. That has nothing in common 😀

Amazing isn’t it?

Ever been a part of “The Deployment Day”. It’s a real thing. And it’s daunting. Well, it’s not just because of the common code, but common code plays a huge role in this. A week before the deployment day all the code across all teams are frozen. You need additional permissions to change after code freeze. A big excel sheet is distributed across all teams where each team enters their dependencies versions to deploy to production. I don’t even want to talk about it, it’s so depressing. Let me check if I have written something on it somewhere that I could share. (found it but this deployment day was much better than the one I’ve experienced before in my first organization).

Eric Evans – Domain Driven Design

I think Sir Eric Evans decided to come up with DDD because he was done with all the shit he saw.

There he tried to explain that redundancy is good as long as it respects the boundaries. Okay, he didn’t say that, it’s just me manipulating his idea to strengthen my point.

But he did mention the example where he said – Having identical classes with the same properties and even the same name is cool if they tell a different story. It’s very much like a conversation. Two identical sentences can have a completely different meaning if the context is changed.

Because of such beautiful ideas, I say that code shouldn’t be looked at as poetry but as a wonderful conversation between two people in context. If you try to look at code as poetry then only you understand it. But if you look at a code as conversation, you make sure that you put your intent out in the world. And DDD bridges this gap.

Now I will share an example from his book.

Just to be clear, I’ve not read the entire book, but I have read different sources and watched youtube seminars talking about DDD that I think I got the gist. And I really like the idea of looking at the code as separate domains with context and intent. Again it is not to be taken blindly – read the situation. Code comes naturally.

Let me try to create a visual representation in my own way:

On the left is a person who hates redundancy and on the right is a person who embraces redundancy as long as it is provided with a beautiful context.

On the right, the person has decided to declare clear contextual boundaries. And a piece of code used in the particular module can be copied and pasted to another module, no problem. It’s the same situation, where the sentence is the same but the context has changed.

C1M1,.., C5M5 doesn’t give a shit about any other module. Therefore, they don’t care if some code is copied.

Live in your own world and respect boundaries

Another thing to notice is that classes are closed and secured in their own package with a single entry point. Whereas on the left all the classes are public. I have seen structures like service/impl where impl package contains the implementations for the different interfaces that are put in the services class. I have even done this sometimes.

When I asked this to my lead like years ago (when I was a fresh graduate who wrote redundant code and embraced the feature of CNTRL + C and CNTRL + V) – why are we creating an interface for every class? I got the answer that it provides flexibility. My immediate question was how? The answer was that if in the future a different implementation is required then we won’t have to change the contract. I waited for 2 complete years to see what kind of requirement will change the implementation but not the interface. 2 years into the future, I called my colleague who was still working in the same team and I asked him, what happened to that module. Trust me, the future is yet to come.

Quick Example To Explain Where I Like To Use Interfaces

Imagine a scenario where there are multiple events coming at you. And you have to process each event separately. There are two ways to solve this:

If/else – switch-case
class Event {
    string type;
    EventData data;
}

Event event;
if (event.type == "A") processor1.execute(event);
if (event.type == "B") processor2.execute(event);
if (event.type == "C") processor3.execute(event);
...
...
...
...
.

Although there’s nothing wrong with this if/else ladder. But this kind of slows us down. Because whenever there’s a new processor code is being changed at multiple places. On top of that, there’s always a chance that someone like me would copy this code in some place elsewhere in a shared environment 😂 which would be devastating in this case. So, abstraction is good.

Abstraction

Providing abstraction here will shorten the code by a lot and it kind of provides basic plumbing to the entire flow.

class Event {
    string type;
    EventData data;
}

class Processor {
   public:
      // pure virtual function providing interface framework.
      virtual void execute(Event event);
      virtual bool shouldProcess(Event event);
};

Event event;
vector<Processor> processors = {processor1, processor2, processor3, processor4, processor5};
for (auto p: processors) 
    if (p.shouldProcess(event)) p.execute(event);

I think this plumbing makes it better. And if I would be using Spring/Java then remember autowiring that would do everything for me. I will just have to write them for a loop.

And don’t confuse this representation with DDD. But you can trust me when I say that context is king and respect the boundaries.

Conclusion

Code redundancy is a good thing.

I want to write so much more on this but I know you won’t read further because it’s already more than 1500 words 😛 So I conclude.

Thanks for reading till the end (if you did). And if you did then make a quick comment and let me know.

Until next time.

Related

Filed Under: Programming, Software Quality Assurance Tagged With: domain-driven-design, java, life, programming, spring

Primary Sidebar

Subscribe to Blog via Email

Do you enjoy the content? Feel free to leave your email with me to receive new content straight to your inbox. I'm an engineer, you can trust me :)

Join 874 other subscribers

Latest Podcasts

Recent Posts

  • Is The Cosmos a Vast Computation?
  • Building Semantic Search for E-commerce Using Product Embeddings and OpenSearch
  • Leader Election with ZooKeeper: Simplifying Distributed Systems Management
  • AWS Serverless Event Driven Data Ingestion from Multiple and Diverse Sources
  • A Step-by-Step Guide to Deploy a Static Website with CloudFront and S3 Using CDK Behind A Custom Domain

Recent Comments

  • Varun Shrivastava on Deploy Lambda Function and API Gateway With Terraform
  • Vaibhav Shrivastava on Deploy Lambda Function and API Gateway With Terraform
  • Varun Shrivastava on Should Girls Wear Short Clothes?
  • D on Should Girls Wear Short Clothes?
  • disqus_X5PikVsRAg on Basic Calculator Leetcode Problem Using Object-Oriented Programming In Java

Categories

  • Blogging
  • Cooking
  • Fashion
  • Finance & Money
  • Programming
  • Reviews
  • Software Quality Assurance
  • Technology
  • Travelling
  • Tutorials
  • Web Hosting
  • Wordpress N SEO

Archives

  • November 2024
  • September 2024
  • July 2024
  • April 2024
  • February 2024
  • November 2023
  • June 2023
  • May 2023
  • April 2023
  • August 2022
  • May 2022
  • April 2022
  • February 2022
  • January 2022
  • November 2021
  • September 2021
  • August 2021
  • June 2021
  • May 2021
  • April 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • February 2020
  • December 2019
  • November 2019
  • October 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • January 2019
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • March 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • October 2017
  • September 2017
  • August 2017
  • July 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • July 2016
  • June 2016
  • May 2016

Tags

Affordable Hosting (4) algorithms (4) amazon (3) aoc-2020 (7) believe in yourself (4) best (4) database (4) earn money blogging (5) education (4) elementary sorting algorithms (4) experience (3) fashion (4) finance (6) Financial Freedom (7) food (7) friends (3) goals (5) google (5) india (10) indian cuisine (5) indian education system (4) java (16) life (16) life changing (4) love (4) make money (3) microservices (9) motivation (4) oops (4) podcast (6) poor education system (4) principles of microservices (5) problem-solving (7) programmer (5) programming (28) python (5) reality (3) seo (6) spring (3) success (10) success factor (4) technology (4) top 5 (7) typescript (3) wordpress (7)

Copyright © 2025 · Be My Aficionado · WordPress · Log in

Go to mobile version