Friday, 21 February 2020

Proxy Design Pattern



Proxy Design Pattern — Simple Explanation for Students


1. What is the Proxy Design Pattern?

The Proxy Design Pattern provides a placeholder or representative object that controls access to a real object.

Instead of a client talking directly to a real object, it talks to a Proxy, and the Proxy decides:

  • Whether to forward the request

  • When to create the real object

  • How to control access

  • Whether to cache results

  • Whether to protect the real object

In simple words:

👉 Proxy = Middleman between Client and Real Object


2. Intent of the Proxy Pattern

The main purposes of Proxy are:

  1. Control access to the real object

  2. Delay expensive object creation (Lazy Loading)

  3. Provide security or authentication (Protective Proxy)

  4. Reduce memory usage

  5. Add extra logic without changing real object


3. General Structure of Proxy Pattern

Client → Proxy → Real Object

The client talks to Proxy.
Proxy talks to Real Object.

The client does NOT directly interact with the Real Object.


================================

Example 1: Project Booker (Business Use Case)

================================

Scenario: Big Organization with Two Consultancies

  • Company gives project to Consultancy A

  • Consultancy A gives work to Consultancy B

  • Application Owner interacts only with Consultancy A

  • Consultancy A internally interacts with Consultancy B

Here, Consultancy A behaves like a Proxy.


Step 1: Create Interface

public interface ProjectBooker {
    void doWork();
    void amount(int amount);
}

Step 2: Real Object (RealProjectBooker)

class RealProjectBooker implements ProjectBooker {

    int amount = 0;

    @Override
    public void doWork() {
        System.out.println("Project Finished");
    }

    @Override
    public void amount(int amount) {
        this.amount = amount;
    }
}

This is the real worker who actually does the work.


Step 3: Proxy Class

class ProxyProjectBooker implements ProjectBooker {

    RealProjectBooker realProjectBooker;
    int amount;

    @Override
    public void doWork() {
        realProjectBooker = new RealProjectBooker();
        realProjectBooker.doWork();
    }

    @Override
    public void amount(int amount) {
        this.amount = amount;
        int tempAmount = amount / 2;
        realProjectBooker.amount(tempAmount);
    }
}

👉 What Proxy does here:

  • Receives full amount from client

  • Passes only half to real object

  • Keeps remaining half as profit


Step 4: Client Code

public class Test {
    public static void main(String[] args) {

        // Application owner creates Proxy
        ProjectBooker abcProj = new ProxyProjectBooker();

        // Application owner asks to do work
        abcProj.doWork();

        // Application owner gives 10,00,000
        abcProj.amount(1000000);
    }
}

Business Interpretation

PartyAmount Received
Application OwnerPays ₹10,00,000
Proxy (Consultancy A)Keeps ₹5,00,000
RealProjectBooker (Consultancy B)Gets ₹5,00,000

👉 Conclusion: Proxy controls the real object.


================================

Example 2: Image Viewer — Lazy Loading Proxy

================================

This is a classic Lazy Loading Proxy Example.


Step 1: Image Interface

public interface Image {
    void showImage();
}

Step 2: Real High-Resolution Image

class HighResolutionImage implements Image {

    public HighResolutionImage(String imageFilePath) {
        loadImage(imageFilePath);
    }

    private void loadImage(String imageFilePath) {
        System.out.println("Loading heavy image from disk...");
    }

    @Override
    public void showImage() {
        System.out.println("Displaying High Resolution Image");
    }
}

This is heavy and expensive object.


Step 3: Image Proxy (Lazy Loading)

class ImageProxy implements Image {

    private String imageFilePath;
    private Image proxiedImage;

    public ImageProxy(String imageFilePath) {
        this.imageFilePath = imageFilePath;
    }

    @Override
    public void showImage() {

        // Create real image only when required
        if (proxiedImage == null) {
            proxiedImage = new HighResolutionImage(imageFilePath);
        }

        proxiedImage.showImage();
    }
}

👉 Key idea: Real object is created only when needed.

This is called Lazy Loading Proxy.


Step 4: Client Code

public class ImageViewer {
    public static void main(String[] args) {

        Image remoteImage = new ImageProxy("sample/remote.jpg");
        Image localImage = new ImageProxy("sample/local.jpg");

        remoteImage.showImage();
        localImage.showImage();
    }
}

What happens internally?

StepAction
Client creates ProxyNo real image created
showImage() calledNow real image is created
Second callUses already created image

👉 This saves memory and improves performance.


================================

Types of Proxy

================================

1. Protective Proxy

Controls access based on authentication or authorization.

Example:

  • Bank system

  • Admin system

  • Secure file access


2. Virtual (Lazy Loading) Proxy

Delays creation of heavy objects.

Example:

  • Loading high-resolution images

  • Loading large files

  • Fetching remote data


================================

Main Advantages of Proxy Pattern

================================

AdvantageExplanation
Memory SavingCreates object only when needed
SecurityControls access
PerformanceUses caching
FlexibilityAdds logic without modifying real object
Loose CouplingClient does not know real object

================================

Final Student Summary

================================

“Proxy controls the Real Object. Client talks to Proxy, not to Real Object.”

In both examples:

  • ProjectBooker example → Proxy controls money flow

  • Image example → Proxy controls object creation

This makes Proxy Pattern very useful in real-world applications.



Just tell me 👍


No comments:

Post a Comment