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: Implement Design Patterns in a Java Service

Improve your software design skills by refactoring a real-world Java service. In this lab, you’ll start with a rigid, hard-to-maintain notification service and apply the Strategy and Factory design patterns to transform it into a flexible, testable, and extensible system. You’ll learn not just what these patterns are, but when and why to use them to simplify complex logic and reduce code duplication.

Lab platform
Lab Info
Level
Intermediate
Last updated
Oct 23, 2025
Duration
45m

Contact sales

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

    Implementing the Strategy Pattern

    Welcome to this Code Lab on refactoring with design patterns! We'll start with a NotificationService that works but is poorly designed. Its main sendNotification method uses a large if-else block to decide how to send a notification. This makes it hard to maintain, test, and extend. Your goal is to refactor it using the Strategy and Factory patterns to improve its design without changing what it does.

    Strategy Pattern

    The first step is to apply the Strategy pattern. This pattern involves creating a common interface (the strategy) for a group of related algorithms and then creating concrete classes that implement this interface. This will allow the NotificationService to use any notification-sending algorithm without being tightly coupled to its implementation. You will start by defining the strategy interface and then creating concrete classes for Email and SMS notifications.

    If you encounter any difficulties during any step, you can reference the /solution/step# directory where the complete solution is available. --- 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

    Implementing the Factory Pattern

    While the Strategy pattern helps to define a family of algorithms, you still need a way to choose the correct one at runtime. A big if-else block in the service to select the strategy would defeat the purpose of our refactoring. This is where the Factory pattern comes in. You'll create a NotificationSenderFactory that encapsulates the logic for creating the appropriate sender object based on the notification type. This removes the selection logic from the NotificationService, further decoupling our components.

  3. Challenge

    Refactoring the Notification Service

    With the strategies and factory in place, it's time for the main event: refactoring the NotificationService. You'll now remove the original if-else structure and replace it with a clean, flexible, and pattern-based implementation that delegates the work to our new components.

  4. Challenge

    Extending the Service

    The refactoring is complete! The final step is to prove the value of the new design by extending it. You'll add a new Push notification type. Observe how easy this is compared to the original design. You only need to create a new strategy class and make a small update to our factory. The core NotificationService class, which contains the main business logic, requires no changes at all. This is the Open/Closed Principle in action! Congratulations — you've finished the lab! By completing these steps you refactored a rigid service into a flexible design that follows the Strategy and Factory patterns. These changes improved the code's maintainability, testability, and extensibility.

    Try it out! Test your refactored service interactively by running:

    cd application
    mvn compile exec:java -Dexec.mainClass="com.example.notification.Main"
    

    This will start a command-line demo where you can enter different notification types (EMAIL, SMS, PUSH), recipients, and messages to see your service in action.

    Great work!

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