diff --git a/content/post/dp.md b/content/post/dp.md
new file mode 100644
index 0000000..d5adea7
--- /dev/null
+++ b/content/post/dp.md
@@ -0,0 +1,347 @@
+---
+title: "DP - Design Patterns"
+description: "Design Patterns in Java."
+date: 2024-12-30T13:00:00Z
+draft: false
+---
+
+Overview of the simplest and most common design patterns according to the book *"Design Patterns Elements of Reusable Object-Oriented Software"*:
+
+- Abstract Factory
+- Factory Method
+- Adapter
+- Composite
+- Decorator
+- Observer
+- Strategy
+- Template Method
+
+# Creational Patterns
+
+**Abstract Factory**:
+
+Creates families of related objects without specifying their concrete classes.
+It provides a higher level of abstraction, enabling the client to produce multiple types of objects from a single factory.
+
+```java
+public interface ButtonFactory {
+    Button createButton();
+}
+
+public class WindowsButtonFactory implements ButtonFactory {
+    public Button createButton() {
+        return new WindowsButton();
+    }
+}
+
+public class MacButtonFactory implements ButtonFactory {
+    public Button createButton() {
+        return new MacButton();
+    }
+}
+
+public interface Button {
+    void render();
+}
+
+public class WindowsButton implements Button {
+    public void render() {
+        System.out.println("Rendering Windows Button");
+    }
+}
+
+public class MacButton implements Button {
+    public void render() {
+        System.out.println("Rendering Mac Button");
+    }
+}
+```
+
+**Factory Method**:
+
+Defines a method for creating objects, but allows subclasses to decide which object to instantiate.
+This pattern promotes loose coupling by relying on the subclass for the specific implementation.
+
+```java
+public interface Button {
+    void render();
+}
+
+public class WindowsButton implements Button {
+    public void render() {
+        System.out.println("Rendering Windows Button");
+    }
+}
+
+public class MacButton implements Button {
+    public void render() {
+        System.out.println("Rendering Mac Button");
+    }
+}
+
+public abstract class UIFactory {
+    public void renderInterface() {
+        Button button = createButton();
+        button.render();
+    }
+
+    protected abstract Button createButton();
+}
+
+public class WindowsUIFactory extends UIFactory {
+    @Override
+    protected Button createButton() {
+        return new WindowsButton();
+    }
+}
+
+public class MacUIFactory extends UIFactory {
+    @Override
+    protected Button createButton() {
+        return new MacButton();
+    }
+}
+```
+
+# Structural Patterns
+
+**Adapter**:
+
+Acts as a bridge between two incompatible interfaces.
+It allows existing classes to work together without modifying their source code by adapting their interfaces.
+
+```java
+public interface USB {
+    void connectWithUSBPort();
+}
+
+public class HDMI {
+    public void connectWithHDMIPort() {
+        System.out.println("Connected using HDMI port");
+    }
+}
+
+public class HDMIToUSBAdapter implements USB {
+    private HDMI hdmiDevice;
+
+    public HDMIToUSBAdapter(HDMI hdmiDevice) {
+        this.hdmiDevice = hdmiDevice;
+    }
+
+    @Override
+    public void connectWithUSBPort() {
+        System.out.print("Adapting HDMI to USB: ");
+        hdmiDevice.connectWithHDMIPort();
+    }
+}
+```
+
+**Composite**:
+
+Enables you to compose objects into tree structures to represent part-whole hierarchies.
+The pattern treats individual objects and compositions of objects uniformly, simplifying client code.
+
+```java
+public interface FileSystemItem {
+    void display(String indent);
+}
+
+public class File implements FileSystemItem {
+    private String name;
+
+    public File(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public void display(String indent) {
+        System.out.println(indent + "File: " + name);
+    }
+}
+
+public class Directory implements FileSystemItem {
+    private String name;
+    private List<FileSystemItem> items = new ArrayList<>();
+
+    public Directory(String name) {
+        this.name = name;
+    }
+
+    public void add(FileSystemItem item) {
+        items.add(item);
+    }
+
+    public void remove(FileSystemItem item) {
+        items.remove(item);
+    }
+
+    @Override
+    public void display(String indent) {
+        System.out.println(indent + "Directory: " + name);
+        for (FileSystemItem item : items) {
+            item.display(indent + "  ");
+        }
+    }
+}
+```
+
+**Decorator**:
+
+Attaches additional behavior or responsibilities to an object dynamically.
+It provides a flexible alternative to subclassing for extending functionality.
+
+```java
+public interface DataSource {
+    void writeData(String data);
+    String readData();
+}
+
+public class FileDataSource implements DataSource {
+    private String filename;
+
+    public FileDataSource(String filename) {
+        this.filename = filename;
+    }
+
+    @Override
+    public void writeData(String data) {
+        System.out.println("Writing data to " + filename);
+    }
+
+    @Override
+    public String readData() {
+        return "Reading data from " + filename;
+    }
+}
+
+public class EncryptionDecorator implements DataSource {
+    private DataSource wrappee;
+
+    public EncryptionDecorator(DataSource source) {
+        this.wrappee = source;
+    }
+
+    @Override
+    public void writeData(String data) {
+        wrappee.writeData(encrypt(data));
+    }
+
+    @Override
+    public String readData() {
+        return decrypt(wrappee.readData());
+    }
+
+    private String encrypt(String data) {
+        return "Encrypted[" + data + "]";
+    }
+
+    private String decrypt(String data) {
+        return data.replace("Encrypted[", "").replace("]", "");
+    }
+}
+```
+
+# Behavioral Patterns
+
+**Observer**:
+
+Defines a one-to-many dependency between objects, where a change in the state of one object automatically notifies and updates all its dependents.
+This pattern is particularly useful for implementing event-driven systems.
+
+```java
+public interface Observer {
+    void update(String message);
+}
+
+public class NewsSubscriber implements Observer {
+    private String name;
+
+    public NewsSubscriber(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public void update(String message) {
+        System.out.println(name + " received update: " + message);
+    }
+}
+
+public class NewsPublisher {
+    private List<Observer> observers = new ArrayList<>();
+
+    public void subscribe(Observer observer) {
+        observers.add(observer);
+    }
+
+    public void unsubscribe(Observer observer) {
+        observers.remove(observer);
+    }
+
+    public void notifyObservers(String message) {
+        for (Observer observer : observers) {
+            observer.update(message);
+        }
+    }
+}
+```
+
+**Strategy**:
+
+Encapsulates interchangeable behaviors and algorithms, allowing you to select them at runtime.
+This pattern promotes the Open/Closed Principle by enabling new strategies to be introduced without altering existing code.
+
+```java
+public interface PaymentStrategy {
+    void pay(int amount);
+}
+
+public class CreditCardPayment implements PaymentStrategy {
+    @Override
+    public void pay(int amount) {
+        System.out.println("Paid " + amount + " using credit card.");
+    }
+}
+
+public class PayPalPayment implements PaymentStrategy {
+    @Override
+    public void pay(int amount) {
+        System.out.println("Paid " + amount + " using PayPal.");
+    }
+}
+```
+
+**Template Method**:
+
+Defines the skeleton of an algorithm in a base class and allows subclasses to override specific steps of the algorithm without changing its structure.
+This ensures code reuse while maintaining flexibility for customization.
+
+```java
+public abstract class Game {
+    public final void play() {
+        initialize();
+        startPlay();
+        endPlay();
+    }
+
+    protected abstract void initialize();
+    protected abstract void startPlay();
+    protected abstract void endPlay();
+}
+
+public class Chess extends Game {
+    @Override
+    protected void initialize() {
+        System.out.println("Chess Game Initialized!");
+    }
+
+    @Override
+    protected void startPlay() {
+        System.out.println("Chess Game Started!");
+    }
+
+    @Override
+    protected void endPlay() {
+        System.out.println("Chess Game Finished!");
+    }
+}
+```