Discuss common design patterns and their implementation in Java.

 


Introduction

  • Overview of design patterns in software development.
  • Why design patterns are crucial for writing scalable, maintainable, and reusable code.
  • Categories of design patterns:
  • Creational — Object creation mechanisms.
  • Structural — Class and object composition.
  • Behavioral — Communication between objects.

1. Creational Design Patterns

1.1 Singleton Pattern

  • Ensures that only one instance of a class is created.
  • Used for logging, database connections, and configuration management.

Implementation:

java
public class Singleton {
private static Singleton instance;

private Singleton() {} // Private constructor
    public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

Use Case: Database connection manager.

1.2 Factory Pattern

  • Provides an interface for creating objects without specifying their exact class.

Implementation:

java
interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() { System.out.println("Drawing Circle"); }
}
class Square implements Shape {
public void draw() { System.out.println("Drawing Square"); }
}
class ShapeFactory {
public static Shape getShape(String type) {
if (type.equalsIgnoreCase("CIRCLE")) return new Circle();
if (type.equalsIgnoreCase("SQUARE")) return new Square();
return null;
}
}
// Usage
Shape shape = ShapeFactory.getShape("CIRCLE");
shape.draw();

Use Case: UI component creation (e.g., buttons, text fields).

1.3 Builder Pattern

  • Used for constructing complex objects step by step.

Implementation:

java
class Car {
private String engine;
private int wheels;
    public static class Builder {
private String engine;
private int wheels;
        public Builder setEngine(String engine) {
this.engine = engine;
return this;
}
        public Builder setWheels(int wheels) {
this.wheels = wheels;
return this;
}
        public Car build() {
return new Car(this);
}
}
    private Car(Builder builder) {
this.engine = builder.engine;
this.wheels = builder.wheels;
}
}
// Usage
Car car = new Car.Builder().setEngine("V8").setWheels(4).build();

Use Case: Configuring objects with multiple optional parameters (e.g., HTTP requests).

2. Structural Design Patterns

2.1 Adapter Pattern

  • Allows incompatible interfaces to work together.

Implementation:

java
interface MediaPlayer {
void play(String audioType);
}
class MP3Player implements MediaPlayer {
public void play(String audioType) {
System.out.println("Playing MP3 file");
}
}
class MP4Player {
void playMP4() {
System.out.println("Playing MP4 file");
}
}
class MediaAdapter implements MediaPlayer {
private MP4Player mp4Player;
    public MediaAdapter() {
mp4Player = new MP4Player();
}
    public void play(String audioType) {
if (audioType.equalsIgnoreCase("MP4")) {
mp4Player.playMP4();
}
}
}
// Usage
MediaPlayer player = new MediaAdapter();
player.play("MP4");

Use Case: Integrating third-party libraries.

2.2 Decorator Pattern

  • Dynamically adds behavior to objects.

Implementation:

java
interface Coffee {
String getDescription();
double cost();
}
class SimpleCoffee implements Coffee {
public String getDescription() { return "Simple Coffee"; }
public double cost() { return 5.0; }
}
class MilkDecorator implements Coffee {
private Coffee coffee;
    public MilkDecorator(Coffee coffee) {
this.coffee = coffee;
}
    public String getDescription() { return coffee.getDescription() + ", Milk"; }
public double cost() { return coffee.cost() + 1.5; }
}
// Usage
Coffee coffee = new MilkDecorator(new SimpleCoffee());
System.out.println(coffee.getDescription() + " - $" + coffee.cost());

Use Case: Adding toppings to a coffee order in an online coffee shop.

3. Behavioral Design Patterns

3.1 Observer Pattern

  • Defines a one-to-many dependency between objects.

Implementation:

java
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class Subscriber implements Observer {
private String name;
    public Subscriber(String name) {
this.name = name;
}
    public void update(String message) {
System.out.println(name + " received: " + message);
}
}
class Publisher {
private List<Observer> observers = new ArrayList<>();
    public void addObserver(Observer observer) {
observers.add(observer);
}
    public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
// Usage
Publisher newsPublisher = new Publisher();
Observer user1 = new Subscriber("Alice");
Observer user2 = new Subscriber("Bob");
newsPublisher.addObserver(user1);
newsPublisher.addObserver(user2);
newsPublisher.notifyObservers("New article published!");

Use Case: Event-driven notifications (e.g., stock market updates, messaging apps).

3.2 Strategy Pattern

  • Defines a family of algorithms, encapsulates them, and makes them interchangeable.

Implementation:

java
interface PaymentStrategy {
void pay(int amount);
}
class CreditCardPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid $" + amount + " using Credit Card.");
}
}
class PayPalPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid $" + amount + " using PayPal.");
}
}
class PaymentContext {
private PaymentStrategy strategy;
    public void setPaymentStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
    public void pay(int amount) {
strategy.pay(amount);
}
}
// Usage
PaymentContext context = new PaymentContext();
context.setPaymentStrategy(new PayPalPayment());
context.pay(100);

Use Case: Payment gateway selection (Credit Card, PayPal, etc.).

Conclusion

  • Design patterns enhance code reusability, scalability, and maintainability.
  • Each pattern solves a specific design problem efficiently.
  • Choosing the right pattern is key to writing better Java applications.

🔹 Next Steps:

  • Explore Java Design Pattern Libraries like Spring Framework.
  • Implement patterns in real-world projects.
  • Experiment with combining multiple patterns.

Comments

Popular posts from this blog

Best Practices for Secure CI/CD Pipelines

What is DevSecOps? Integrating Security into the DevOps Pipeline

SEO for E-Commerce: How to Rank Your Online Store