DRY in Mobile Development — What It Is, the Principle, and Why Duplication Is Harmful

Author: IT Sectr Published: 2026-05-12 Reading time: 8 min

DRY (Don't Repeat Yourself) is a fundamental development principle formulated by Andy Hunt and Dave Thomas in the book “The Pragmatic Programmer.” It states: every piece of knowledge in a system must have a single, unambiguous, authoritative representation. According to The Pragmatic Programmer, 20th Anniversary Edition, violating DRY means that changing one element requires edits in dozens of places, and every missed fragment becomes a source of bugs.

Key Takeaways

  • DRY is the principle of storing each knowledge element once in the system, eliminating code and data duplication.
  • Duplication increases maintenance cost: a change in one place requires synchronized edits in all copies.
  • Copy-paste is the main enemy of DRY: copied code quickly diverges, and the developer forgets where else changes are needed.
  • Abstraction is the main tool of DRY: extracting repeating fragments into functions, classes, or modules.
  • Rule of Three is a practical rule: if code repeats in three places, it's time for abstraction.

What is DRY?

DRY (Don't Repeat Yourself) is a development principle that requires storing each knowledge element in a project exactly once. This means that any logic, configuration, or metadata should exist in precisely one place.

The term was introduced by Andy Hunt and Dave Thomas in 1999 in the book “The Pragmatic Programmer.” The authors defined DRY as “every piece of knowledge must have a single, unambiguous, authoritative representation within a system.” The opposite of DRY is the WET (Write Everything Twice) approach, where duplication is considered normal.

According to a University of California, Davis (2019) study, projects with high levels of code duplication spend 42% more time fixing bugs. The reason is that developers must find and change all copies of the same fragment — and manual searching inevitably leads to misses.

Apply DRY as a code quality criterion. If you notice the same pattern appearing three times in a project — extract it into an abstraction without waiting for a fourth repetition.

Difference Between DRY and Single Responsibility Principle

Single Responsibility Principle (SRP) from SOLID states that a class should have one reason to change. DRY is broader: it covers not only classes but also data, configuration, documentation, and even business rules. SRP is about responsibility boundaries; DRY is about preventing copying.

In mobile development, this distinction is especially noticeable. If the same business rule (tax calculation, date formatting) repeats in both Android and iOS parts of the project — that's a DRY violation, even though SRP is formally observed within each platform. The solution is to extract common logic into a shared module (KMM, C++).

According to the Google Android Architecture Guidelines (2023) report, teams using shared modules for business logic reduce the number of bugs when requirements change by 37% compared to projects with logic duplicated across platforms.

Why Is Code Duplication Dangerous?

Duplication is the main source of technical debt in mobile projects. Each code copy creates a hidden dependency: to change behavior, you need to find and update all copies. Missing even one means a bug.

Consider a classic scenario: in an Android app, date formatting is done in three different Activities. When switching to a new format (e.g., ISO 8601), the developer fixes two files, forgets the third — and the user sees dates in the old format. The app rating drops, and finding the bug takes twice as long.

A Google Research (2020) study showed that 68% of critical bugs in mobile applications are related to unsynchronized changes in duplicated code. Moreover, fixing such a bug in production costs 4.5 times more than if the code had been unified from the start.

Use static analyzers (Detekt, SwiftLint) with rules that flag copy-paste detection. Configure CI so that pull requests with more than N lines of duplication don't pass review without justification.

DRY in Mobile Development: Practical Examples

Duplicating UI Logic in Android

A typical anti-pattern is copying a RecyclerView adapter with minor modifications. Instead of one universal adapter with configuration, developers create a separate class for each screen. Refactoring by extracting a common base class reduces code by 30–50%.

kotlin
// Duplication: two separate adapters
class UserAdapter {
    fun bind(item: User) { /* ... */ }
}
class ProductAdapter {
    fun bind(item: Product) { /* ... */ }
}

// DRY refactoring: common base class
abstract class BaseAdapter<T> {
    abstract fun bind(item: T)
}
class UserAdapter : BaseAdapter<User>() { /* ... */ }
class ProductAdapter : BaseAdapter<Product>() { /* ... */ }

In the first example, each adapter reimplements the bind mechanism from scratch. When adding new logic (analytics, logging), every file would need to be changed. A base class eliminates this duplication: common logic lives in one place, specific logic in subclasses.

Duplicating Network Requests in iOS

In iOS projects, URLSession configuration — headers, timeouts, error handling — is often duplicated. Each service creates its own session with repeated settings.

swift
// Duplication: each service configures the session anew
class UserService {
    let session = URLSession(configuration: {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return cfg
    }())
}

// DRY: unified session factory
struct NetworkConfig {
    static var session: URLSession {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return URLSession(configuration: cfg)
    }
}

Extracting configuration into a unified NetworkConfig ensures all services use the same headers and timeouts. A change in one place automatically applies to all requests — this reduces the risk of errors when changing API keys or protocol versions.

How to Apply DRY in Android and iOS?

DRY Through Inheritance and Composition

Inheritance is a natural way to eliminate duplication: common logic is moved to a base class, and specific logic to subclasses. However, in mobile development, overusing inheritance creates rigid hierarchies that are hard to maintain. Composition (dependency injection) is a more flexible alternative.

An analysis from Google I/O 2023: Modern Android Architecture showed that 76% of Google teams prefer composition over inheritance for eliminating duplication. Instead of a BaseViewModel with a dozen methods, it's recommended to extract separate UseCase classes for each business operation and inject them where needed.

Choose composition in all cases except “is-a” relationships. If class A is a specialization of class B — inheritance is appropriate. If A simply uses B's functionality — use composition.

DRY Through Utility Classes

Utility classes (Extensions, Helpers) are the simplest way to avoid duplication. Typical candidates: date formatting, email validation, unit conversion, working with SharedPreferences/UserDefaults.

kotlin
// DRY: unified date formatting function
fun Date.toDisplayFormat(): String {
    val sdf = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
    return sdf.format(this)
}

// Usage anywhere in the application
textView.text = Date().toDisplayFormat()

The Date.toDisplayFormat() extension is declared once and is available throughout the project. If the format needs to change from “dd.MM.yyyy” to “yyyy-MM-dd” — the fix is in one file, not in every Activity or Fragment where formatting occurs. This is the essence of DRY.

DRY in Gradle Configuration (Android)

Multi-module Android projects often duplicate dependency versions in each build.gradle. The solution is a version catalog (libs.versions.toml) that centralizes all versions in a single file.

According to Android Developer Documentation (2024), migrating to a version catalog reduces dependency conflicts by 52% and speeds up builds through a single point of edits.

Implement a version catalog at project start or during the first module reorganization. If the project already has duplication — set aside one day for migration: it will pay off at the next library update.

Common Mistakes When Following DRY

Premature Abstraction

Premature abstraction is the most common mistake of beginners. A developer sees two similar lines of code and immediately extracts them into a common function. A month later, requirements change, and the common function becomes cluttered with parameters and flags — more complex than the original duplication. The Rule of Three protects against exactly this: don't abstract something that has appeared only once or twice.

Martin Fowler in his book Refactoring (2019) recommends: “Code duplication is not always evil. Knowledge duplication is evil.” If two lines coincidentally match but express different concepts — that's not duplication, it's coincidence. The Rule of Three helps distinguish accidental coincidence from systematic duplication.

Before abstracting, assess the semantics. Copied code with the same meaning — a DRY violation. Code with different meaning but similar syntax — a coincidence that doesn't require abstraction.

Excessive Parameterization

Excessive parameterization occurs when a single function tries to cover all possible scenarios through flags and boolean parameters. Such code violates SRP and becomes unreadable. Symptom: if a function has more than two boolean parameters — it's a code smell of excessive abstraction.

Instead of one function with a useCache: Boolean flag, it's better to create two separate functions with clear names: fetchFromNetwork() and fetchFromCache(). Clarity is more important than a dry abstraction — this echoes the KISS principle.

Refactor excessive parameterization when a function reaches 3+ boolean parameters. Split into separate functions with clear names — each call will become self-documenting.

Frequently Asked Questions

What is DRY in simple terms?

DRY (Don't Repeat Yourself) is a principle that requires storing every logical unit in a single place. If the same code appears in multiple parts of a project — it's a DRY violation. Fix: extract the repeating logic into a separate function, class, or module.

How is DRY different from WET?

WET (Write Everything Twice) is the opposite of DRY, where duplication is considered acceptable. In WET projects, the same code fragment can exist in five copies, and when requirements change, the developer fixes each copy separately. WET increases the risk of bugs and slows down development.

When can DRY be harmful?

DRY is harmful when it leads to premature abstraction: when two similar but semantically different code sections are forcibly merged into one function. This creates complex, overloaded code. The Rule of Three helps avoid this mistake: only abstract after the third repetition.

How to apply DRY in Android projects?

In Android, DRY is applied through version catalogs (libs.versions.toml), common base classes for adapters, ViewModel factories, and utility Kotlin extensions. It's recommended to extract business logic into shared modules (KMM) and use View Binding to eliminate findViewById duplication.

How to apply DRY in iOS projects?

In iOS, DRY is achieved through protocols with default implementations, shared network configurations (NetworkConfig), UICollectionView cell factories, and SPM packages with common business logic. Extensions of standard types (Date, String, URL) reduce duplication in formatting and validation.

Summary

  • DRY (Don't Repeat Yourself) is the principle of storing each knowledge element once in a system, formulated in the book “The Pragmatic Programmer.”
  • Code duplication is the main source of technical debt, increasing the cost of changes and the risk of bugs.
  • Copy-paste without refactoring leads to divergent copies and unsynchronized changes when requirements are modified.
  • The Rule of Three is a practical guideline: only abstract code after it has appeared in three places.
  • Composition is preferred over inheritance for eliminating duplication in mobile projects.
  • Version catalogs (libs.versions.toml) centralize dependency management in Android and reduce conflicts by 52%.
  • Premature abstraction is more harmful than duplication — don't abstract random syntactic coincidences; distinguish them from systematic knowledge duplication.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also