Software Quality Assurance Vietnam Software Development Risk Management

[97 Things Every Programmer Should Know – #07] Share Carefully: Why Code Reuse Requires Context

Saturday, 24 Oct 2026 6 min read 7 views

[97 Things Every Programmer Should Know – #07] Share Carefully: Why Code Reuse Requires Context

Summary

Reusing code is often considered a good software development practice because it reduces duplication and simplifies maintenance. However, sharing code between unrelated parts of a system can introduce unnecessary dependencies. Before extracting common logic into a shared library, developers should understand its context, the relationships between components, and how those components may change independently.

Why Isn't Code Reuse Always a Good Idea?

In software development, code reuse is generally considered a sign of good design.

Instead of writing the same logic multiple times, developers extract common functionality into shared libraries or reusable components.

This approach can reduce duplication and make code easier to manage. However, it can also introduce problems when applied without considering the system's structure.

In 97 Things Every Programmer Should Know, Udi Dahan shares an experience from his first professional software project.

As a recent graduate eager to demonstrate his abilities, he spent considerable time studying the existing codebase. When assigned his first task, he applied several practices he had learned, including adding comments, implementing logging, and extracting similar code into shared libraries.

However, during code review, he discovered that his approach to code reuse was not necessarily beneficial.

The problem was not code reuse itself.

The problem was that he had overlooked the context in which the code was used.

Context Matters More Than Code Similarity

Consider two parts of a system that contain nearly identical logic.

At first glance, extracting that logic into a shared function seems reasonable. It reduces the total number of lines and eliminates duplication.

But what if those two components serve entirely different purposes?

Although their implementations may currently look similar, they may have different responsibilities and different reasons to change.

Their similarity could be temporary.

Before refactoring, each component can evolve independently. Changes to one do not necessarily affect the other.

Once the shared code is extracted into a common library, however, both components become dependent on the same implementation.

As Udi Dahan illustrates, this is like using one shoelace to tie two separate shoes.

Previously independent components are now connected.

A seemingly harmless change to a few lines of shared code can affect multiple parts of the system.

Reducing duplicate code does not automatically reduce system complexity. Sometimes, it simply moves complexity into dependencies.

How Can Shared Code Increase Maintenance Costs?

Imagine two components that each contain four similar lines of code.

Initially, the logic is independent. If one component's business requirements change, developers can update it without affecting the other.

After extracting those four lines into a shared library, both components depend on the same code.

Now, changing the shared implementation may require developers to:

  • Check whether the change affects other consumers.
  • Verify that all dependent components still behave correctly.
  • Run additional tests to avoid unexpected regressions.

Although the codebase contains fewer lines, the cost of changing those lines may increase.

This illustrates an important distinction between code duplication and coupling.

Duplication means that similar logic exists in multiple places. Coupling means that components depend on one another.

Removing duplication often introduces a dependency. Whether that trade-off is beneficial depends on the context.

When the shared code is used within a small, closely related part of a system, the benefits may outweigh the risks.

However, sharing code across unrelated components can create dependencies that make future changes more difficult.

When Should Developers Reuse Code?

The lesson is not to avoid code reuse entirely.

Reusability remains valuable when the shared components belong to an appropriate context and are likely to evolve together.

Before creating a shared library, developers should consider several questions:

  1. Do these components serve the same purpose? Similar implementations do not necessarily mean identical responsibilities.
  2. Will they change for the same reasons? If different business requirements drive their evolution, independent implementations may be safer.
  3. How far will the dependency extend? Sharing code within a small module is different from connecting unrelated areas of a system.
  4. Will reuse actually simplify maintenance? Fewer lines of code are not always worth the additional testing and coordination.

The following comparison summarizes the trade-offs.

SituationDesign consideration
Similar code with the same responsibilitySharing may reduce duplication and simplify maintenance
Similar code serving unrelated purposesKeeping implementations separate may preserve flexibility
Reuse within a closely related moduleDependencies are usually easier to manage
Reuse across independent system areasChanges may affect more components and require broader testing

The important question is not simply whether two pieces of code look similar.

It is whether they belong together from a design and business perspective.

Applying This Lesson to Software Development

In real projects, the temptation to eliminate duplicated code can be strong, especially when developers are trying to improve code quality.

However, refactoring should not focus exclusively on reducing the number of lines.

Developers also need to understand component boundaries, business responsibilities, and the consequences of introducing new dependencies.

For software development teams such as VAON, this lesson offers a useful principle when reviewing architecture or planning refactoring work.

Before creating common utilities or shared libraries, teams should evaluate whether the affected components genuinely share the same context.

A well-designed library can improve maintainability. An unnecessary shared library can make otherwise independent changes more expensive.

Conclusion: Share Carefully

Code reuse is useful, but it is not automatically the best design choice.

Two pieces of code may look identical today while serving different purposes and evolving in different directions tomorrow.

Extracting them into a shared library reduces duplication but also creates dependencies.

The goal of good software design is therefore not to minimize the number of lines at all costs. It is to maintain a structure that remains understandable and easy to change.

Before sharing code, understand its context. Reuse should simplify a system, not make independent components unnecessarily dependent on each other.

 

About This Series

97 Things Every Programmer Should Know explores practical lessons about software design, problem-solving, and professional development.

This article is adapted from #07 –「共有は慎重に」 (Share Carefully) by Udi Dahan, published in the Japanese edition of 97 Things Every Programmer Should Know.

The article preserves the original lesson while organizing its key ideas for software development teams.

Learn more about VAON and our software development services.

Ready to Transform Your Business?

Let's discuss how we can help you leverage AI and digital transformation for your enterprise.

Frequently asked questions

Is code duplication always bad?
No. Although duplication can increase maintenance effort, keeping small pieces of similar code separate may be appropriate when they serve different purposes or change independently. The decision should consider context rather than similarity alone.
When should developers create a shared library?
A shared library is most useful when multiple components genuinely share the same responsibility and are expected to evolve together. Developers should also evaluate the scope of the dependency and whether reuse will reduce overall maintenance costs.
What is the main risk of excessive code reuse?
Excessive code reuse can create unnecessary coupling. A change to shared logic may affect several components, requiring additional testing and coordination. This can make the system more difficult to maintain despite having fewer lines of code.
Should developers prioritize fewer lines of code?
Not necessarily. Reducing code size is useful only when it also improves clarity and maintainability. A slightly larger codebase with independent components may be easier to modify than a smaller codebase with tightly coupled dependencies.

Share this article