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.

Plus I have compiled a cheat sheet containing a summary of the Structural Design Patterns.
Sign up in the link to receive it.

Advertisement

One thought on “Structural Design Patterns: Facade Pattern

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 )

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.