每天一个设计模式-2  外观模式(Facade)

1.生活中的示例

客户想要购买一台电脑,一般有两种方法:

1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高。

2.去电脑组装公司,告诉他们你需要的电脑配置,再由电脑组装公司的人来组装电脑,这种方式比较简单通用,现实中一般也是这个样子。

如图所示:

DIY

交给装机公司

2.从示例中联想编程

显然,DIY要求客户熟悉各配件的使用,联想到编程上就是客户端直接调用各个模块完成所需功能,对于客户端来说显得很麻烦。

卖CPU的公司、卖主板的公司。。。在代码中可以理解为小的模块,装机公司即为这次学习的主角“外观”。

结合编程

3.外观模式的定义

为子系统中的组接口提供一个一致的界面,Facade模式定义了一个高层接口(不只是Interface),这个接口使得这一子系统更加容易使用

接口:这里的接口不一定是Interface,也有可能是一个方法,提供外部和内部交互的通道。

界面:主要指的是从一个组件外部来看这个组件,能看到什么(只能看到Facde中封装的方法),这就是组件的界面,也就是组件的外观。

4.外观模式解决的主要问题

使客户端操作更加简单。

5.编程思路

通过引入一个外观类,在这个类里面定义客户端需要的方法,在这些方法中分别调用多个模块来实现某一个功能,从而使得客户端变得简单。

6.类图

UML类图讲解:http://blog.csdn.net/tianhai110/article/details/6339565

7.代码

子系统代码(模块)

public interface Model1Api {

    public void test1();

}

Model1Api

public class Model1Impl implements Model1Api {

    public Model1Impl(){

    }

    public void finalize() throws Throwable {

    }

    public void test1(){
        System.out.println("启动了Model1模块");
    }

}

Model1Impl

public interface Model2Api {

    public void test2();

}

Model2Api

public class Model2Impl implements Model2Api {

    public Model2Impl(){

    }

    public void finalize() throws Throwable {

    }

    public void test2(){
        System.out.println("启动了Model2模块");
    }

}

Model2Impl

public interface Model3Api {

    public void test3();

}

Model3Api

public class Model3Impl implements Model3Api {

    public Model3Impl(){

    }

    public void finalize() throws Throwable {

    }

    public void test3(){
        System.out.println("启动了Model3模块");
    }

}

Model3Impl


外观

public class Facade {

    public Facade(){

    }

    public void finalize() throws Throwable {

    }

    public static void test(){
        Model1Api m1 = new Model1Impl();
        Model2Api m2 = new Model2Impl();
        Model3Api m3 = new Model3Impl();
        m1.test1();
        m2.test2();
        m3.test3();
    }
}

Facade


客户

public class Client {

    public Client(){

    }

    public void finalize() throws Throwable {

    }

    /**
     *
     * @param args
     */
    public static void main(String[] args){
        Facade.test();
    }

}

Client


8.外观模式的目的

外观模式的目的不是给子系统添加新的功能接口,而是为了让外部减少与子系统内多个模块的交互,松散耦合,从而让外部能更简单的使用子系统。虽然可以在外观类内定义一些子系统没有的功能,但不建议这样做,外观类的主要作用就是组装已有的功能来实现用户需要,而不是添加新的实现。

9.Facade也可以实现成为Interface

这样做会增加系统的复杂度,因为这样做还需要一个Facade的实现和一个获取Facade接口对象的工厂,客户端通过这个工厂才成生成需要的Facade接口对象。但是这样做的好处是,能够有选择性的暴露接口的方法

10.外观模式的优缺点

优点:

1.松散耦合:降低了客户端与子系统的耦合关系,使得子系统的各个模块扩展性和可维护性增强。

2.简单易用:客户端更容易使用功能。

3.更好的划分访问的层次:把暴露给外部的功能集中到外观中,这样既方便了客户端,又隐藏了内部的具体实现细节。

缺点:

过多的或者不合理的使用Facade也容易让人迷惑,到底调用Facade好还是直接调用模块好。

11.总结

外观模式作用就是组装,将子系统多个模块以某种方式拼装到一起,客户端调用时只需要调用外观类的方法就可以得到自己想要的功能。并且,客户端无需知道如何组装以及实现细节,简化了客户端的操作。有选择的暴露接口方法,方便划分访问的分层

 

------博主写博客不容易,转载请注明出处,谢谢:http://www.cnblogs.com/xiemubg/p/5945720.html

每天一个设计模式-2 外观模式(Facade)的更多相关文章

  1. 乐在其中设计模式(C#) - 外观模式(Facade Pattern)

    原文:乐在其中设计模式(C#) - 外观模式(Facade Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 外观模式(Facade Pattern) 作者:webabcd 介绍 ...

  2. 8.4 GOF设计模式三: 外观模式 Facade

    GOF设计模式三: 外观模式 Facade  “现有系统”功能强大.复杂,开发“新系统”需要用到其中一部分,但又要增加一部 分新功能,该怎么办?4.1 Facade Pattern: Key Fea ...

  3. 二十四种设计模式:外观模式(Facade Pattern)

    外观模式(Facade Pattern) 介绍为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用.示例有一个Message实体类,某对象对它 ...

  4. python : 设计模式之外观模式(Facade Pattern)

    #为啥要用外观模式举例说明 这个例子很形象,直接从人家博客上贴过来的,参考链接在下面 不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别,如果是自己泡茶需要自行准备茶叶.茶具和开水,如图1(A)所示,而 ...

  5. [设计模式] 10 外观模式 facade

    外观模式应该是用的很多的一种模式,特别是当一个系统很复杂时,系统提供给客户的是一个简单的对外接口,而把里面复杂的结构都封装了起来.客户只需使用这些简单接口就能使用这个系统,而不需要关注内部复杂的结构. ...

  6. 设计模式 笔记 外观模式 Facade

    //---------------------------15/04/16---------------------------- //Facade 外观模式-----对象结构型模式 /* 1:意图: ...

  7. 设计模式之外观模式(Facade)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  8. 【设计模式】—— 外观模式Facade

    前言:[模式总览]——————————by xingoo 模式意图 外观模式主要是为了为一组接口提供一个一致的界面.从而使得复杂的子系统与用户端分离解耦. 有点类似家庭常用的一键开关,只要按一个键,台 ...

  9. 结构型设计模式之外观模式(Facade)

    结构 意图 为子系统中的一组接口提供一个一致的界面,F a c a d e 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 适用性 当你要为一个复杂子系统提供一个简单接口时.子系统往往因 ...

随机推荐

  1. 初识npm

    一.npm简介: npm全称为Node Package Manager,是一个基于Node.js的包管理器,也是整个Node.js社区最流行.支持的第三方模块最多的包管理器. npm的初衷:JavaS ...

  2. win10电脑优化

    Windows10必做的优化 --道心 关闭服务 右键点击"此电脑",选择"管理",进入"计算机管理"窗口. 在左侧的菜单选择"服 ...

  3. 机器指令翻译成 JavaScript —— No.4 动态跳转

    上一篇,我们用模拟流程的方式,解决了跳转问题. 不过静态跳转,好歹事先是知道来龙去脉的.而动态跳转,只有运行时才知道要去哪.既然流程都是未知的,翻译从何谈起? 动态跳转,平时出现的多吗?非常多!除了 ...

  4. Flume1 初识Flume和虚拟机搭建Flume环境

    前言:       工作中需要同步日志到hdfs,以前是找运维用rsync做同步,现在一般是用flume同步数据到hdfs.以前为了工作简单看个flume的一些东西,今天下午有时间自己利用虚拟机搭建了 ...

  5. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  6. 玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理

    Windows服务Debug版本 注册 Services.exe -regserver 卸载 Services.exe -unregserver Windows服务Release版本 注册 Servi ...

  7. C# 深拷贝的具体代码的封装与调用

    先封装下实现方法: public class DeepClone { public static object CopyObject(Object obj) { if (obj == null) { ...

  8. python的print函数的格式化输出

    使用print函数的时候,可以像C一样格式化输出,同时还支持参数化输出 print('%s' % ("CooMark")) print('整数|%d|' % (123)) prin ...

  9. css3圆环百分比,菜单栏定位导航

    前段时间,社区个人中心改版,看了下设计图,当时隐约感觉到有两个地方(圆环百分比,菜单栏定位导航)比较麻烦.设计图大致如下: 首先看圆环百分比,网上的做法大致分两种,一种是用了CSS3中的transfo ...

  10. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(14)-EasyUI缺陷修复与扩展

    系列目录 不知不觉已经过了13讲,(本来还要讲多一讲是,数据验证之自定义验证,基于园友还是对权限这块比较敢兴趣,讲不讲验证还是看大家的反映),我们应该对系统有一个小结.首先这是一个团队开发项目,基于接 ...