Friday, 29 November 2013

Builder Design pattern - Real Time Example [Meal Package]

Master Software Architecture & Clean Code!

Subscribe to Ram N Java for clean code, design pattern implementations, and practical Java tutorials!

SUBSCRIBE NOW

Structuring Complex Orders with the Builder Pattern

In food ordering and retail management systems, configuring combo meal packages involves assembling multiple distinct components: a main course, side dish, beverage, and dessert. Creating these meal combinations using constructors with numerous parameters makes the codebase fragile, error-prone, and difficult to extend.

The Builder Design Pattern solves this challenge by separating the stepwise preparation of a meal package from its final representation. A dedicated director oversees the construction steps, allowing identical construction processes to produce entirely different meal packages cleanly.

Complete Java Code Walkthrough

Here is an end-to-end, clean Java implementation demonstrating how to build customizable meal packages using the Builder pattern:

// 1. Product Class
class MealPackage {
    private String mainItem;
    private String sideItem;
    private String drink;
    private String dessert;

    public void setMainItem(String mainItem) { this.mainItem = mainItem; }
    public void setSideItem(String sideItem) { this.sideItem = sideItem; }
    public void setDrink(String drink) { this.drink = drink; }
    public void setDessert(String dessert) { this.dessert = dessert; }

    @Override
    public String toString() {
        return "MealPackage [Main=" + mainItem + ", Side=" + sideItem + ", Drink=" + drink + ", Dessert=" + dessert + "]";
    }
}

// 2. Builder Interface
interface MealBuilder {
    void buildMainItem();
    void buildSideItem();
    void buildDrink();
    void buildDessert();
    MealPackage getMeal();
}

// 3. Concrete Builder: Veg Meal
class VegMealBuilder implements MealBuilder {
    private MealPackage meal = new MealPackage();

    @Override
    public void buildMainItem() { meal.setMainItem("Veggie Burger"); }

    @Override
    public void buildSideItem() { meal.setSideItem("French Fries"); }

    @Override
    public void buildDrink() { meal.setDrink("Orange Juice"); }

    @Override
    public void buildDessert() { meal.setDessert("Fruit Salad"); }

    @Override
    public MealPackage getMeal() { return this.meal; }
}

// 4. Concrete Builder: Non-Veg Meal
class NonVegMealBuilder implements MealBuilder {
    private MealPackage meal = new MealPackage();

    @Override
    public void buildMainItem() { meal.setMainItem("Crispy Chicken Burger"); }

    @Override
    public void buildSideItem() { meal.setSideItem("Chicken Wings"); }

    @Override
    public void buildDrink() { meal.setDrink("Cold Soda"); }

    @Override
    public void buildDessert() { meal.setDessert("Chocolate Brownie"); }

    @Override
    public MealPackage getMeal() { return this.meal; }
}

// 5. Director Class
class MealDirector {
    private MealBuilder mealBuilder;

    public MealDirector(MealBuilder mealBuilder) {
        this.mealBuilder = mealBuilder;
    }

    public void constructMeal() {
        mealBuilder.buildMainItem();
        mealBuilder.buildSideItem();
        mealBuilder.buildDrink();
        mealBuilder.buildDessert();
    }

    public MealPackage getMeal() {
        return mealBuilder.getMeal();
    }
}

// 6. Client Application
public class MealBuilderDemo {
    public static void main(String[] args) {
        // Build Veg Meal
        MealBuilder vegBuilder = new VegMealBuilder();
        MealDirector vegDirector = new MealDirector(vegBuilder);
        vegDirector.constructMeal();
        MealPackage vegMeal = vegDirector.getMeal();
        System.out.println("Assembled: " + vegMeal);

        // Build Non-Veg Meal
        MealBuilder nonVegBuilder = new NonVegMealBuilder();
        MealDirector nonVegDirector = new MealDirector(nonVegBuilder);
        nonVegDirector.constructMeal();
        MealPackage nonVegMeal = nonVegDirector.getMeal();
        System.out.println("Assembled: " + nonVegMeal);
    }
}

Key Architectural Benefits

  • Step-by-Step Construction Control: Guarantees that all required parts of the meal package are built in a controlled, ordered workflow.
  • Decoupled Presentation: The client code interacts solely with the director and receives fully formed objects, avoiding partially initialized instances.
  • Scalable Variations: New meal combos (such as a KidsMealBuilder) can be integrated effortlessly without modifying existing classes.

Watch More Related Design Pattern Tutorials


Click here to watch in Youtube : https://www.youtube.com/watch?v=Okw_XkQaXtE

Click the below Image to Enlarge

Builder Design pattern - Real Time Example

















See also:

  • Builder Design Pattern - Introduction
  • Builder Design pattern - Real Time Example [Animal Toys]
  • Builder Design pattern - Real Time Example [Beverage]
  • Builder Design Pattern - Class Diagram
  • Builder Design Pattern - Sequence Diagram
  • Builder Design Pattern - Implementation [Beverage]
  • Builder Design Pattern - Implementation [Animal Toy]
  • Builder Design Pattern - KeyPoints
  • All Design Patterns Links
  • Builder Design pattern - Introduction

    Master Software Architecture & Clean Code!

    Subscribe to Ram N Java for clean code, design pattern implementations, and practical Java tutorials!

    SUBSCRIBE NOW

    What is the Builder Design Pattern?

    The Builder Design Pattern is a foundational creational design pattern identified by the Gang of Four (GoF). It aims to separate the construction of a complex object from its representation, allowing the exact same construction sequence to create diverse object representations.

    In standard object-oriented programming, instantiating an object with numerous optional or mandatory attributes often forces developers to rely on constructors with endless parameter lists (known as the telescoping constructor anti-pattern) or messy setter chains that risk inconsistent states. The Builder pattern eliminates these bottlenecks cleanly.

    Core Components of the Builder Pattern

    • Product: The complex object being constructed, typically containing multiple configurable parts.
    • Builder (Interface): Specifies an abstract interface for creating parts of a Product object step by step.
    • Concrete Builder: Implements the Builder interface, keeps track of the representation being assembled, and provides an interface for retrieving the final product.
    • Director: Orchestrates the building steps in a specific sequence using the Builder interface.

    When Should You Use It?

    • When the algorithm for creating a complex object should be independent of the parts that make up the object and how they are assembled.
    • When the construction process must allow different representations for the object that is constructed.
    • When you want to prevent object construction in an incomplete or mutable invalid state.

    Watch More Related Design Pattern Tutorials


    Click here to watch in Youtube : https://www.youtube.com/watch?v=hFi1ZDrFeLo

    Click the below Image to Enlarge

    Builder Design pattern - Introduction

























    See also:

  • Builder Design pattern - Real Time Example [Meal Package]
  • Builder Design pattern - Real Time Example [Animal Toys]
  • Builder Design pattern - Real Time Example [Beverage]
  • Builder Design Pattern - Class Diagram
  • Builder Design Pattern - Sequence Diagram
  • Builder Design Pattern - Implementation [Beverage]
  • Builder Design Pattern - Implementation [Animal Toy]
  • Builder Design Pattern - KeyPoints
  • All Design Patterns Links
  • Builder Design pattern - Sequence Diagram

    Master Software Architecture & Clean Code!

    Subscribe to Ram N Java for clean code, design pattern implementations, and practical Java tutorials!

    SUBSCRIBE NOW

    Understanding the Builder Pattern Sequence Flow

    The Builder Design Pattern is a creational pattern designed to separate the step-by-step construction of a complex object from its actual representation. While a class diagram illustrates static structural relationships, a UML Sequence Diagram highlights the dynamic runtime interaction between collaborating objects over time.

    By tracing the message exchange among the Client, Director, Builder, and Product, developers can clearly see the exact invocation timeline and lifecycle required to safely produce a fully initialized instance.

    Key Sequence Steps Explained

    • Step 1 (Instantiation): The Client instantiates a concrete builder object (e.g., ConcreteBuilder).
    • Step 2 (Configuration): The Client creates the Director, passing the ConcreteBuilder instance via constructor injection or a setter method.
    • Step 3 (Orchestration): The Client calls director.construct().
    • Step 4 (Stepwise Build Messages): The Director issues ordered messages to the builder interface (such as builder.buildPartA(), builder.buildPartB()). The builder continuously updates the internal Product state.
    • Step 5 (Retrieval): The Client invokes builder.getResult() (or retrieves it through the director) to receive the completed, immutable product.

    Runtime Execution in Java Code

    Here is clean Java code illustrating the precise method invocations reflected in the Builder pattern sequence diagram:

    // Product
    class Product {
        private String partA;
        private String partB;
    
        public void setPartA(String partA) { this.partA = partA; }
        public void setPartB(String partB) { this.partB = partB; }
    
        @Override
        public String toString() {
            return "Product [partA=" + partA + ", partB=" + partB + "]";
        }
    }
    
    // Builder Interface
    interface Builder {
        void buildPartA();
        void buildPartB();
        Product getResult();
    }
    
    // Concrete Builder
    class ConcreteBuilder implements Builder {
        private Product product = new Product();
    
        @Override
        public void buildPartA() {
            product.setPartA("Initialized Part A");
        }
    
        @Override
        public void buildPartB() {
            product.setPartB("Initialized Part B");
        }
    
        @Override
        public Product getResult() {
            return this.product;
        }
    }
    
    // Director
    class Director {
        private Builder builder;
    
        public Director(Builder builder) {
            this.builder = builder;
        }
    
        public void construct() {
            // Sequenced message invocations to Builder
            builder.buildPartA();
            builder.buildPartB();
        }
    }
    
    // Client
    public class SequenceDiagramDemo {
        public static void main(String[] args) {
            // Sequence: 1. Instantiate Builder
            Builder builder = new ConcreteBuilder();
    
            // Sequence: 2. Instantiate Director with Builder
            Director director = new Director(builder);
    
            // Sequence: 3. Trigger construction flow
            director.construct();
    
            // Sequence: 4. Retrieve final assembled product
            Product finalProduct = builder.getResult();
            System.out.println("Result: " + finalProduct);
        }
    }

    Watch More Related Design Pattern Tutorials


    Click here to watch in Youtube : https://www.youtube.com/watch?v=jWvEmjSTOgI

    Click the below Image to Enlarge
    Builder Design pattern - Sequence Diagram

















    See also:

  • Builder Design Pattern - Introduction
  • Builder Design pattern - Real Time Example [Meal Package]
  • Builder Design pattern - Real Time Example [Animal Toys]
  • Builder Design pattern - Real Time Example [Beverage]
  • Builder Design Pattern - Class Diagram
  • Builder Design Pattern - Implementation [Beverage]
  • Builder Design Pattern - Implementation [Animal Toy]
  • Builder Design Pattern - KeyPoints
  • All Design Patterns Links
  • Builder Design pattern - Class Diagram

    Master Software Architecture & Clean Code!

    Subscribe to Ram N Java for clean code, design pattern implementations, and practical Java tutorials!

    SUBSCRIBE NOW

    Understanding the Builder Pattern Class Diagram

    The Builder Design Pattern is a GoF creational pattern that decouples the construction of a complex object from its internal representation. While understanding the conceptual theory is helpful, mastering the UML Class Diagram is essential to designing modular, extensible object architectures.

    A standard Builder class diagram defines four core participants and maps out their structural dependencies, inheritance hierarchies, and aggregation relationships.

    Key Participants in the Class Diagram

    • Product: The complex object being assembled, containing multiple fields and nested components.
    • Builder (Interface / Abstract Class): Defines the contract of discrete assembly operations (e.g., buildPartA(), buildPartB()) and the product retrieval method.
    • ConcreteBuilder: Implements the Builder interface, tracks intermediate states, and instantiates the concrete Product.
    • Director: Holds an aggregation reference to a Builder instance and coordinates the step-by-step assembly process via a construction method (e.g., construct()).
    • Client: Configures the Director with a specific ConcreteBuilder and retrieves the final product.

    Clean Java Code Mapping to the Diagram

    Here is an end-to-end Java implementation demonstrating how these UML relationships translate directly into production-ready code:

    // 1. Product
    class Computer {
        private String cpu;
        private String ram;
        private String storage;
    
        public void setCpu(String cpu) { this.cpu = cpu; }
        public void setRam(String ram) { this.ram = ram; }
        public void setStorage(String storage) { this.storage = storage; }
    
        @Override
        public String toString() {
            return "Computer [CPU=" + cpu + ", RAM=" + ram + ", Storage=" + storage + "]";
        }
    }
    
    // 2. Builder Interface
    interface ComputerBuilder {
        void buildCpu();
        void buildRam();
        void buildStorage();
        Computer getComputer();
    }
    
    // 3. ConcreteBuilder
    class GamingComputerBuilder implements ComputerBuilder {
        private Computer computer = new Computer();
    
        @Override
        public void buildCpu() { computer.setCpu("High-Performance Octa-Core CPU"); }
    
        @Override
        public void buildRam() { computer.setRam("32GB DDR5 RAM"); }
    
        @Override
        public void buildStorage() { computer.setStorage("2TB NVMe SSD"); }
    
        @Override
        public Computer getComputer() { return this.computer; }
    }
    
    // 4. Director (Aggregates ComputerBuilder)
    class ComputerAssembler {
        private ComputerBuilder builder;
    
        public ComputerAssembler(ComputerBuilder builder) {
            this.builder = builder;
        }
    
        public void construct() {
            builder.buildCpu();
            builder.buildRam();
            builder.buildStorage();
        }
    
        public Computer getComputer() {
            return builder.getComputer();
        }
    }
    
    // 5. Client
    public class ClassDiagramDemo {
        public static void main(String[] args) {
            ComputerBuilder builder = new GamingComputerBuilder();
            ComputerAssembler director = new ComputerAssembler(builder);
    
            director.construct();
            Computer gamingPc = director.getComputer();
    
            System.out.println("Configured: " + gamingPc);
        }
    }

    Watch More Related Design Pattern Tutorials


    Click here to watch in Youtube : https://www.youtube.com/watch?v=EHS4h2noiMQ

    Click the below Image to Enlarge
    Builder Design pattern - Class Diagram

















    See also:

  • Builder Design Pattern - Introduction
  • Builder Design pattern - Real Time Example [Meal Package]
  • Builder Design pattern - Real Time Example [Animal Toys]
  • Builder Design pattern - Real Time Example [Beverage]
  • Builder Design Pattern - Sequence Diagram
  • Builder Design Pattern - Implementation [Beverage]
  • Builder Design Pattern - Implementation [Animal Toy]
  • Builder Design Pattern - KeyPoints
  • All Design Patterns Links
  • Builder Design pattern - keypoints

    Master Software Architecture & Clean Code!

    Subscribe to Ram N Java for clean code, design pattern implementations, and practical Java tutorials!

    SUBSCRIBE NOW

    Core Concepts of the Builder Design Pattern

    The Builder Design Pattern is a GoF creational pattern engineered to separate the step-by-step construction of a complex object from its representation. In large enterprise systems, creating complex objects with numerous optional parameters often leads to anti-patterns such as telescoping constructors or incomplete object initialization via mutable setters.

    By delegating object construction to dedicated builder components, this pattern provides fine-grained control over the creation process while enforcing object immutability and consistent state.

    Essential Architectural Takeaways

    • Solves Telescoping Constructors: Eliminates excessive overloaded constructor chains, making object instantiation expressive and readable.
    • Stepwise Construction Control: Unlike standard factories that build an object in a single pass, the Builder pattern constructs the product step by step under the client’s or director’s control.
    • Separation of Concerns: Isolates complex construction logic from the domain representation, aligning cleanly with the Single Responsibility Principle.
    • Supports Immutability: Fields can be marked final, ensuring objects cannot be altered once construction finishes.

    When to Choose the Builder Pattern

    • When an object requires four or more constructor parameters, especially when many are optional.
    • When you want to guarantee immutable objects without exposing public setter methods.
    • When the creation algorithm must be independent of the parts that assemble the final product.

    Watch More Related Design Pattern Tutorials


    Click here to watch in Youtube : https://www.youtube.com/watch?v=glz7DVUZ9y4

    Click the below Image to Enlarge

















    See also:

  • Builder Design Pattern - Introduction
  • Builder Design pattern - Real Time Example [Meal Package]
  • Builder Design pattern - Real Time Example [Animal Toys]
  • Builder Design pattern - Real Time Example [Beverage]
  • Builder Design Pattern - Class Diagram
  • Builder Design Pattern - Sequence Diagram
  • Builder Design Pattern - Implementation [Beverage]
  • Builder Design Pattern - Implementation [Animal Toy]
  • All Design Patterns Links
  • Thursday, 28 November 2013

    Flyweight Design pattern - Implementation

    Master Software Design Patterns!

    Subscribe to Ram N Java for clean code, architecture patterns, and practical Java tutorials!

    SUBSCRIBE NOW

    Why Use the Flyweight Design Pattern?

    Imagine your application needs to render hundreds of thousands of graphical elements (like circles with various colors). If you instantiate a brand-new object using the new operator for each circle, your application will quickly consume massive amounts of heap memory and slow down.

    The Flyweight Pattern is a structural design pattern that solves this problem by sharing common object instances instead of creating duplicate objects. By reusing existing instances, memory consumption drops drastically and overall application performance improves.

    Understanding Intrinsic vs Extrinsic State

    To successfully implement the Flyweight pattern, divide the object's data into two distinct states:

    • Intrinsic State: Data that is constant, shared across instances, and stored inside the object memory (e.g., the underlying shape definition).
    • Extrinsic State: Data that varies and depends on external context (e.g., color, coordinates, or runtime properties). This data is passed into methods or modified on the fly rather than storing separate objects.

    Core Implementation in Java

    The Flyweight factory maintains a lookup map (cache) of reusable objects. When a shape is requested, it checks the map first before creating a new instance.

    import java.util.HashMap;
    import java.util.Map;
    
    // 1. Common Interface
    interface Shape {
        void draw();
    }
    
    // 2. Concrete Flyweight Class
    class Circle implements Shape {
        private String color;
        private int x, y, radius;
    
        public void setColor(String color) {
            this.color = color;
        }
    
        public void setX(int x) { this.x = x; }
        public void setY(int y) { this.y = y; }
        public void setRadius(int radius) { this.radius = radius; }
    
        @Override
        public void draw() {
            System.out.println("Drawing Circle [Color: " + color + 
                               ", X: " + x + ", Y: " + y + 
                               ", Radius: " + radius + 
                               ", HashCode: " + System.identityHashCode(this) + "]");
        }
    }
    
    // 3. Flyweight Factory
    class ShapeFactory {
        private static final Map<String, Shape> shapeMap = new HashMap<>();
    
        public static Shape getShape(String shapeType) {
            Shape shape = shapeMap.get(shapeType);
    
            if (shape == null) {
                if ("CIRCLE".equalsIgnoreCase(shapeType)) {
                    shape = new Circle();
                    shapeMap.put(shapeType, shape);
                    System.out.println("Created new Circle object in memory.");
                }
            }
            return shape;
        }
    }
    
    // 4. Demo / Client
    public class FlyweightPatternDemo {
        private static final String[] COLORS = { "Red", "Green", "Blue", "Orange", "Black" };
    
        public static void main(String[] args) {
            for (String color : COLORS) {
                for (int i = 0; i < 2; i++) {
                    Circle circle = (Circle) ShapeFactory.getShape("CIRCLE");
                    circle.setColor(color);
                    circle.setX(i * 10);
                    circle.setY(i * 20);
                    circle.setRadius(15);
                    circle.draw();
                }
            }
        }
    }

    Watch More Related Design Pattern Tutorials


    Click here to watch in Youtube : https://www.youtube.com/watch?v=SKZQx1DdA9U

    Click the below Image to Enlarge
    Flyweight Design pattern - Implementation

    Flyweight Design pattern - Class Diagram



    Shape.java

    public interface Shape
    {
    void draw();
    }

    Circle.java

    public class Circle implements Shape
    {
    private String    color;
    private final int x      = 10;
    private final int y      = 20;
    private final int radius = 30;

    public Circle()
    {
    }

    public Circle( String color )
    {
    this.color = color;
    }

    public String getColor()
    {
    return color;
    }

    public void setColor( String color )
    {
    this.color = color;
    }

    @Override
    public void draw()
    {
    System.out.println(this+" : Circle: Draw() [Color : " + color + ", x : " + x + ", y :" + y + ", radius :"
                   + radius);
    }
    }

    ShapeFactory.java

    import java.util.HashMap;

    public class ShapeFactory
    {
    private static final HashMap<String, Shape> shapeMap = new HashMap<String, Shape>();

    public static Shape getShape( String shapeType )
    {
    Shape shape=null;
    if( shapeType.equalsIgnoreCase("circle") )
    {
    shape = (Circle) shapeMap.get("circle");

    if( shape == null )
    {
    shape = new Circle();
    shapeMap.put("circle", shape);
    System.out.println("Creating circle object with out any color in shapefactory : " + shape
                   + "\n");
    }
    }
    return shape;
    }
    }

    FlyweightPatternDemo.java

    public class FlyweightPatternDemo
    {
    private static final String colors[] = { "Red", "Green", "Blue", "Orange", "Black" };

    public static void main( String[] args )
    {

    System.out.println("\n################ Red color Circles ####################");
    for( int i = 0; i < 10; ++i )
    {
    Circle circle = (Circle) ShapeFactory.getShape("circle");
    circle.setColor(colors[0]);
    circle.draw();
    }
    System.out.println("\n############### Green color Circles ####################");
    for( int i = 0; i < 10; ++i )
    {
    Circle circle = (Circle) ShapeFactory.getShape("circle");
    circle.setColor(colors[1]);
    circle.draw();
    }
    System.out.println("\n################ Blue color Circles ####################");
    for( int i = 0; i < 10; ++i )
    {
    Circle circle = (Circle) ShapeFactory.getShape("circle");
    circle.setColor(colors[2]);
    circle.draw();
    }
    System.out.println("\n################ Orange color Circles ####################");
    for( int i = 0; i < 10; ++i )
    {
    Circle circle = (Circle) ShapeFactory.getShape("circle");
    circle.setColor(colors[3]);
    circle.draw();
    }
    System.out.println("\n################ Black color Circles ####################");
    for( int i = 0; i < 10; ++i )
    {
    Circle circle = (Circle) ShapeFactory.getShape("circle");
    circle.setColor(colors[4]);
    circle.draw();
    }
    }
    }

    Output

    ################ Red color Circles ####################
    Creating circle object with out any color in shapefactory : Circle@10385c1

    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Red, x : 10, y :20, radius :30

    ############### Green color Circles ####################
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Green, x : 10, y :20, radius :30

    ################ Blue color Circles ####################
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Blue, x : 10, y :20, radius :30

    ################ Orange color Circles ####################
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Orange, x : 10, y :20, radius :30

    ################ Black color Circles ####################
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30
    Circle@10385c1 : Circle: Draw() [Color : Black, x : 10, y :20, radius :30

    See also:

  • Flyweight Design pattern - Introduction
  • Flyweight Design pattern - Real Time Example
  • Flyweight Design pattern - Class Diagram
  • Flyweight Design pattern - Sequence Diagram
  • Flyweight Design pattern - Key Points
  • All Design Patterns Links
  • Sunday, 24 November 2013

    Memento Design pattern - Implementation


    Click here to watch in Youtube : https://www.youtube.com/watch?v=ZjouanHQmdk

    Click the below Image to Enlarge
    Memento Design pattern - Implementation
    Memento Design pattern - Class Diagram








































    LedTV.java

    public class LedTV
    {
    private String  size;
    private String  price;
    private boolean usbSupport;

    public LedTV( String size, String price, boolean usbSupport )
    {
    super();
    this.size = size;
    this.price = price;
    this.usbSupport = usbSupport;
    }

    public String getSize()
    {
    return size;
    }

    public void setSize( String size )
    {
    this.size = size;
    }

    public String getPrice()
    {
    return price;
    }

    public void setPrice( String price )
    {
    this.price = price;
    }

    public boolean isUsbSupport()
    {
    return usbSupport;
    }

    public void setUsbSupport( boolean usbSupport )
    {
    this.usbSupport = usbSupport;
    }

    @Override
    public String toString()
    {
    return "LedTV [size=" + size + ", price=" + price + ", usbSupport=" + usbSupport + "]";
    }

    }


    Memento.java

    public class Memento
    {
    private LedTV ledTV;

    public Memento( LedTV ledTV )
    {
    super();
    this.ledTV = ledTV;
    }

    public LedTV getLedTV()
    {
    return ledTV;
    }

    public void setLedTV( LedTV ledTV )
    {
    this.ledTV = ledTV;
    }

    @Override
            public String toString()
            {
           return "Memento [ledTV=" + ledTV + "]";
            }

    }

    Caretaker.java

    import java.util.ArrayList;
    import java.util.List;
    /*
     * Store Room
     */
    public class Caretaker
    {
    private List<Memento> ledTvList = new ArrayList<Memento>();

    public void addMemento( Memento m )
    {
    ledTvList.add(m);
    System.out.println("LED TV's snapshots Maintained by CareTaker :" + ledTvList);
    }

    public Memento getMemento( int index )
    {
    return ledTvList.get(index);
    }
    }


    Originator.java

    /*
     * Hall
     */
    public class Originator
    {
    LedTV ledTV;

    public LedTV getLedTV()
    {
    return ledTV;
    }

    public void setLedTV( LedTV ledTV )
    {
    this.ledTV = ledTV;
    }

    public Memento createMemento()
    {
    return new Memento(ledTV);
    }

    public void setMemento( Memento memento )
    {
    ledTV = memento.getLedTV();
    }

    @Override
            public String toString()
            {
           return "Originator [ledTV=" + ledTV + "]";
            }

    }

    MementoClient.java

    public class MementoClient
    {

    public static void main( String[] args )
    {
    Originator originator = new Originator();
    originator.setLedTV(new LedTV("42 inch", "60000Rs", false));

    Caretaker caretaker = new Caretaker();
    caretaker.addMemento(originator.createMemento());

    originator.setLedTV(new LedTV("46 inch", "80000Rs", true));
    caretaker.addMemento(originator.createMemento());

    originator.setLedTV(new LedTV("50 inch", "100000Rs", true));
    System.out.println("\nOrignator current state : " + originator);

    System.out.println("\nOriginator restoring to 42 inch LED TV...");

    originator.setMemento(caretaker.getMemento(0));

    System.out.println("\nOrignator current state : " + originator);

    }

    }

    Output

    LED TV's snapshots Maintained by CareTaker :[Memento [ledTV=LedTV [size=42 inch, price=60000Rs, usbSupport=false]]]
    LED TV's snapshots Maintained by CareTaker :[Memento [ledTV=LedTV [size=42 inch, price=60000Rs, usbSupport=false]], Memento [ledTV=LedTV [size=46 inch, price=80000Rs, usbSupport=true]]]

    Orignator current state : Originator [ledTV=LedTV [size=50 inch, price=100000Rs, usbSupport=true]]

    Originator restoring to 42 inch LED TV...

    Orignator current state : Originator [ledTV=LedTV [size=42 inch, price=60000Rs, usbSupport=false]]

    See also:

  • Momento Design pattern - Introduction
  • Momento Design pattern - Real time Example
  • Memento Design pattern - Class Diagram
  • Memento Design pattern - Sequence Diagram
  • Momento Design pattern - KeyPoints
  • All Design Patterns Links
  • Proxy Design pattern - Implementation[Virtual Proxy]

    🚀 Master Core Java & Structural Design Patterns!

    Enjoying easy-to-understand design pattern guides? Subscribe to Ram N Java for clean code walkthroughs!

    🔔 Subscribe to Ram N Java

    Understanding the Virtual Proxy Design Pattern

    The Virtual Proxy Pattern is a specialized implementation of the Proxy structural design pattern. It acts as a placeholder for resource-intensive or heavyweight objects, delaying their creation and initialization until they are genuinely needed (a concept known as lazy loading or lazy initialization).

    Why Use a Virtual Proxy?

    Creating complex objects upfront—such as high-resolution images, large data models, or external service connections—can severely degrade performance and consume heavy memory. A Virtual Proxy solves this problem by:

    • Providing the exact same interface as the real subject.
    • Handling lightweight operations without loading the real object.
    • Instantiating the expensive object only when an essential operation is requested.

    Key Components of Virtual Proxy

    1. Subject Interface: Declares common operations for both the real object and the proxy.
    2. Real Subject: The actual heavyweight object that performs the core, memory-intensive work.
    3. Virtual Proxy: Holds a reference to the real subject, controlling its instantiation and access transparently.

    Explore More Proxy Pattern Tutorials

    Expand your understanding of proxy architectures with these related tutorials from our channel:


    Click here to watch in Youtube : https://www.youtube.com/watch?v=ooPPd_LIkzQ

    Click the below Image to Enlarge
    Virtual Proxy
    Virtual Proxy - Class Diagram













































    Image.java


    interface Image
    {
    public void displayImage();
    }

    RealImage.java


    //on System A 
    class RealImage implements Image
    {

    private String filename = null;

    /**
    * Constructor
    * 
    * @param FILENAME
    */
    public RealImage( final String FILENAME )
    {
    filename = FILENAME; 
    loadImageFromDisk();
    }

    /**
    * Loads the image from the disk
    */
    private void loadImageFromDisk()
    {
    System.out.println("   Loading   " + filename);
    }

    /**
    * Displays the image
    */
    public void displayImage()
    {
    System.out.println("   Displaying " + filename+"\n");
    }

    }

    ProxyImage.java


    //on System B 
    class ProxyImage implements Image
    {

    private RealImage image    = null;
    private String    filename = null;

    /**
    * Constructor
    * 
    * @param FILENAME
    */
    public ProxyImage( final String FILENAME )
    {
    filename = FILENAME;
    }

    /**
    * Displays the image
    */
    public void displayImage()
    {
    if( image == null )
    {
    image = new RealImage(filename);
    }
    image.displayImage();
    }

    }


    Client.java


    class Client
    {

    /**
    * Test method
    */
    public static void main( String[] args )
    {
    final Image IMAGE1 = new ProxyImage("HiResolution_100MB_Dog Photo");
    final Image IMAGE2 = new ProxyImage("HiResolution_100MB_Lion photo");

    System.out.println("IMAGE1["+IMAGE1+"] calling displayImage first time :");
    IMAGE1.displayImage(); // loading necessary
    System.out.println("IMAGE1["+IMAGE1+"] calling displayImage second time :");
    IMAGE1.displayImage(); // loading unnecessary
    System.out.println("IMAGE1["+IMAGE1+"] calling displayImage third time :");
    IMAGE1.displayImage(); // loading unnecessary
    System.out.println("###############################################################\n");

    System.out.println("IMAGE2["+IMAGE2+"] calling displayImage first time :");
    IMAGE2.displayImage(); // loading necessary
    System.out.println("IMAGE2["+IMAGE2+"] calling displayImage second time :");
    IMAGE2.displayImage(); // loading unnecessary

    }

    }

    Output


    IMAGE1[ProxyImage@1ad086a] calling displayImage first time :
       Loading   HiResolution_100MB_Dog Photo
       Displaying HiResolution_100MB_Dog Photo

    IMAGE1[ProxyImage@1ad086a] calling displayImage second time :
       Displaying HiResolution_100MB_Dog Photo

    IMAGE1[ProxyImage@1ad086a] calling displayImage third time :
       Displaying HiResolution_100MB_Dog Photo

    ###############################################################

    IMAGE2[ProxyImage@42719c] calling displayImage first time :
       Loading   HiResolution_100MB_Lion photo
       Displaying HiResolution_100MB_Lion photo

    IMAGE2[ProxyImage@42719c] calling displayImage second time :
       Displaying HiResolution_100MB_Lion photo


    See also:

  • Proxy Design Pattern - Introduction
  • Proxy Design pattern - Real Time Example[ATM]
  • Proxy Design pattern - Real Time Example [Proxy Server]
  • Proxy Design pattern - Class Diagram
  • Proxy Design pattern - Sequence Diagram
  • Proxy Design pattern - Implementation [Protection Proxy]
  • Proxy Design pattern - Implementation [Remote Proxy]
  • Proxy Design Pattern - Key Points
  • All Design Patterns Links
  • Tutorials