Prototype design pattern in Java with realtime example

Richard 29 Published: 09/19/2024

Prototype design pattern in Java with realtime example

Here's a comprehensive guide on the Design Pattern - Prototype, along with a real-time example in Java:

What is the Prototype Pattern?

The prototype pattern is a creational pattern that allows you to create objects without specifying their classes explicitly. Instead of creating an object by calling its constructor, the prototype pattern involves cloning an existing object and then modifying it as needed.

This pattern helps in reducing the cost and effort required to create new objects. In many cases, the process of creating a new object can be expensive or complicated, especially if that object has complex initialization logic or relies on external resources. By using prototypes, you can avoid these costs and complexities.

When to Use Prototype Pattern?

The prototype pattern is useful when:

You need to create multiple objects with similar characteristics but slightly different properties. The creation of an object involves complex initialization logic or relies on external resources. You want to improve the performance of your system by reducing the number of objects that need to be created.

Java Example:

Let's consider a scenario where we have a Shape class, and we want to create different types of shapes (e.g., Circle, Rectangle, etc.). We can use the prototype pattern to achieve this.

Here's an example implementation:

// Prototype interface

public interface Shape {

void draw();

}

// Concrete shape classes

class Circle implements Shape {

@Override

public void draw() {

System.out.println("Drawing a circle...");

}

}

class Rectangle implements Shape {

@Override

public void draw() {

System.out.println("Drawing a rectangle...");

}

}

// Prototype factory class

public class ShapeFactory {

private Shape prototype;

public ShapeFactory(Shape prototype) {

this.prototype = prototype;

}

public Shape createClone(String type) {

if (type.equals("Circle")) {

return clone(new Circle());

} else if (type.equals("Rectangle")) {

return clone(new Rectangle());

}

return null; // or throw an exception

}

private Shape clone(Shape shape) {

try {

return (Shape) shape.getClass().getConstructor().newInstance();

} catch (Exception e) {

// handle the exception

}

return null; // or return a default shape

}

}

// Client code

public class Main {

public static void main(String[] args) {

ShapeFactory factory = new ShapeFactory(new Circle());

Shape circle = factory.createClone("Circle");

circle.draw(); // Output: Drawing a circle...

factory = new ShapeFactory(new Rectangle());

Shape rectangle = factory.createClone("Rectangle");

rectangle.draw(); // Output: Drawing a rectangle...

}

}

In this example, we have two concrete shape classes (Circle and Rectangle) that implement the Shape interface. We also have a ShapeFactory class that serves as a prototype factory. It takes a prototype shape (in this case, either a Circle or a Rectangle) as a constructor argument.

The createClone() method in the ShapeFactory class creates a new object based on the provided prototype and type. It uses the clone() method to create a copy of the prototype.

In the client code (Main), we create two different shape factories, each with a different prototype. We then use these factories to create new shapes by calling the createClone() method.

Benefits:

The prototype pattern offers several benefits:

Improved performance: By reusing existing objects instead of creating new ones, you can reduce the computational overhead and memory usage. Faster development: You don't need to write custom constructors or initialization logic for each new object type. Simplified code: The prototype pattern helps keep your code organized by encapsulating object creation and modification within a single factory class.

In summary, the prototype pattern is a valuable creational design pattern that allows you to create objects without specifying their classes explicitly. By using prototypes, you can improve performance, simplify code, and speed up development.

Prototype scope in Java

I'll make sure to respond in English this time. Here's an explanation of prototype scope in Java:

In object-oriented programming (OOP), a scope refers to the region of code where a variable or method is accessible. In Java, there are several types of scopes:

Method Scope: A variable declared within a method is only accessible within that method and its inner classes. Class Scope (or Static Scope): Variables declared inside the class but outside any method are also known as static variables. They can be accessed from anywhere in the class, including methods and static initializer blocks.

Now, let's talk about prototype scope. A prototype is an instance of a class that serves as a template for creating new objects. When you create a new object using new, Java creates a copy of the prototype and sets it to null after construction. The scope of a variable inside a prototype depends on where the variable is declared:

Member Variables (or Fields:* Member variables are defined within the class body, outside any method. They have Class Scope, meaning they can be accessed from anywhere in the class.

If you declare a member variable as static, it has Global Scope and can be accessed from any part of your program. Non-static member variables (default) have Instance Scope, meaning each instance of the class has its own copy of the variable.

Local Variables: Variables declared within a method or constructor have Method Scope, which means they are only accessible within that specific method or constructor.

Here's an example to illustrate the scope differences:

public class Car {

private static int speed = 0; // Class Scope (static)

private double distance = 0.0; // Instance Scope

public void accelerate(int miles) {

// Member Variable with Method Scope (local variable)

int acceleration = miles;

// Accessing a Class Scope (static) variable

System.out.println("Current speed: " + speed);

// Accessing an Instance Scope member variable

distance += 10.0;

}

public static void main(String[] args) {

Car myCar = new Car();

myCar.accelerate(50);

}

}

In this example:

speed is a class-level variable (Class Scope) and can be accessed from anywhere in the class, including the accelerate() method. distance is an instance-level variable (Instance Scope) and each instance of the Car class has its own copy of this variable. The local variable acceleration within the accelerate() method has Method Scope and is only accessible within that specific method.

I hope this explanation helps clarify the concept of prototype scope in Java!