Java设计模式百例 - 门面模式

本文源码见:https://github.com/get-set/get-designpatterns/tree/master/facade

门面模式(Facade Pattern)用于隐藏系统的复杂性,并向客户端提供一些简化访问方法和对现有系统类方法的委托调用。这种类型的设计模式属于结构型模式,用来隐藏系统的复杂性。

现在政府办事越来越方便了,很多城市、区县都有统一的办事大厅,里边有各个部门的窗口,一般进去一圈该办的事情就齐活了。想想之前,政府办个事情,这个部门盖个章,那个部门开个证明,不同的部门分散在城市的不同位置,一天有时候都办不妥当。先为这种进步点个赞!

各个部门还在各自的地方,但是都会在办事大厅开一个窗口。其实这个办事大厅就相当于各个部门的一个总的门面,就是用到了“门面模式”。我们现在的系统通常会越来越复杂,类之间的依赖调用关系逐渐变复杂,接口越来越多,这时候通常会用一个专门的类对某个模块或子系统进行一个包装,归置归置,简化对外提供服务的方法调用,较少方法数量。

例子

好久没有用那个画图的例子了,这里再次搬出来。对于门面模式来说,没有固化的类关系模型,一切以简化和封装为出发点,所以这个例子也比较简洁,领会意思即可。

这个例子中,有圆形、矩形和三角形三种形状,它们都继承自Shape

# Shape.java
public interface Shape {
    void draw();
}

# Circle.java
public class Circle implements Shape {
    public void draw() {
        System.out.println("Draw a circle.");
    }
}

# Rectangle.java
public class Rectangle implements Shape {
    public void draw() {
        System.out.println("Draw a ectangle.");
    }
}

# Triangle.java
public class Triangle implements Shape{
    public void draw() {
        System.out.println("Draw a triangle.");
    }
}

随着形状的增多,类数量也会显著增加,这个时候如果有一个统一的类来提供各个图形的draw功能就好了。我们之前用这个例子解释过工厂模式,工厂模式主要是用来获取类实例的,而门面模式是统一对外提供接口调用的。本例的门面类如下:

ShapeDrawer.java

public class ShapeDrawer {
    private ShapeDrawer() {}
    public static void drawCircle() {
        new Circle().draw();
    }
    public static void drawTrangle() {
        new Triangle().draw();
    }
    public static void drawRectangle() {
        new Rectangle().draw();
    }
}

这里,ShapeDrawer是作为类来使用了,因为其方法都是static的,因此也就不用创建其对象,所以构造方法声明为私有的。使用时直接调用静态方法即可:ShapeDrawer.drawCircle();

当然,这只是一种方式,并不是说门面模式就要这样做。
* 门面也可以是单例的,由一个单一的对象负责提供服务;
* 门面也可以是普通的多例的,比如其要包装的目标是多个对象,那么每个对象可能会需要一个门面实例,这个时候,门面通常也是起到一种隔离的作用,比如被包装的对象有许多接口是系统内调用的,并不对其他模块或子系统开放,而门面对象起到了一层代理的作用。

总结

门面模式更多是一种设计思想,而不是具体模型。目的是为子系统中的一组接口提供一个一致的界面,通过定义一个高层接口,降低访问复杂系统的内部子系统时的复杂度,使得这一子系统更加容易使用。

目录如下: ==================================== 实例1 HelloWorld 实例10 创建一个窗体 实例100 上传文件 实例11 按扭 实例12 复选框 实例13 复合下拉列表 实例14 下拉列表 实例15 选项卡 实例16 对话框 实例17 文件对话框 实例18 使用HTML语言 实例19 菜单 实例2 java流程控制 实例20 工具栏 实例21 内部窗体 实例22 分割一个面板 实例23 滑动杆 实例24 颜色过滤器 实例25 表格 实例26 基本图形绘制 实例27 绘制波图形 实例28 图片的处理 实例29 绘制指针时钟 实例3 数组数据操作 实例30 三围立方框 实例31 三围立方体 实例32 标准输入输出 实例33 读写文件(字节) 实例34 读写文件(字符操作) 实例35 获取文件信息 实例36 目录操作 实例37 读取随机文件 实例38 操作EXECL文件 实例39 生成PDF文件 实例4 矢量对象操作 实例40 压缩和解压文件 实例41 执行系统命令 实例42 获取计算机名称和IP地址 实例43 一对简单的服务器和客户端 实例44 多线程服务器 实例45 使用SMTP协议发送邮件 实例46 使用SMTP协议接收邮件 实例47 使用JAVAMAIL发送邮件 实例48 使用JAVAMAIL接收邮件 实例49 获取URL文本 实例5 哈希表和枚举器 实例50 一个简单的WEB服务器 实例51 数据报通讯:聊天吧 实例52 使用ODBC连接数据库 实例53 加载JDBC驱动 实例54 使用语句预处理 实例55 可滚动结果集 实例56 数据库元数据 实例57 结果集元数据 实例58 调用存储过程 实例59 事务处理 实例6 类的继承 实例60 继承THREAD 实例62 多线程 实例63 线程组群 实例64 线程间通讯 实例65 线程同步 实例66 线程控制 实例67 线程优先级 实例68 使用DOM解析XML 实例69 使用SAX解析XML 实例7 接口和抽象类 实例70 使用JDOM解析XML 实例71 使用JDOM操作XML 实例72 欢迎进入APPLET世界 实例73 传递参数 实例74 监测鼠标事件 实例75 监测键盘事件 实例76 在APPLET中使用SWING 实例77 应用JAR包 实例78 播放声音 实例79 一个简单的SERVLET 实例8 类的标识和访问控制 实例80 使用SERVLET获取客户表单 实例81 SERVLET读取COOKIE数据 实例82 SERVLET读取SESSION数据 实例83 一个简单的JSP 实例84 JSP处理表单提交 实例85 JSP连接数据库 实例86 JSP使用数据连接池 实例87 JSP+BEAN的应用 实例88 JSP+BEAN连接数据库 实例89 读取属性文件 实例9 异常的捕获和实现自己的异常类 实例90 上传文件 实例91 读取浏览器文件头 实例92 无状态会话EJB 实例93 有状态会话EJB 实例94 容器管理实体EJB 实例95 BEAN自管理实体EJB 实例96 消息驱动BEAN 实例97 简单的STRUTS 实例98 信息表单提交 实例99 连接数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值