The DRY principle: striking the delicate balance between code reuse and clarity

· Imen Ezzine · 3 minutes to read
Lego

This article explores the DRY (Don't Repeat Yourself) principle and its impact on code quality. While emphasizing its importance in avoiding repetition and facilitating maintenance, it highlights the risks of excessive application of this principle, which can be detrimental to clarity and project evolution. The aim is to strike the right balance between reuse and simplicity.

In this article, we explore the DRY (Don't Repeat Yourself) principle and its impact on code quality. While essential for avoiding redundancy and facilitating maintenance, its excessive application can sometimes complicate the understanding and evolution of a project. Let's find out how to strike the right balance between reuse and clarity.

The DRY principle: a double-edged sword

Recently, we put the finishing touches to the initial version of our current project, which will soon be launched in production. As the complexity of our code evolves due to the nature of the project, we're focusing on making it simpler and more streamlined. By implementing best practices such as the DRY (Don't Repeat Yourself) principle to avoid redundancy, we aim to maintain high quality.

This leads me to discuss a principle that I consider to be double-edged, and which should be used judiciously while remaining pragmatic.

Why apply the DRY principle?

The DRY “Don't Repeat Yourself” principle is a software development philosophy aimed at minimizing redundancy in source code. While this approach is widely praised for its effectiveness in managing code complexity, it is essential to understand how its rigid application can sometimes create confusion.

Example:

Let's take a case where we have two entities in a Symfony application: User and Admin. These two entities share common properties, such as firstname, lastname, and email. However, without normalization, we would be duplicating these properties in every entity, which violates the DRY principle. Here's an example of how it would look without normalization:

// src/Entity/User.php

namespace App\Entity;

class User
{
    private string $firstname;
    private string $lastname;
    private string $email;
    private string $job;
}
// src/Entity/Admin.php

namespace App\Entity;

class Admin
{
    private string $firstname;
    private string $lastname;
    private string $email;
    private array $roles;
}

In this case, the PhpStorm inspector or PHP Mess Detector would report a duplication of firstname, lastname and email properties in both entities. A classic suggestion would be to use inheritance to centralize these properties in a parent class, Account, to eliminate the duplication:

//src/Entity/Account.php

namespace App\Entity;

abstract class Account
{
    private string $firstname;
    private string $lastname;
    private string $email;
}

Next, we inherit User and Admin of this class Account, while adding properties specific to each of these entities:

//src/Entity/User.php

namespace App\Entity;

class User extends Account
{
    private string $job;
}
//src/Entity/Admin.php

namespace App\Entity;

class Admin extends Account
{
    private array $roles;
}

This approach centralizes shared properties in a base class. It improves readability and reduces the risk of duplication errors. However, it's important to bear in mind that this solution doesn't always have to be coupled with an ORM integration like Doctrine. Sometimes, working directly with a pure object model is better suited to keeping code independent of any framework. If Doctrine becomes necessary later on, you can always map these models with tools like MappedSuperclass or SingleTableInheritance.

When abstraction becomes excessive

However, this quest to reduce redundancy can sometimes lead to excessive abstraction. When developers seek to generalize too quickly, the code becomes harder to understand for those unfamiliar with the specific details of the project. Complex abstractions can create layers of indirection which, instead of clarifying the code, introduce additional levels of confusion.

Another aspect to consider is that persistence in strictly following the DRY principle can lead to generic code structures that are not optimal for each particular case. For example, when factoring a property such as a unique identifier (ID) for different entities, we may find that the associated rules vary according to the business context. Let's take the case of a system where users have simple numeric IDs, while customers require IDs with a regional prefix (e.g. EU-12345). In this case, centralizing ID management can complicate the code with additional conditions. Sometimes, intentional duplication of certain parts of the code, adapted to each entity, can improve readability and maintenance, especially when specific variations are likely to appear in the future.

DRY in the context of modern architecture

In modern architectures, particularly with microservices and Polyrepo strategies, it is sometimes encouraged to copy and paste between isolated services. As each service is autonomous and independent, a moderate duplication of code between different services can allow better management of local modifications and facilitate deployment without impacting other parts of the system.

Finding the right balance between code reuse and clarity is a constant challenge for developers. It's important to recognize that DRY is a guideline, not an absolute rule. Compromises may be necessary to maintain readable, understandable code while enjoying the benefits of reuse.

Conclusion

In conclusion, although the DRY principle is a valuable guide to improving code quality, its rigid application can sometimes lead to confusion. In the context of complex architectures such as microservices, developers may even be encouraged to duplicate code to guarantee service independence. The important thing is to remain aware of the project's context, and find the optimum balance between code reuse, readability and maintenance.

Are you looking to apply the DRY principle without compromising the readability and maintainability of your code?

At SensioLabs, our Symfony and PHP experts can help you structure your projects efficiently: intelligent code factoring, good development practices and scalable architecture.

This might also interest you

Chart going up
Silas Joisten New

Why Tests? Explained for Management

For business leaders: why testing matters for ROI, risk reduction, and agility explained in management language with numbers and real case studies.

Read more
Code happy in lights
Imen Ezzine

Code Review: Types, Organization, and Best Practices

Code review is an essential step in the software development cycle. It improves code quality, reduces bugs, and encourages knowledge sharing within the team. GitLab and GitHub, two of the most popular code management platforms, offer advanced features to facilitate this process. This article covers the various types of code reviews, how to organize them, and how to use templates and checklists to make PRs (pull requests) more efficient.

Read more
Many Lego figurines on a white table with hands playing with them
Alexandre Nesson

Scrum Guide Expansion Pack (2025): Key Insights You Need to Know

A new building block has been added to the Scrum Guide to enrich it! Does it offer real value, or is it just window dressing? Read on to find out in this article written by one of our experts.

Read more
The SensioLabs team celebrating the 20th anniversary of Symfony with balloons
Jules Daunay

The Story Continues: SensioLabs Celebrates Symfony's 20th Anniversary

Time flies, especially when you're busy shaping the future of development! The SensioLabs team has just reached a milestone with the anniversary of the Symfony framework. We marked the occasion at the office, but the party isn't over yet. The date is already set for an XXL celebration at SymfonyCon Amsterdam 2025, from November 27 to 28.

Read more
PHP 8.5 URI extension
Oskar Stark

PHP 8.5's New URI Extension: A Game-Changer for URL Parsing

PHP 8.5 introduces a powerful new URI extension that modernizes URL handling. With support for both RFC 3986 and WHATWG standards, the new Uri class provides immutable objects, fluent interfaces, and proper validation - addressing all the limitations of the legacy parse_url() function. This guide shows practical before/after examples and explains when to use each standard.

Read more
Open in new tab
Silas Joisten

The Tab Trap: Why Forcing New Tabs Is Bad UX

We’ve all done it — added target="_blank" to a link to “help users” stay on our site. But what feels like a harmless convenience often creates confusion, breaks accessibility, and introduces hidden security risks.

Read more
3 dog heads
Mathieu Santostefano

Bring Your Own HTTP client

Break free from rigid dependencies in your PHP SDKs. Learn how to use PSR-7, PSR-17, and PSR-18 standards along with php-http/discovery to allow users to bring their favorite HTTP client, whether it's Guzzle, Symfony HttpClient, or another. A must-read for PHP and Symfony developers.

Read more
Vegetables on a wooden board with a knife with a pan on top
Rémi Brière

Why Scrum Fails (and How to Fix It) - Part 2

Scrum is often seen as the obvious framework for structuring and energizing product development, especially digital products. However, its adoption doesn't automatically guarantee success. So, what does Scrum really enable? More importantly, what are the conditions necessary for its effectiveness? And, above all, what pitfalls should be avoided to ensure it becomes a real asset?

Read more
Blue sign on a building with several Now What? letters
Thibaut Chieux

How To Prioritize Messages When Building Asynchronous Applications With Symfony Messenger

Asynchronous processing offers benefits like decoupled processes and faster response times, but managing message priorities can become a challenge. When dealing with tasks ranging from password resets to complex exports, ensuring timely delivery of critical messages is essential. This article explores common asynchronous processing issues and provides solutions using Symfony Messenger, allowing you to optimize your application without extensive refactoring.

Read more
SensioLabs University Courses announcing the new level 3 Master training course now available
Jules Daunay

Master Symfony: Unlock Expert Skills with Our Training

Take your Symfony proficiency from good to great with the new Level 3 training course at SensioLabs! Master complex topics, optimize performance, and become a Symfony expert.

Read more
PHP 8.5
Oskar Stark

What's New in PHP 8.5: A Comprehensive Overview

PHP 8.5 will be released in November 2025 and brings several useful new features and improvements. This version focuses on developer experience enhancements, new utility functions, and better debugging capabilities.

Read more
Two images: on the left many cars stuck in a traffic jam with the sign "All directions" above, on the right a blue car moving forward alone on the highway with the sign "Service Subscriber" and a Symfony logo above
Steven Renaux

Symfony Lazy Services with Style: Boost DX using Service Subscribers

Boost your Symfony app's performance and developer experience! Learn how to use Service Subscribers and traits for lazy service loading to reduce eager instantiation, simplify dependencies, and create modular, maintainable code.

Read more
the surface of the earth seen from the space with city lights forming networks
Imen Ezzine

HTTP Verbs: Your Ultimate Guide

HTTP Verbs Explained: Learn the basics of GET, POST, PUT, DELETE, and more. This article explains how they work, their applications, and their security implications.

Read more
Poster of Guillaume Loulier presentation
Salsabile El-Khatouri

A Symfony Training at SensioLabs: Behind The Scenes

What does Symfony training at SensioLabs look like? Find out in this interview with Guillaume Loulier, a passionate developer and trainer, who tells us all about the official Symfony training courses.

Read more
AI and Symfony
Silas Joisten

Building AI-Driven Features in Symfony

AI is transforming web development — and with php-llm/llm-chain, PHP developers can easily add powerful LLM features to Symfony apps. This guide shows you how to get started with chatbots, smart assistants, and more.

Read more
Image