Structural Design Patterns: Proxy Pattern

Previously we used the facade pattern in order to interact with a legacy application. Our next pattern would be the proxy pattern.

The proxy pattern is used when we want

  • Control the access to an object
  • Add extra functionality when accessing an object.

One of the most common usages is when we want to monitor specific actions and add some metrics.

For example we have a data upload service.

package com.gkatzioura.design.structural.proxy;

public interface DataUploadService {

    void upload(String payload);

}

And its http implementation

package com.gkatzioura.design.structural.proxy;

public class HttpDataUploadImpl implements DataUploadService {

    @Override
    public void upload(String payload) {

    }

}

We need to have some measures on the average time it takes to send our application’s payload, in order to decide wether our implementation is good enough. If not we might need to consider something more performant.

Instead of messing with our implementation and adding code that has nothing to do with the actual transmission of the payload we shall create a proxy of our implementation.

package com.gkatzioura.design.structural.proxy;

import java.nio.charset.Charset;
import java.time.Duration;
import java.time.Instant;

public class HttpDataUploadProxy implements DataUploadService {

    private final HttpDataUploadImpl httpDataUpload;

    public HttpDataUploadProxy(HttpDataUploadImpl httpDataUpload) {
        this.httpDataUpload = httpDataUpload;
    }

    @Override
    public void upload(String payload) {

        Instant start = Instant.now();

        httpDataUpload.upload(payload);

        Duration duration = Duration.between(start,Instant.now());
        int byteSize = payload.getBytes(Charset.defaultCharset()).length;

        /**
         * Log properly to splunk, cloudwatch etc
         */
    }
}

As you can see our implementation hasn’t changed and we do manage to send the metrics needed to the analytics service of your choice.

We can also apply the same pattern in case this service has some quota and thus we want to control it because it might lead us to be over budget.

package com.gkatzioura.design.structural.proxy;

public class HttpDataUploadQuotaProxy implements DataUploadService {

    private final HttpDataUploadImpl httpDataUpload;

    public HttpDataUploadQuotaProxy(HttpDataUploadImpl httpDataUpload) {
        this.httpDataUpload = httpDataUpload;
    }

    @Override
    public void upload(String payload) {

        if(quotaExceeded()) {
            throw new IllegalStateException("Quota exceeded cannot upload payload");
        }

        httpDataUpload.upload(payload);
    }

    private boolean quotaExceeded() {

        /**
         * Code that should check whether we exceeded our quota or not
         */

        return false;
    }

}

Summing up we just used the proxy pattern in order to control the access to our object and also to enhance its functionality.

You can also find the source code on github.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.