结构型设计模式:外观设计模式

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[][] {};
            }
        }

原文发布于微信公众号 - 程序你好(codinghello)

原文发表时间:2018-08-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Ldpe2G的个人博客

ScalaMP ---- 模仿 OpenMp 的一个简单并行计算框架

12230
来自专栏WeTest质量开放平台团队的专栏

Unity手游崩溃异常如何捕获--C#及JVM捕获

C#脚本未捕获的异常,与Android和Native未捕获异常很大的区别是,未捕获异常不会照成引用的闪退。所以,C#脚本的异常危害相对较小,但是同样更加容易存在...

37340
来自专栏极客猴

常用Python标准库

众所周知,Python有庞大的库资源,有官方标准库以及第三方的扩展库。每个库都一把利器,能帮助我们快速处理某方面的问题。作为一名python的初学者,当把基本的...

36130
来自专栏嵌入式程序猿

教你MODBUS程序符合MISRA规则

做嵌入式开发的广大工程师应该对MISRA C不陌生,他是Motor Industry Software Reliability Association 的缩写,...

17230
来自专栏JavaEdge

Java Fork Join 框架Doug Lea 关于Java 7引入的他写的Fork/Join框架的论文0. 摘要1. 简介2. 设计3. 实现

33080
来自专栏自动化测试实战

RF第三讲--定义用户关键字

39750
来自专栏美团技术团队

Android插件化、热补丁中绕不开的ProGuard的坑

26260
来自专栏AndroidTv

移动端造json假数据时的坑(转义符问题)

迭代开发中,经常出现服务端接口还没开发完成的情况,所以经常需要移动端自己在本地造一些假数据。

43550
来自专栏Crossin的编程教室

【每日一坑 4】 查找文件

上一个坑,取出字符串中的数字,在论坛上出现了好几种方法。除了基本的遍历判断来做外,还有一些简便的python解法: 1.正则 ''.join(re.findal...

28670
来自专栏FreeBuf

代码安全审计:当file_exists遇上eval

起因 昨晚有人在一QQ群上问lcms(一款网站CMS系统)的一个漏洞是怎么形成的,说了半天。他截图不完整,于是叫他传代码,下载回来找到router.php代码片...

20990

扫码关注云+社区

领取腾讯云代金券