Skip to main content

Command Palette

Search for a command to run...

YAGNI Principle in Java

Published
5 min read
YAGNI Principle in Java

Stop Writing Code for Problems That Don’t Exist Yet

When developers design software, a common mistake is adding features for the future.

You might think:

“We might need this later… let's build it now.”

But most of the time:

  • That feature is never used

  • Requirements change completely

  • The system becomes more complex

This is where the YAGNI Principle comes in.


What is the YAGNI Principle?

YAGNI stands for:

You Aren’t Gonna Need It

The principle says:

Do not add functionality until it is actually required.

It originated from Extreme Programming, an Agile development methodology.

Instead of predicting the future, developers should focus on current requirements only.


Why YAGNI Matters

When developers ignore YAGNI, they often create:

❌ unnecessary abstractions
❌ unused features
❌ complicated architectures

This leads to:

  • harder debugging

  • slower development

  • difficult maintenance

YAGNI encourages developers to build simple and clean code first.


Example Scenario

Suppose you are building a User Registration System.

Current requirement:

✔ Send email notification after registration.

A developer might think:

"Later we may need SMS and Push notifications, so let's implement everything now."

This violates the YAGNI principle.


Example: Violating YAGNI

Here the developer creates a generic notification system even though only email is required.

interface NotificationService {
    void sendNotification(String message);
}

Email implementation:

class EmailNotification implements NotificationService {

    @Override
    public void sendNotification(String message) {
        System.out.println("Sending Email: " + message);
    }
}

SMS implementation (not required now):

class SMSNotification implements NotificationService {

    @Override
    public void sendNotification(String message) {
        System.out.println("Sending SMS: " + message);
    }
}

Push notification implementation:

class PushNotification implements NotificationService {

    @Override
    public void sendNotification(String message) {
        System.out.println("Sending Push Notification: " + message);
    }
}

User service:

class UserService {

    private NotificationService notificationService;

    public UserService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }

    public void registerUser(String username) {

        System.out.println(username + " registered successfully");

        notificationService.sendNotification(
            "Welcome " + username
        );
    }
}

Problems in this design

Even though it looks flexible, we introduced:

  • 3 extra classes

  • an interface

  • dependency complexity

But the system only needs email notifications.

This is overengineering.


Example: Applying YAGNI

Instead, we implement only what is needed today.

Email service:

class EmailService {

    public void sendEmail(String message) {
        System.out.println("Sending Email: " + message);
    }
}

User registration:

class UserService {

    private EmailService emailService = new EmailService();

    public void registerUser(String username) {

        System.out.println(username + " registered successfully");

        emailService.sendEmail(
            "Welcome " + username
        );
    }
}

Benefits

✔ Simple implementation

✔ Easy to maintain

✔ Less code

✔ Faster development

If SMS or Push notifications are required later, we can refactor and extend the system then.


Real World Example

Imagine building an online learning platform.

Initial requirement:

✔ Users should watch video lessons

A developer ignoring YAGNI might add:

  • AI recommendations

  • course analytics

  • offline download

  • subtitle translation

  • multi-device synchronization

But the Minimum Viable Product (MVP) only needs:

✔ video player
✔ course list

Everything else can be built later when users actually need it.


YAGNI Decision Flow

A simple YAGNI decision process:

1️⃣ Identify the feature idea

2️⃣ Ask: Is this required right now?

If No → Do NOT implement it
If Yes → Implement the simplest solution

This keeps the system clean and adaptable.


Advantages of YAGNI

1. Simpler Code

Less abstraction and fewer classes.

2. Faster Development

Developers focus only on real requirements.

3. Easier Maintenance

Less unused code to manage.

4. Better Flexibility

Future changes can be implemented cleanly.


Common Misunderstanding

YAGNI does not mean:

❌ Avoid planning
❌ Write messy code
❌ Ignore architecture

It means:

✔ Avoid premature implementation of features.


YAGNI vs Overengineering

Approach Result
Overengineering Complex system
Premature optimization Hard to modify
YAGNI Simple and maintainable
Minimal implementation Faster iteration

Famous Quote

“Always implement things when you actually need them, never when you just foresee that you need them.”

This philosophy helps developers keep software clean, maintainable, and scalable.


Final Thoughts

The YAGNI Principle reminds developers that:

Great software is not about writing more code.

It is about writing only the code that truly matters.

Follow these rules:

✔ Build only what is required today
✔ Keep the implementation simple
✔ Extend the system when new requirements appear

If applied correctly, YAGNI helps developers build clean, maintainable, and flexible systems.


Design Principles for Java Developers

Part 7 of 10

This series explains core Java design principles and SOLID principles with simple examples, real-world use cases, and interview-focused explanations to help developers write clean, maintainable, and scalable code.

Up next

KISS Principle in Java

Keep It Simple, Stupid — Design That Actually Works Introduction As Java developers, we often fall into a common trap:more code = more intelligence. In reality, the best software systems are usually: