Design Pattern Notes
Design Pattern Notes
Design Patterns
Patterns Covered
Database Private
Ensure a class has only
Creational Singleton connection, constructor, static
one instance
config manager instance
Converts interface
Bridge between Legacy system
Structural Adapter to match client
incompatible interfaces integration
expectation
Payment
Define interchangeable methods, Encapsulates
Behavioral Strategy
algorithms sorting algorithm logic
strategies
State-dependent
Change behavior when Media players,
State behavior without
internal state changes UI modes
conditionals
One-to-many
Notify multiple objects Event systems, relationship with
Observer
about state changes UI components automatic
notification
📝 Singleton Design Patterns
public class A { We have only one object per class, and
everyone should be able to use it. If we want to
private static A a;
🔒🧩
access a single component everywhere, we
can use the Singleton Design Pattern.
private A() {} // Private constructor
1️⃣ The class must be public.
public static A getA() { 2️⃣ It must have a private static variable.
if (a == null) { 3️⃣ It must have a private constructor.
a = new A();
}
return a;
}
}
class Test {
public static void main(String[] args) {
A a1 = A.getA();
A a2 = A.getA();
🌟 Separate 3 rows.
🌟 In the first row, write the class name, interface name, abstract class name.
🌟 In the second row, write the variables.
🌟 In the third row, write the method.
🌟 If underlined, it is static, if not underlined, it is instances.
🌟 (-) Mark private (+) Mark public
🌟 A colon (:) is used to indicate the data type.
🌟 The final keyword is indicated by an underscore (-) symbol.
🌟 Abstract class is indicated by italic type.
📝 Factory Design Pattern
interface Vehicle { Directly creating an object from a class is
public abstract void drive(); prohibited, and objects are created with
} logic from a factory.
class Car implements Vehicle {
@Override
public void drive() {
System.out.println("Driving a car...");
}
}
class VehicleFactory {
public Vehicle makeVehicle(String type) {
if (type.equals("Car")) {
return new Car();
} else if (type.equals("Bike")) {
return new Bike();
} else {
return null;
}
}
}
class TestVehicle {
public static void main(String[] args) {
VehicleFactory factory = new VehicleFactory();
Vehicle v1 = factory.makeVehicle("Car");
v1.drive();
Vehicle v2 = factory.makeVehicle("Bike");
v2.drive();
}
}
Factory - +createProduct(type)
ConcreteProduct - +operation()
📝Adapter Design Pattern Notes
Adaptee - + specificRequest()
class Laptop {
private SD sd;
public void setSd(SD sd) { this.sd = sd; }
public void viewFile() { sd.readSDCard(); }
}
class C {
public void c1() {
System.out.println("C.c1");
}
}
class X {
private A a; Class Attributes Methods
private B b;
private C c;
- subsystem 1: Subsystem 1
+ Facade()
public X() { Facade - subsystem 2: Subsystem 2
+ operation()
a = new A(); - subsystem 3: Subsystem 3
b = new B();
c = new C();
} Subsystem 1 + operation 1()
@Override
public void display() {
System.out.println("Displaying image: " + filename);
}
}
interface Strategy {
public boolean check(String text);
}
b = true;
break; // Exit loop once 'j' is found ConcreteStrategyB - + execute()
}
}
+setStrategy(stra
return b; Context - strategy: Strategy tegy: Strategy)
} + useStrategy()
}
class Context {
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public boolean useStrategy(String text) {
return strategy.check(text);
}
}
class Test {
public static void main(String[] args) {
String text = "Hello Java";
Context context = new Context();
context.setStrategy(new SahanStrategy());
System.out.println("SahanStrategy result: " + context.useStrategy(text));
context.setStrategy(new KasunStrategy());
System.out.println("KasunStrategy result: " + context.useStrategy(text));
}
}
📝 Template Method Design Pattern
The class that designs the algorithm must
abstract class A { be an abstract class.
public final void process() { The method that writes the algorithm must
m();
be final.
n();
p();
}
private void m() {
System.out.println("m");
}
class X extends A {
@Override
public void n() {
System.out.println("X.n");
}
}
class Test {
Real-World Analogy
public static void main(String[] args) {
A a = new X();
a.process();
}
}
class TestPrinter {
public static void main(String[] args) {
DocumentPrinter p1 = new InvoicePrinter();
p1.printDocumentProcess();
interface Command {
void execute();
}
class Robot {
void walk() {
System.out.println("Robot is walking");
}
void speak() {
System.out.println("Robot is speaking");
}
}
inv.setCommand(speak);
inv.invoke();
}
}
Command - +execute()
Receiver - +action()
📝 Iterator Design Pattern
The common model for reading any collection is to use an
interface BookIterator { iterator.
boolean hasNext(); This pattern is only relevant for collections.
Object next();
}
class Zookeeper {
private Animal animal;
class TestZoo {
public static void main(String[] args) {
Zookeeper zookeeper = new Zookeeper();
zookeeper.setAnimal(lion);
zookeeper.commandSound();
zookeeper.setAnimal(elephant);
zookeeper.commandSound();
}
}
Class / Interface Attributes Methods
State - +handle()
Observer - +update()