76

Structural Design Patterns: Facade Pattern

 5 years ago
source link: https://www.tuicool.com/articles/hit/2M7RNnV
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

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 best pattern to use in order to achieve this is the facade pattern.

Somehow, you end up with a very complex system that 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 reports generated in the CSV files have to do with time series data and the database report about usage data.

The functionalities described above need to be incorporated into 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;

public interface GeolocationReport {

     String[][] generate(Double lat,Double lng,Double distance);

}

The Geolocation 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;

public class XMLGeolocationReport implements GeolocationReport {

    @Override
    public String[][] generate(Double lat, Double lng, Double distance) {

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

        return new String[][]{};
    }

}

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;

public interface TimeSeriesReport {

    String[][] 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.Date;

public class CSVTimeSeriesReport implements TimeSeriesReport {

    @Override
    public String[][] generate(Date start, Date end) {

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

        return new String[][]{};
    }
}

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.UUID;

public interface UsageReport {

    String[][] report(UUID uuid);

}

The usage report will be based on the database report.

package com.gkatzioura.design.structural.facade;

import java.util.UUID;

public class SQLUsageReport implements UsageReport {

    @Override
    public String[][] report(UUID uuid) {
        return new String[0][];
    }
}

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 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.UUID;

public interface UserUsageFacade {

    String[][] usageOn(UUID user, Date from, Double lat,Double lng);

}

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

package com.gkatzioura.design.structural.facade;

import java.util.Date;
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 String[][] usageOn(UUID user, Date from, Double lat, Double lng) {

        String[][] locationData = geolocationReport.generate(lat,lng,DEFAULT_DISTANCE);
        Date to = Date.from(from.toInstant().plusSeconds(DEFAULT_TIME_RANGE));
        String[][] timeSetiesData = timeSeriesReport.generate(from,to);
        String[][] usageData = usageReport.report(user);

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

        return new String[][] {};
    }
}

You can find the source code on GitHub .

Here, you can also find some helpful articles on the Adapter Pattern, the Decorator Pattern, the Composite Pattern and the Bridge Pattern.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK