面向对象的设计模式(十二),外观模式

?终于考试完了,瞬间感觉轻松了许多,又可以安心地写代码了,下面进入今天的正题–外观模式。

?外观模式,也称门面模式,顾名思义,就是一个对象封装了一系列相关的操作(行为),使得这些操作仅对外提供(暴露)方法(接口),客户端根据这些外观(暴露的接口)就可以简单地完成一系列操作,达到了客户端无需知道内部实现细节,只需知道对象的外观就可以实现一系列行为,简单来说就是面向对象的封装。这一系列行为也就是一个系统的功能。

定义:通过一个统一的对象实现一个系统的外部与内部的通讯,提供了一个高层次的接口,使得系统功能更加透明,更加容易使用。

使用场景:

  1. 为一个复杂系统提供一个简单的接口。为一个复杂系统提供一个简单的接口,对外部隐藏系统的内部实现,隔离变化,使得当这个系统因为不断演化而不断的修改,定制也可以更加容易地扩展使用,即对外部的使用是一样的,客户端无需知道内部发生了什么变化,隐藏了系统的内部实现,这也就是封装的好处了。
  2. 简化子系统之间的依赖,降低它们之前的耦合。当不同的子系统需要使用其他系统的功能的时候,那么我们就需要构建一个层次结构的系统,这时我们通过外观模式为这些子系统提供一个通讯接口,即每层的入口点。

优点:

  1. 因为对客户端隐藏了系统的细节,减少了客户端对于系统的耦合,能够拥抱变化。
  2. 对系统一系列功能进行了整合,封装,使得系统更加容易使用。

缺点:

  1. 外观类接口膨胀。因为我们外观类需要封装一系列相关的功能,这一系列相关的功能可能需要不同的类实现,那么我们不是简单地给这个外观类提供实现不同功能类,而是为每个实现不同功能的类提供一个接口,然后再使用的时候给这些接口提供实现类,这样可以便于扩展,反之,外观类接口必然膨胀,也增加了程序员的一定的负担。
  2. 违背了开闭原则,当业务出现变更的时候,可能需要直接修改外观类(通常是修改外观类中的接口的实现类)。

下面以现代智能机模拟实现外观模式

代码实现:

虚拟手机(接口)—-接打电话功能接口


public interface Phone {
    /**
     * 打电话
     */
    public void call();
    /**
     * 挂断
     */
    public void handup();
}

虚拟相机(接口)—-拍照功能接口

/**
 * 照相机
 * @author lt
 *
 */
public interface Camera {
    public void open();
    public void takePicture();
    public void close();
}

真实的手机(实现类)

/**
 * 以前的旧手机,非智能,只能打电话和挂电话
 * @author lt
 *
 */
public class PhoneImpl implements Phone{

    @Override
    public void call() {
        System.out.println("打电话");
    }

    @Override
    public void handup() {
        System.out.println("挂断电话");
    }
}

真实的相机(实现类)

/**
 * 三星相机
 * @author lt
 *
 */
public class SamsungCamera implements Camera{

    @Override
    public void open() {
        System.out.println("打开相机");
    }

    @Override
    public void takePicture() {
        System.out.println("拍到了一个美女");
    }

    @Override
    public void close() {
        System.out.println("相机关闭了");
    }
}

现代智能机(Android/Iphone)—-外观类

/**
 * 现代智能机 ---  集照相,视频聊天,打电话于一身
 * @author lt
 *
 */
public class SmartPhone {
    // 对应实现完成手机功能接口的实现类
    public Phone phone = new PhoneImpl();
    // 对应实现相机功能接口的实现类
    public Camera camera = new SamsungCamera();

    public void call() {
        phone.call();
    }

    public void hangup() {
        phone.handup();
    }

    public void takePicture() {
        openCamera();
        camera.takePicture();
        closeCamera();
    }

    public void openCamera() {
        camera.open();
    }

    public void closeCamera() {
        camera.close();
    }

    /**
     * 视频通话
     */
    public void videoChat() {
        openCamera();
        System.out.println("和妹子视频聊天");
        closeCamera();
    }
}

?SmartPhone是外观类,这里具体是现代智能机,具有接打电话,拍照等功能,是这个模式核心类;PhoneCamera是两个特定功能的接口,分别是接打电话的功能,拍照功能,相应的实现类是PhoneImlSamsungCamera。这里给外观类整了两个接口,即PhoneCamera,这样做的目的是以后要修改接打电话和拍照功能的实现时(如新的硬件)只需要将外观类SmartPhone中的相应功能的接口实现类改变一下就可以了,其他的都不用改,这也就是面向接口编程的好处,和J2EE中的ServiceDao层都提供一个接口和相应实现类一样,目的是一样的,即便于修改扩展。

测试:


public class Test {

    public static void main(String[] args) {
        SmartPhone iphone7s = new SmartPhone();
        // 用7s拍照
        iphone7s.takePicture();
        // 用7s视频聊天
        iphone7s.videoChat();
    }
}

运行结果:

可以看到,现代的智能机既有一般手机的功能,也有相机的功能,使得我们只需要一部智能机就不需要专门为打电话买一个手机,专门为拍照买一个相机了,一部手机统统搞定,而且避免了许多麻烦,如我们点击屏幕的相机(系统内置App)系统自动打开了相机,拍照完了以后系统自动将相机关闭,视频聊天也一样,这使得我们使用更加简单,更加方便。

总结:

?外观模式使用也非常多,面向对象中的封装也通常是使用了外观模式,封装不一定使用了外观模式,但外观模式一定需要封装。通过外观模式,使得复杂系统功能更加丰富,使用更加简单。通过一个外观类就可以操作整个系统,减少了用户的使用成本,同时因为内部面向接口编程,使得使扩展维护更加简单,从而使得系统可以容易地面对多变的场景,提升了系统的扩展性灵活性。

时间: 2024-10-11 11:56:12

面向对象的设计模式(十二),外观模式的相关文章

C#设计模式之十二代理模式(Proxy Pattern)【结构型】

原文:C#设计模式之十二代理模式(Proxy Pattern)[结构型] 一.引言 今天我们要讲[结构型]设计模式的第七个模式,也是"结构型"设计模式中的最后一个模式,该模式是[代理模式],英文名称是:Proxy Pattern.还是老套路,先从名字上来看看."代理"可以理解为"代替",代替"主人"做一些事情,为什么需要"代理",是因为某些原因(比如:安全方面的原因),不想让"主人"直接

研磨设计模式解析及python代码实现——(二)外观模式(Facade)

一.外观模式定义 为子系统中的一组接口提供一个一致的界面,使得此子系统更加容易使用. 二.书中python代码实现 1 class AModuleApi: 2 def testA(self): 3 pass 4 class AModuleImpl(AModuleApi): 5 def testA(self): 6 print "Now Call testA in AModule!" 7 class BModuleApi: 8 def testB(self): 9 pass 10 cla

设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)

 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就推卸给另外个一个部门(对象).至于究竟谁来解决问题呢?政府部门就是为了能够避免屁民的请求与官员之间耦合在一起,让多个(部门)对象都有可能接收请求,将这些(部门)对象连接成一条链,而且沿着这条链传递请求.直到有(部门)对象处理它为止. 样例1:js的事件浮升机制 样例2: 2.问题 假设有多个对象都有

设计模式学习笔记--外观模式

好久没写设计模式的blog了,这次重新回来填坑,先找一个最简单但是却最常用的设计模式来学习,外观模式.其实说是一个设计模式,其实我们在实际的编程中无时无刻不在用外观模式,可以说这个设计模式已经渗透到编程的各个方便,可能我们自己没感觉出来罢了. 一.外观模式的定义 先来看一下外观模式的定义: 外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层的接口,这个接口使得这一系列子系统更加容易使用. 简单解释一下,所谓外观模式,就是在我们设计系统的时候,将若干个子系统的功

设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕该功能.如查找.排序等,一种经常使用的方法是硬编码(Hard Coding)在一个类中,如须要提供多种查找算法,能够将这些算法写到一个类中,在该类中提供多个方法,每个方法相应一个详细的查找算法:当然也能够将这些查找算法封装在一个统一的方法中,通过if-else-或者case等条件推断语句来进行选择.

【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法:当然也可以将这些查找算法封装在一个统一的方法中,通过if-else-或者case等条件判断语句来进行选择.这

设计模式学习之外观模式(Facade,结构型模式)(8)

1.什么是外观模式为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 2.为什么要使用外观模式在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,从而导致客户程序随着子系统的变化而变化,那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子系统与客户程序之间的依赖解耦? 现在来考虑这样一个抵押系统,当有一个客户来时,有如下几件事情需要确认:到银行子系统查询他是否有足够多的存款,到信用子系统查询他是否有良好的信

设计模式学习(十) 外观模式

迪米特法则(最少知识原则): 一个软件实体应当尽可能少的与其他实体发生相互作用. 外观模式核心: -- 为子系统提供统一的入口,封装子系统的复杂性,便于客户端调用. 以办理公司为例: package com.lp.facade; public interface 工商局 { void checkName(); } class 海淀区工商局 implements 工商局{ @Override public void checkName() { System.out.println("检查名字是否有

设计模式(十)外观模式

外观模式核心:为子系统提供统一的入口,封装子系统的复杂性,便于客户端的调用. 开发中常见的场景:频率很高,哪里都会遇到.各种技术和框架中,都有外观模式的使用. 如:JDBC封装后的,commons提供的DBUtils类,Hibernate提供的工具类.Spring JDBC工具类等. 例: 1. 创建工商局接口,海淀区工商局类实现该接口 2. 创建税务局接口,海淀区税务局类实现该接口 3. 创建银行接口,中国工商银行类实现该接口 4. 创建质检局接口,海淀区质检局类实现该接口 5. 创建Regi

c#设计模式之:外观模式(Facade)

一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 "门面"模式.下面就具体介绍下外观模式. 二.外观模式的详细介绍 2.1定义 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使用.使用外观模式时,我们创建了一个统一的类,用来包装子系统中一个或多个复杂的类,客户端可以直接通过外观类来调用内部