Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
5 views

Java Design Patterns

The document outlines various Java design patterns, including Singleton, Factory, Builder, Prototype, Observer, Decorator, and Adapter patterns, detailing their concepts, implementations, and use cases. Each pattern is accompanied by example code and interview questions to assess understanding. A comparison table summarizes the purpose and appropriate usage scenarios for each design pattern.

Uploaded by

Jha Avinash
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Java Design Patterns

The document outlines various Java design patterns, including Singleton, Factory, Builder, Prototype, Observer, Decorator, and Adapter patterns, detailing their concepts, implementations, and use cases. Each pattern is accompanied by example code and interview questions to assess understanding. A comparison table summarizes the purpose and appropriate usage scenarios for each design pattern.

Uploaded by

Jha Avinash
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Java Design Patterns

1. Singleton Pattern
Concept:

●​ Ensures that a class has only one instance and provides a global point of access
to it.
●​ Used when only one object should control the entire application's behavior (e.g.,
logging, database connection, configuration manager).

Implementation:

Eager Initialization (Thread-safe but may create unused instance)


java

class Singleton {
private static final Singleton instance = new Singleton(); //
Instance created eagerly
private Singleton() {} // Private constructor prevents
instantiation
public static Singleton getInstance() {
return instance;
}
}

Lazy Initialization (Not thread-safe)


java

class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // Creates instance only
when needed
}
return instance;
}
}
Thread-safe Singleton (Double-Checked Locking)
java

class Singleton {
private static volatile Singleton instance;

private Singleton() {}

public static Singleton getInstance() {


if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

Best Approach: Using Enum (Recommended)


java

enum Singleton {
INSTANCE;

public void show() {


System.out.println("Singleton using Enum");
}
}

Interview Questions:

1.​ Why should we use the Singleton pattern?


2.​ What are the different ways to implement Singleton?
3.​ What is the issue with lazy initialization in a multithreading environment?
4.​ How does volatile help in Singleton implementation?
5.​ Why is an Enum the best way to implement Singleton?
2. Factory Pattern
Concept:

●​ Used to create objects without exposing the creation logic to the client.
●​ Helps in handling object creation based on conditions.

Implementation:
java

// Step 1: Create an interface


interface Shape {
void draw();
}

// Step 2: Implement concrete classes


class Circle implements Shape {
public void draw() {
System.out.println("Drawing Circle");
}
}

class Rectangle implements Shape {


public void draw() {
System.out.println("Drawing Rectangle");
}
}

// Step 3: Create Factory class


class ShapeFactory {
public static Shape getShape(String type) {
if (type.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (type.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}

// Step 4: Usage
public class FactoryPatternDemo {
public static void main(String[] args) {
Shape shape1 = ShapeFactory.getShape("CIRCLE");
shape1.draw();

Shape shape2 = ShapeFactory.getShape("RECTANGLE");


shape2.draw();
}
}

Interview Questions:

1.​ What is the Factory pattern, and where is it used?


2.​ How is the Factory pattern different from the Singleton pattern?
3.​ Can we use Generics in the Factory pattern?
4.​ How does the Factory pattern help in Open/Closed Principle?

3. Builder Pattern
Concept:

●​ Used to construct complex objects step by step.


●​ Useful when a class has multiple optional parameters.

Implementation:
java

class Computer {
// Required parameters
private String CPU;
private int RAM;

// Optional parameters
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;

private Computer(ComputerBuilder builder) {


this.CPU = builder.CPU;
this.RAM = builder.RAM;
this.isGraphicsCardEnabled = builder.isGraphicsCardEnabled;
this.isBluetoothEnabled = builder.isBluetoothEnabled;
}

public static class ComputerBuilder {


private String CPU;
private int RAM;
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;

public ComputerBuilder(String CPU, int RAM) {


this.CPU = CPU;
this.RAM = RAM;
}

public ComputerBuilder setGraphicsCardEnabled(boolean


isGraphicsCardEnabled) {
this.isGraphicsCardEnabled = isGraphicsCardEnabled;
return this;
}

public ComputerBuilder setBluetoothEnabled(boolean


isBluetoothEnabled) {
this.isBluetoothEnabled = isBluetoothEnabled;
return this;
}

public Computer build() {


return new Computer(this);
}
}
}

// Usage
public class BuilderPatternDemo {
public static void main(String[] args) {
Computer computer = new Computer.ComputerBuilder("Intel i7",
16)
.setGraphicsCardEnabled(true)
.setBluetoothEnabled(false)
.build();
}
}
Interview Questions:

1.​ What problem does the Builder pattern solve?


2.​ How is it different from the Factory pattern?
3.​ How does the Builder pattern support immutability?
4.​ Can we modify the Builder class after creating an object?

4. Prototype Pattern
Concept:

●​ Creates objects by copying an existing object instead of creating new instances.

Implementation:
java

class Prototype implements Cloneable {


String name;

public Prototype(String name) {


this.name = name;
}

@Override
protected Prototype clone() throws CloneNotSupportedException {
return (Prototype) super.clone();
}
}

public class PrototypePatternDemo {


public static void main(String[] args) throws
CloneNotSupportedException {
Prototype p1 = new Prototype("Original");
Prototype p2 = p1.clone();

System.out.println(p1.name);
System.out.println(p2.name);
}
}
Interview Questions:

1.​ How does the Prototype pattern work?


2.​ What is the difference between shallow copy and deep copy?
3.​ How can we implement deep cloning in Java?

5. Observer Pattern
Concept:

●​ Used when one object (Subject) needs to notify multiple dependent objects
(Observers) about state changes.

Implementation:
java

import java.util.ArrayList;
import java.util.List;

// Observer interface
interface Observer {
void update(String message);
}

// Concrete Observer
class User implements Observer {
private String name;

public User(String name) {


this.name = name;
}

@Override
public void update(String message) {
System.out.println(name + " received message: " + message);
}
}

// Subject class
class Channel {
private List<Observer> observers = new ArrayList<>();
public void subscribe(Observer observer) {
observers.add(observer);
}

public void notifyObservers(String message) {


for (Observer observer : observers) {
observer.update(message);
}
}
}

// Usage
public class ObserverPatternDemo {
public static void main(String[] args) {
Channel channel = new Channel();

Observer user1 = new User("Alice");


Observer user2 = new User("Bob");

channel.subscribe(user1);
channel.subscribe(user2);

channel.notifyObservers("New Video Uploaded!");


}
}

Interview Questions:

1.​ What is the Observer pattern?


2.​ What is the difference between the Observer and Publisher-Subscriber patterns?

6. Decorator Pattern
Concept:

●​ Used to dynamically add behaviors to objects without modifying their code.


●​ Follows Open/Closed Principle (open for extension, closed for modification).

Use Case:
●​ When we want to extend functionality of classes without altering their structure.
●​ Example: Adding extra features to coffee (like sugar, milk) without modifying the
base Coffee class.

Implementation:
java

// Step 1: Create Component Interface


interface Coffee {
String getDescription();
double cost();
}

// Step 2: Concrete Component


class SimpleCoffee implements Coffee {
public String getDescription() {
return "Simple Coffee";
}

public double cost() {


return 50;
}
}

// Step 3: Decorator Abstract Class


abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;

public CoffeeDecorator(Coffee coffee) {


this.coffee = coffee;
}

public String getDescription() {


return coffee.getDescription();
}

public double cost() {


return coffee.cost();
}
}
// Step 4: Concrete Decorators
class Milk extends CoffeeDecorator {
public Milk(Coffee coffee) {
super(coffee);
}

public String getDescription() {


return coffee.getDescription() + ", Milk";
}

public double cost() {


return coffee.cost() + 10;
}
}

class Sugar extends CoffeeDecorator {


public Sugar(Coffee coffee) {
super(coffee);
}

public String getDescription() {


return coffee.getDescription() + ", Sugar";
}

public double cost() {


return coffee.cost() + 5;
}
}

// Step 5: Usage
public class DecoratorPatternDemo {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println(coffee.getDescription() + " = Rs." +
coffee.cost());

coffee = new Milk(coffee);


System.out.println(coffee.getDescription() + " = Rs." +
coffee.cost());
coffee = new Sugar(coffee);
System.out.println(coffee.getDescription() + " = Rs." +
coffee.cost());
}
}

Output:
java

Simple Coffee = Rs.50.0


Simple Coffee, Milk = Rs.60.0
Simple Coffee, Milk, Sugar = Rs.65.0

Interview Questions:

1.​ What is the purpose of the Decorator pattern?


2.​ How is it different from inheritance?
3.​ Where is the Decorator pattern used in Java?
4.​ Can we have multiple decorators applied at once?

7. Adapter Pattern
Concept:

●​ Converts one interface into another so that two incompatible interfaces can work
together.
●​ Acts as a bridge between two classes.

Use Case:

●​ When we need to use a legacy class with a new system.


●​ Example: Suppose we have an OldCharger with a roundPin(), but we need a
charger that supports flatPin(). The Adapter helps convert it.

Implementation:
java

// Step 1: Create Target Interface


interface NewCharger {
void chargeWithFlatPin();
}

// Step 2: Adaptee (Old Interface)


class OldCharger {
public void chargeWithRoundPin() {
System.out.println("Charging with Round Pin");
}
}

// Step 3: Adapter Class


class ChargerAdapter implements NewCharger {
private OldCharger oldCharger;

public ChargerAdapter(OldCharger oldCharger) {


this.oldCharger = oldCharger;
}

public void chargeWithFlatPin() {


System.out.println("Adapter converts flat pin to round
pin...");
oldCharger.chargeWithRoundPin();
}
}

// Step 4: Usage
public class AdapterPatternDemo {
public static void main(String[] args) {
OldCharger oldCharger = new OldCharger();
NewCharger newCharger = new ChargerAdapter(oldCharger);

newCharger.chargeWithFlatPin();
}
}

Output:

Adapter converts flat pin to round pin...


Charging with Round Pin
Interview Questions:

1.​ What is the Adapter pattern, and why is it used?


2.​ What are the types of Adapter patterns?
○​ Class Adapter (uses inheritance)
○​ Object Adapter (uses composition)
3.​ How is the Adapter pattern different from the Decorator pattern?
4.​ Can the Adapter pattern be used with multiple incompatible interfaces?

Comparison of Design Patterns:


Pattern Purpose When to Use?

Singleton Ensures one instance of a When a single control point is needed (e.g.,
class database connection, logging)

Factory Creates objects based on When object creation logic is complex or


conditions depends on user input

Builder Constructs objects step by When an object has many optional


step parameters

Prototyp Creates objects by cloning When object creation is expensive and


e existing ones duplication is required

Observer Notifies dependent objects When multiple objects should react to one
about state changes object's changes (e.g., event listeners)

Decorato Adds behavior dynamically When we want to enhance functionality


r to an object without modifying the base class

Adapter Converts one interface into When we need to integrate incompatible


another systems

You might also like