Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。
作为开发人员,大多数时候,我们必须处理复杂的系统和许多依赖关系——有时甚至根本没有相关文档。
在这些情况下,找到解决这些挑战的方法是至关重要的。处理它的最常用方法是隐藏所有这些依赖项,并指定一个面向前端的接口。
为了实现这一点,最好的模式是facade模式。
不知何故,您最终得到了一个非常复杂的系统,该系统以各种方式生成报告。系统将报表生成为XML文件、CSV文件,甚至从数据库生成报表。
XML文件中生成的报告根据位置提取统计信息。CSV文件中生成的报告与时间序列数据和关于使用数据的数据库报告有关。
上面描述的功能需要合并到web应用程序中。
第一步是基于每个报表创建一些接口。第一个接口将是地理位置报告。通过给出地点和距离,报告将在指定地点的距离内生成。
package com.gkatzioura.design.structural.facade;
public interface GeolocationReport {
String[][] generate(Double lat,Double lng,Double distance);
}
Geolocation报表将基于系统生成的XML报表。因此,实现将基于XML报表。
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[][]{};
}
}
我们的下一份报表将与时间序列数据有关。两个日期将作为参数给出,因此将检索所需的数据。
package com.gkatzioura.design.structural.facade;
import java.util.Date;
public interface TimeSeriesReport {
String[][] generate(Date start,Date end);
}
因为CSV报表是用时间序列数据生成的,所以我们的实现将基于我们系统的CSV报表。
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[][]{};
}
}
最后一步是用户使用报告。应提供代表用户的uuid。
package com.gkatzioura.design.structural.facade;
import java.util.UUID;
public interface UsageReport {
String[][] report(UUID uuid);
}
使用基于数据库报表。
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][];
}
}
到目前为止,我们抽象了系统的主要功能。我们的下一步是创建facade,它使用所有这些功能并在web应用程序需求和提供信息的系统之间架起桥梁。例如,基于用户的使用情况,我们需要基于用户的时间和位置获得数据。
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);
}
而且,实现将使用报表实现来创建最适合我们的web应用程序的报表。
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[][] {};
}
}