- Lab
-
Libraries: If you want this lab, consider one of these libraries.
- Core Tech
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 Info
Table of Contents
-
Challenge
Implementing the Strategy Pattern
Welcome to this Code Lab on refactoring with design patterns! We'll start with a
NotificationServicethat works but is poorly designed. Its mainsendNotificationmethod uses a largeif-elseblock 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
NotificationServiceto 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 forEmailandSMSnotifications.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. -
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-elseblock 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 aNotificationSenderFactorythat encapsulates the logic for creating the appropriate sender object based on the notification type. This removes the selection logic from theNotificationService, further decoupling our components. -
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 originalif-elsestructure and replace it with a clean, flexible, and pattern-based implementation that delegates the work to our new components. -
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
Pushnotification 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 coreNotificationServiceclass, 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
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.