Featured resource
2026 Tech Forecast
2026 Tech Forecast

Stay ahead of what’s next in tech with predictions from 1,500+ business leaders, insiders, and Pluralsight Authors.

Get these insights
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Guided: Refactor Java Notification Application Using SOLID Principles

In this Code Lab, students will refactor a simple Java notification application to adhere to SOLID principles. Starting with a single class that violates these principles, they will step by step transform it into a well-designed, maintainable, and extensible system.

Lab platform
Lab Info
Level
Intermediate
Last updated
Oct 24, 2025
Duration
35m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use.
Table of Contents
  1. Challenge

    Step 1: Introduction and Initial Setup

    Welcome to the SOLID principles Code Lab! In software engineering, SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible, and maintainable.

    In this first step, you will become familiar with the project structure and run the initial set of tests. The starter code contains a NotificationService class (located at src/main/java/com/solid/notification/NotificationService.java) that works but violates several SOLID principles. The goal is to refactor it step by step. > This lab experience was developed by the Pluralsight team using Forge, an internally developed AI tool utilizing Gemini technology. All sections were verified by human experts for accuracy prior to publication. For issue reporting, please contact us.

  2. Challenge

    Step 2: The Single Responsibility Principle (SRP)

    The Single Responsibility Principle states that a class should have only one reason to change. The current NotificationService class (in src/main/java/com/solid/notification/NotificationService.java) is responsible for sending both emails and SMS messages. If the SMS sending logic needs to change, a class that also contains email logic must be modified. This is a clear violation of SRP.

    In this step, the NotificationService will be refactored into smaller, more focused classes: EmailService and SmsService.

  3. Challenge

    Step 3: The Open/Closed Principle (OCP)

    The Open/Closed Principle asserts that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. This means it should be possible to add new functionality without changing existing code.

    To adhere to OCP, a Notification interface will be introduced at src/main/java/com/solid/notification/interfaces/Notification.java. All notification services (EmailService, SmsService, and the new PushNotificationService) will implement this interface, allowing new services to be added in the future without altering the code that uses these services.

  4. Challenge

    Step 4: Liskov Substitution (LSP) and Interface Segregation (ISP)

    The Interface Segregation Principle (ISP) states that no client should be forced to depend on methods it does not use. The current Notification interface is simple, but what if some notifications support video and others don't? Forcing all classes to have a sendVideo method violates ISP.

    The Liskov Substitution Principle (LSP) states that objects of a superclass should be replaceable with objects of its subclasses without breaking the application.

    In this step, more specific interfaces will be created: TextNotification (in src/main/java/com/solid/notification/interfaces/TextNotification.java) and MultimediaNotification (in src/main/java/com/solid/notification/interfaces/MultimediaNotification.java) to follow ISP and ensure the class hierarchy respects LSP.

  5. Challenge

    Step 5: The Dependency Inversion Principle (DIP)

    The Dependency Inversion Principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions. Also, abstractions should not depend on details. Details should depend on abstractions.

    A high-level NotificationManager (in src/main/java/com/solid/notification/NotificationManager.java) will be created that depends on the Notification interface (an abstraction), not on concrete classes like EmailService. The specific service to use will be 'injected'. Finally, the application in src/main/java/com/solid/notification/Main.java will be updated to see everything working together.

  6. Challenge

    Step 6: Compilation and Execution

    Congratulations! In this lab, you've successfully transformed a poorly designed notification application into a well-architected system that embodies all five SOLID principles.

    You started with a monolithic NotificationService class and systematically refactored it by applying the Single Responsibility Principle to separate concerns, the Open/Closed Principle to enable extensibility, the Liskov Substitution and Interface Segregation Principles to create focused, substitutable contracts, and the Dependency Inversion Principle to decouple high-level logic from concrete implementations.

    Through this hands-on experience, you've learned how to write Java code that is more maintainable, testable, and adaptable to change, skills that are fundamental to professional software engineering.

About the author

Pluralsight Code Labs offer an opportunity to get hands-on learning in real-time. Be it a Challenge, Sandbox, or Guided Lab, these provide the real world experience needed to succeed in your development role.

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight