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.

Structural Design Patterns: Facade Pattern

As developers most of the time we have to deal with complex systems, with many dependencies and even non existing documentation at all.

In these situations finding a way to tackle those challenges is essential. The most common way to deal with it, is to hide all those dependencies and specify a front facing interface.

The pattern to use in order to achieve is the facade pattern.

Somehow you end it up with a very complex system which generates reports in various ways. The system generates reports as xml files, csv files and even generates reports from a database.
The report generated in xml files extracts statistics based on a location, the report generated in csv files has to do with timeseries data and the database report about usage data.

The functionalities described above need to be incorporated to a web application.

The first step would be to create some interfaces based on each report.
The first interface will be the Geolocation report. By giving a location and a distance, a report shall be generated with locations within the distance specified from the point.

package com.gkatzioura.design.structural.facade;

import java.util.List;

public interface GeolocationReport {

     List<LocationInformation> generate(Double lat, Double lng, Double distance);

}

The Geolation report will be based on the xml reports generated from our system. Thus the implementation would be based on the xml report.

package com.gkatzioura.design.structural.facade;

import java.util.ArrayList;
import java.util.List;

public class XMLGeolocationReport implements GeolocationReport {

    @Override
    public List<LocationInformation> generate(Double lat, Double lng, Double distance) {

        /**
         * http requests to retrieve the xml
         * iterate the xml using stax
        */

        return new ArrayList<>();
    }

}

Our next report will have to do with time series data. Two dates will be given as an argument and thus the data needed will be retrieved.

package com.gkatzioura.design.structural.facade;

import java.util.Date;
import java.util.List;

public interface TimeSeriesReport {

    List<TimeInformation> generate(Date start, Date end);

}

Since the csv report is the one generated with time series data, our implementation will be based on the csv report of our system.

package com.gkatzioura.design.structural.facade;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class CSVTimeSeriesReport implements TimeSeriesReport {

    @Override
    public List<TimeInformation> generate(Date start, Date end) {

        /**
         * retrieve the csv and iterate line by line with the time limits
         */

        return new ArrayList<>();
    }
}

The last step is the user usage report. A uuid representing the user shall be given.

package com.gkatzioura.design.structural.facade;

import java.util.List;
import java.util.UUID;

public interface UsageReport {

    List<Usage> report(UUID uuid);

}

The usage report will be based on the database report.

package com.gkatzioura.design.structural.facade;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class SQLUsageReport implements UsageReport {

    @Override
    public List<Usage> report(UUID uuid) {

        return new ArrayList<>();
    }

}

So far we have abstracted the main functionalities of our system. Our next step is to create the facade which uses all those functionalities and bridges the gap between our web application needs and the the system that provides the information.
For example based on the user’s usage we need to have data based on the time and location of the user.

package com.gkatzioura.design.structural.facade;

import java.util.Date;
import java.util.List;
import java.util.UUID;

public interface UserUsageFacade {

    List<UserUsage> usageOn(UUID user, Date from, Double lat, Double lng);

}

And the implementation will use the report implementations in order to create the report that suits our web application.

package com.gkatzioura.design.structural.facade;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

public class UserUsageFacadeImpl implements UserUsageFacade {

    private final GeolocationReport geolocationReport;
    private final TimeSeriesReport timeSeriesReport;
    private final UsageReport usageReport;

    private final double DEFAULT_DISTANCE = 20d;
    private final int DEFAULT_TIME_RANGE = 20;

    public UserUsageFacadeImpl(GeolocationReport geolocationReport, TimeSeriesReport timeSeriesReport, UsageReport usageReport) {
        this.geolocationReport = geolocationReport;
        this.timeSeriesReport = timeSeriesReport;
        this.usageReport = usageReport;
    }

    @Override
    public List<UserUsage> usageOn(UUID user, Date from, Double lat, Double lng) {

        List locationInformationData = geolocationReport.generate(lat, lng, DEFAULT_DISTANCE);
        Date to = Date.from(from.toInstant().plusSeconds(DEFAULT_TIME_RANGE));
        List timeSetiesData = timeSeriesReport.generate(from, to);
        List usageData = usageReport.report(user);

        /**
         * Generate the report based on the data retrieved
         */

        return new ArrayList<>();
    }
}

You can find the source code on github.
Also you can find some helpful articles on the Adapter Pattern, the Decorator Pattern, the Composite Pattern and the Bridge Pattern.

Structural Design Patterns: Decorator Pattern

Previously we altered the behaviour of our abstract objects using the bridge pattern and we implemented a tree like structure for our components using the composite pattern and delegating the requests.

The decorator pattern allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.

So imagine the scenario of applying various discounts to one of our products.

We will start with the discount interface to specify the discount action.

package com.gkatzioura.design.structural.decorator;

import java.math.BigDecimal;

public interface Discount {
    
    BigDecimal apply(BigDecimal originalPrice);
    
}

An object which shall implement the discount will apply the discount and give back the discounted price.
One of the discounts that we want to apply is a special discount for newly registered members.
Newly registered members will have 20% off on their first order

package com.gkatzioura.design.structural.decorator;

import java.math.BigDecimal;

public class NewlyRegisteredDiscount implements Discount {

    public static final BigDecimal SEVENTY_FIVE = new BigDecimal(75);
    public static final BigDecimal ONE_HUNDRED = new BigDecimal(100);

    @Override
    public BigDecimal apply(BigDecimal originalPrice) {

        return originalPrice.multiply(SEVENTY_FIVE).divide(ONE_HUNDRED);
    }

}

As you have experienced sometimes more than one discounts are applied.
Our system also provides our customers with coupon discounts of 5 dollars off.

It is very comon to apply multiple discounts and our systems has to support this action. It is common to create discount packages which in reality are just a compination of packages.
To do so we will utilize the decorator pattern.
We will create the discount decorator.

package com.gkatzioura.design.structural.decorator;

import java.math.BigDecimal;

public class DiscountDecorator implements Discount {

    protected Discount discount;

    public DiscountDecorator(Discount discount) {
        this.discount = discount;
    }

    @Override
    public BigDecimal apply(BigDecimal originalPrice) {
        return discount.apply(originalPrice);
    }
}

So we want to have a first purchase discount and a 5 dollars of discount for new users referenced by other users.
We will call this discount as ‘referenced user’ discount.
The goal is to have 5 dollars off and a discount applied to the original price.

package com.gkatzioura.design.structural.decorator;

import java.math.BigDecimal;

public class ReferencedUserDiscount extends DiscountDecorator {

    public static final BigDecimal FIVE = new BigDecimal(5);

    public ReferencedUserDiscount(Discount discount) {
        super(discount);
    }
    
    @Override
    public BigDecimal apply(BigDecimal originalPrice) {

        BigDecimal discountedPrice = super.apply(originalPrice);

        if(discountedPrice.compareTo(FIVE)<=0) {
            return discountedPrice;
        }

        return discountedPrice.subtract(FIVE);
    }
}

Imagine now the scenario of a loyalty discount. We want a two year plan for our users with a discount of 5% for each one of their orders.

package com.gkatzioura.design.structural.decorator;

import java.math.BigDecimal;

public class TwoYearPlanDiscount extends DiscountDecorator {

    public static final BigDecimal NINETY_NINE = new BigDecimal(95);
    public static final BigDecimal ONE_HUNDRED = new BigDecimal(100);

    public TwoYearPlanDiscount(Discount discount) {
        super(discount);
    }

    @Override
    public BigDecimal apply(BigDecimal originalPrice) {
        return super.apply(originalPrice).multiply(NINETY_NINE).divide(ONE_HUNDRED);
    }

}

As you can see both in the cases of the referenced user discount and both in the case of the two years plan discount we didn’t alter our original discount for our newly registered users. What we did is decorating the original discount and giving back the discount by taking into account the various options.

The decorator pattern is about

  • Add Responsibilities or remove them from an object dynamically at run-time.
  • Extend functionality in a flexible way without subclassing

So let’s put our plan into action.

package com.gkatzioura.design.structural.decorator;

import java.math.BigDecimal;

public class DecoratorScenario {

    public static void main(String args[]) {

        NewlyRegisteredDiscount newlyRegisteredDiscount = new NewlyRegisteredDiscount();
        ReferencedUserDiscount referencedUserDiscount = new ReferencedUserDiscount(newlyRegisteredDiscount);
        TwoYearPlanDiscount twoYearPlanDiscount = new TwoYearPlanDiscount(referencedUserDiscount);
        BigDecimal discountPrice = twoYearPlanDiscount.apply(new BigDecimal(100));
    }

}

Our newly registered users will have three types of discounts.

You can find the sourcecode on github.

Structural Design Patterns: Composite Pattern

Previously we checked the adapter pattern the use cases and the bridge pattern. The pattern we will examine in this post is the composite pattern.
By following the composite pattern we “compose” objects into tree structures representing part-whole hierarchies, therefore clients can treat individual objects and compositions uniformly.

By referencing the word hierarchies the first thing that comes to mind is organisations. A military organisation is a great example for the composite pattern.

One of the most basic actions of military personnel is to execute orders.
Thus we will make an interface which specifies the ability to execute orders.

package com.gkatzioura.design.structural.composite;

public interface MilitaryPersonnel {

    void executeOrder();

}

The private is the lowest rank in a military organisation. A private cannot delegate a task or give orders. Therefore he will just execute an order.

package com.gkatzioura.design.structural.composite;

public class Private implements MilitaryPersonnel {

    @Override
    public void executeOrder() {

    }

}

Above the private there are other ranks like Major, Lieutenant, Colonel etc. Those are officer ranks and officers execute orders but also they can assign orders.
So the Officer interface will specify the ability to assign orders.

package com.gkatzioura.design.structural.composite;

public interface Officer {

    void assignOrder();

}

Be aware that an officer in order to execute an order he will take some actions on his own and he might as well assign some orders to lower rank personnel.

So the Lieutenant will be able to execute orders but also to assign orders to ranks lower that him.

package com.gkatzioura.design.structural.composite;

import java.util.ArrayList;
import java.util.List;

public class Lieutenant implements MilitaryPersonnel, Officer {

    private List<MilitaryPersonnel> lowerRankersonel = new ArrayList<>();

    public Lieutenant(List<MilitaryPersonnel> lowerRankersonel) {
        this.lowerRankersonel = lowerRankersonel;
    }

    public void addPrivateUnderCommand(Private soldier) {
        lowerRankersonel.add(soldier);
    }
    
    @Override
    public void executeOrder() {
        
        //other actions

        assignOrder();

        //other actions.
    }

    @Override
    public void assignOrder() {

        lowerRankersonel.forEach(lr->lr.executeOrder());
    }
}

The same that applies to the lieutenant applies to the major who is able to execute orders and assign orders to lower ranks.

package com.gkatzioura.design.structural.composite;

import java.util.ArrayList;
import java.util.List;

public class Colonel implements MilitaryPersonnel, Officer {

    private List<MilitaryPersonnel> lowerRankersonel = new ArrayList<>();

    public Colonel(List<MilitaryPersonnel> lowerRankersonel) {
        this.lowerRankersonel = lowerRankersonel;
    }

    public void addPrivateUnderCommand(Private soldier) {
        lowerRankersonel.add(soldier);
    }

    public void addLieutenantUnderCommand(Lieutenant lieutenant) {
        lowerRankersonel.add(lieutenant);
    }

    @Override
    public void executeOrder() {
        //other actions

        assignOrder();

        //other actions
    }

    @Override
    public void assignOrder() {
        lowerRankersonel.forEach(lr->lr.executeOrder());
    }
}

In our scenario the general is the highest rank and thus when he assigns an order this order will be executed by the composite we implemented.

package com.gkatzioura.design.structural.composite;

import java.util.ArrayList;
import java.util.List;

public class General implements  Officer {

    private List<MilitaryPersonnel> lowerRankersonel = new ArrayList<>();

    public General(List<MilitaryPersonnel> lowerRankersonel) {
        this.lowerRankersonel = lowerRankersonel;
    }

    @Override
    public void assignOrder(MilitaryPersonnel militaryPersonnel) {
        militaryPersonnel.executeOrder();
    }
}

And a main class will display the composite’s functionality.

package com.gkatzioura.design.structural.composite;

import java.util.Collections;

public class CompositeScenario {

    public static void main(String[] args) {

        Private ryan = new Private();
        Lieutenant lieutenant = new Lieutenant(Collections.singletonList(ryan));
        Major major = new Major(Collections.singletonList(lieutenant));
        General general = new General();
        general.assignOrder(major);
    }
}

As you can see the general object, which is the client treated all the objects uniformly.
The whole hierarchy is represented in a tree structure.
The private is the leaf the major and the lieutenant represent the Composite that forwards the requests to the corresponding child components.

You can find the source code on github.