Harnessing the Prototype Design Pattern for Smart Caching

Sarvadaman Singh
3 min readNov 26, 2023

--

Image by freepik

The Prototype design pattern is a creational pattern that focuses on efficient object creation by allowing the duplication of existing objects, known as prototypes. Instead of creating new objects through traditional instantiation, the pattern involves copying or cloning an existing instance to generate new objects with identical or customized properties. This approach is particularly useful when creating objects is resource-intensive or complex.

Key elements of the Prototype pattern include:

Prototype Interface or Base Class: Defines a common interface or base class for all concrete prototypes. This interface typically includes a method for cloning the object.

Concrete Prototypes: Classes that implement the prototype interface or extend the base class. They provide the actual implementation of the clone operation.

Client: Initiates the cloning process by requesting a new object from a prototype. The client receives a copy of the prototype and can further customize the cloned object if needed.

Clone Method: The method within the prototype interface or base class responsible for creating a copy of the object. It can be implemented using shallow or deep cloning, depending on the requirements.

The Prototype pattern promotes flexibility and efficiency in scenarios where object creation is resource-intensive, and instances share common structures. By allowing the copying of existing objects, the pattern facilitates the creation of new objects with minimal overhead. This can be especially beneficial in situations such as caching mechanisms, configuration management, and scenarios where the cost of creating new objects is higher than cloning existing ones.

Use Case: Caching Mechanisms

In scenarios where data retrieval or object creation is resource-intensive, a caching mechanism can be implemented to store and reuse instances of objects. The Prototype pattern plays a role in this use case by providing a mechanism to create and manage prototype objects, which can be used as templates for creating cached instances.

Here’s how the Prototype pattern can be applied in a caching scenario:

Prototype Creation:

Create prototype objects that represent the types of objects you want to cache. These prototype objects are fully configured instances that can serve as templates.

public class CachedObject implements Cloneable {
private String data;

// Constructor and methods to set and get data...

@Override
public CachedObject clone() throws CloneNotSupportedException {
return (CachedObject) super.clone();
}
}

Cache Management:

Maintain a cache (e.g., a Map) to store instances of the prototype objects. When an object is requested, check if it exists in the cache. If it does, return a clone of the cached object; otherwise, create a new instance, store it in the cache, and return a clone.

public class ObjectCache {
private Map<String, CachedObject> cache = new HashMap<>();

public CachedObject getObject(String key) {
if (cache.containsKey(key)) {
try {
return cache.get(key).clone(); // Return a clone of the cached object
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
// If the object is not in the cache, create a new one, store it, and return a clone
CachedObject newObject = new CachedObject(/* initialize with default values */);
cache.put(key, newObject);
try {
return newObject.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}

Client Usage:

Clients that need instances of the cached objects can use the ObjectCache to retrieve them. The client gets a clone of the cached object, and modifications to the cloned object do not affect the original cached object.

public class Client {
public static void main(String[] args) {
ObjectCache objectCache = new ObjectCache();

// Client requests an object from the cache
CachedObject cachedObject1 = objectCache.getObject("key1");

// Modify the cloned object without affecting the cached object
cachedObject1.setData("Modified Data");

// Client requests the same object again
CachedObject cachedObject2 = objectCache.getObject("key1");

// The second object is a clone of the cached object, and changes to the first object don't affect it
System.out.println(cachedObject2.getData()); // Output: Original Data
}
}

By using the Prototype pattern in a caching mechanism, you can efficiently reuse and manage instances of objects, reducing the overhead of creating new instances and improving performance in scenarios where object creation is expensive.

--

--

Sarvadaman Singh

Technology enthusiast, Product Manager, Product Architect, Product Designer