Hello, Java developers!
Today, we’re going to discuss Design Patterns in Java. Design patterns are typical solutions to commonly occurring problems in software design. They are like templates that can be applied to real-world coding situations.
We’ll focus on three fundamental design patterns: Observer, Singleton, and Factory.
Observer Pattern
The Observer pattern is used when there is a one-to-many relationship between objects, such as if one object is modified, its dependent objects are to be notified automatically.
Example Implementation:
java
Copy code
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class ConcreteObserver implements Observer {
private String observerState;
public void update(String message) {
observerState = message;
System.out.println("State changed to: " + observerState);
}
}
class Subject {
private final List observers = new ArrayList<>();
private String state;
public void attach(Observer o) {
observers.add(o);
}
public void setState(String state) {
this.state = state;
notifyAllObservers();
}
private void notifyAllObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
}
Singleton Pattern
The Singleton pattern ensures a class has only one instance and provides a global point of access to it.
Example Implementation:
java
Copy code
class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Factory Pattern
The Factory pattern is used when we have a superclass with multiple sub-classes and based on input, we need to return one class instance.
Example Implementation:
java
Copy code
interface Shape {
void draw();
}
class Rectangle implements Shape {
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
class Circle implements Shape {
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
class ShapeFactory {
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}
return null;
}
}
Exercise: Implement a Design Pattern in Java
Now, it’s your turn. Choose one of the design patterns (Observer, Singleton, or Factory) and implement it in a Java application. For example:
Implement the Singleton pattern in a scenario where you need a single database connection shared across the application.Use the Factory pattern to create different geometric shapes in a drawing application.Apply the Observer pattern to build a simple event notification system.Conclusion
Well done! Understanding and implementing design patterns is crucial for building robust and maintainable Java applications. These patterns provide tested and proven solutions to common software design challenges.
Experiment with these patterns and try incorporating them into your projects to see the benefits they offer in terms of code organization and scalability.
Happy coding, and explore the world of design patterns in Java!