Java设计模式之 [9] 结构型模式 - 外观模式

简介

1.外观模式(Facade) 也叫"过程模式":外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口.这个接口使得这一子系统更加容易使用
2.外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需要跟这个接口发生调用,,而不需关心这个子系统内部的调用细节

外观模式的原理图
Java设计模式之 [9] 结构型模式 - 外观模式_第1张图片
原理图

1.外观类(Facade):为调用端提供统一的调用接口,外观类知道了那些子系统负责处理请求,从而将调用端的请求代理给适当的子系统对象

案例 影院管理项目

2.调用者(Client).外观接口调用者
3.子系统的集合:指的是模块或者子系统,处理Facede对象指派的任务,它是功能的提供者
组建一个家庭影院 : DVD播放器,投影仪,自动屏幕.环绕立体声,爆米花机,要求完成家庭影院的功能,其过程为:
1.直接使用遥控器:统筹设备开关
2.开爆米花机
3.放下屏幕
4.开投影仪
5.开音响
6.开DVD,选dvd
7.去拿爆米花
8.调暗灯光
9.播放
10.观影结束之后,关闭各种设备

传统方式解决

1.创建所有的类
2,创建对象
3.调用方方法
.....

传统方式解决影院管理问题分析

1.在ClientTest的main方法中.创建各个子系统的对象,并且直接去调用子系统(对象)的相关方法,或造成调用过程混乱,没有清晰的过程
2.不利于ClientTest中,去维护子系统的操作
3.解决思路,定义一个高层接口,给子系统中的一组接口提供一个一致的界面(比如在高层接口提供的四个方法ready.play,pause,end)用来访问子系统中的一群接口
4.也就是说,通过定义一个一致的接口(界面类).用以屏蔽内部子系统的细节,使得调用端只需要跟这个接口发生调用,而无需关心这个子系统的内部细节 ==>> 外观模式

解决方案

1.外观模式可以理解为转换一群接口,客户只要调用一个接口,而不用调用多个接口才能实现目的,比如再pc上安装软件的时候,经常以后一键安装,可以省区很多操作
2.外观模式就是解决多个复杂接口带来的使用困难,起到简化用户操作的作用

实例

1.类图


Java设计模式之 [9] 结构型模式 - 外观模式_第2张图片
类图

2.代码

public class DVDPlayer {
    //使用单例模式 使用饿汉式
    private static DVDPlayer instance = new DVDPlayer();
    
    public static DVDPlayer getInstance() {
        return instance;
    }
    
    public void on() {
        System.out.println(" dvd on ");
    }
    public void off() {
        System.out.println(" dvd off ");
    }
    
    public void play() {
        System.out.println(" dvd play ");
    }
    
    public void pause() {
        System.out.println(" dvd pause ");
    }
}
public class Popcorn {
    private static Popcorn instance = new Popcorn();

    public static Popcorn getInstance() {
        return instance;
    }

    public void on() {
        System.out.println(" Popcorn on ");
    }

    public void off() {
        System.out.println(" Popcorn off ");
    }

    public void pop() {
        System.out.println(" Popcorn pop ");
    }

}
public class Projector {
    private static Projector instance = new Projector();

    public static Projector getInstance() {
        return instance;
    }

    public void on() {
        System.out.println(" Projector on ");
    }

    public void off() {
        System.out.println(" Projector off ");
    }

    public void focus() {
        System.out.println(" Projector focus ");
    }
}
public class Screen {
    private static Screen instance = new Screen();

    public static Screen getInstance() {
        return instance;
    }

    public void up() {
        System.out.println(" Screen up ");
    }

    public void down() {
        System.out.println(" Screen down ");
    }

}
public class Stereo {
    private static Stereo instance = new Stereo();

    public static Stereo getInstance() {
        return instance;
    }

    public void on() {
        System.out.println(" Stereo on ");
    }

    public void off() {
        System.out.println(" Stereo off ");
    }

    public void up() {
        System.out.println(" Stereo up ");
    }

    public void down() {
        System.out.println(" Stereo down ");
    }
}
public class TheaterLight {
    private static TheaterLight instance = new TheaterLight();

    public static TheaterLight getInstance() {
        return instance;
    }

    public void on() {
        System.out.println(" TheaterLight on ");
    }

    public void off() {
        System.out.println(" TheaterLight off ");
    }

    public void up() {
        System.out.println(" TheaterLight up ");
    }

    public void down() {
        System.out.println(" TheaterLight` down ");
    }
}
public class HomeClient {
    // 定义各个子系统对象

    private TheaterLight light;
    private DVDPlayer dvdPlayer;
    private Popcorn popcorn;
    private Screen screen;
    private Stereo stereo;
    private Projector projector;

    public HomeClient() {
        this.light = light.getInstance();
        this.dvdPlayer = dvdPlayer.getInstance();
        this.popcorn = popcorn.getInstance();
        this.screen = screen.getInstance();
        this.stereo = stereo.getInstance();
        this.projector = projector.getInstance();
    }


    // 操作分为4步骤
    public void ready() {
        popcorn.on();
        popcorn.pop();
        screen.down();
        projector.on();
        stereo.on();
        dvdPlayer.on();
        light.down();
    }

    public void play() {
        dvdPlayer.play();
    }

    public void pause() {
        dvdPlayer.pause();
    }

    public void end() {
        popcorn.off();
        popcorn.off();;
        screen.up();
        projector.off();
        stereo.down();
        dvdPlayer.off();
        light.up();
    }

}

测试

public class Client {
    public static void main(String[] args) {
        
        HomeClient client = new HomeClient();
        System.out.println("--------------------");
        client.ready();
        System.out.println("--------------------");
        client.play();
        System.out.println("--------------------");
        client.pause();
        System.out.println("--------------------");
        client.end();
    }
}

打印结果

--------------------
 Popcorn on 
 Popcorn pop 
 Screen down 
 Projector on 
 Stereo on 
 dvd on 
 TheaterLight` down 
--------------------
 dvd play 
--------------------
 dvd pause 
--------------------
 Popcorn off 
 Popcorn off 
 Screen up 
 Projector off 
 Stereo down 
 dvd off 
 TheaterLight up 
外观模式再Mybatis框架应用得源码分析

1.类图


Java设计模式之 [9] 结构型模式 - 外观模式_第3张图片
类图

2.Mybatis中的 Configuration 去创建 Meta Object对象使用到了外观模式

  public MetaObject newMetaObject(Object object) {
    return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
  }
  public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
    if (object == null) {
      return SystemMetaObject.NULL_META_OBJECT;
    } else {
      return new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
    }
  }
外观模式的注意事项和细节

1.外观模式对外屏蔽了子系统的细节,因此外观模式降低了客户端对子系统使用的复杂度
2.外观模式对客户端和子系统的耦合关系,使得子系统内部的模块更容易维护和多站
3.通过合理的使用外观模式,可以使得我们更好的划分访问的层次
4.当系统需要分层设计的时候,可以考虑使用Facade模式
5.在维护一个遗留的大型系统的时候,可能这个系统已经非常难以维护和拓展,此时可以考虑为新系统设计一个 Facade类,来提供遗留系统比较清晰的简单接口,当新系统一个Facade类交互,提高复用性
6.不能过多或者不合理的使用外观模式,使用外观模式好,还是直接调用好,要让系统有层次,利于维护为目的

你可能感兴趣的:(Java设计模式之 [9] 结构型模式 - 外观模式)