外观模式

世上唯一不能复制的是时间,唯一不能重演的是人生,唯一不劳而获的是年龄。该怎么走,过什么样的生活,全凭自己的选择和努力。人生很贵,请别浪费!与智者为伍,与良善者同行。外观模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

外观模式

案例引入

要求,组建一个家庭影院,DVD播放器,投影仪,自动屏幕,环绕立体声,爆米花机,实现家庭影院的功能。过程为,直接用遥控器,统筹各设备开关,开爆米花机,放下屏幕,开投影仪,开音响,开dvd,选dvd,取爆米花,调暗灯光,播放电影,观影结束后,关闭各设备。

传统方式实现案例

外观模式
无具体代码

传统方式实现案例分析

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

基本介绍

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

外观模式原理类图

外观模式

类图说明
  • 1.外观类,为调用者,提供统一的接口,外观类知道那些子系统负责处理请求,从而将调用者的请求代理给适当子系统的对象。、
  • 2.调用者,外观接口的使用者。
  • 3.子系统的集合,指模块或者子系统,处理Facede对象指派的任务,是功能的实际提供者。

外观模式实现案例

代码
/**
 * @author 长名06
 * @version 1.0
 * 界面类
 */
public class HomeTheaterFacade {

    private DVDPlayer dvdPlayer = DVDPlayer.getDvdPlayer();

    public Popcorn popcorn = Popcorn.getPopcorn();

    public Projector projector = Projector.getProjector();

    public Stereo stereo = Stereo.getStereo();

    public Screen screen = Screen.getScreen();

    public TheaterLight theaterLight = TheaterLight.getTheaterLight();

    public void ready(){
        popcorn.on();
        popcorn.pop();
        dvdPlayer.on();
        projector.on();
        screen.down();
        stereo.on();
        theaterLight.dim();
    }

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

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

    public void pause(){
        dvdPlayer.pause();
        stereo.setVolume();
    }
}
/**
 * @author 长名06
 * @version 1.0
 * 爆米花机
 */
public class Popcorn {

    private static Popcorn popcorn = new Popcorn();

    public static Popcorn getPopcorn(){
        return popcorn;
    }

    private Popcorn(){

    }

    public void on(){
        System.out.println("爆米花机 打开");
    }

    public void off(){
        System.out.println("爆米花机 关闭");
    }

    public void pop(){
        System.out.println("爆米花机 爆米花中");
    }
}
/**
 * @author 长名06
 * @version 1.0
 * 投影仪
 */
public class Projector {
    private static Projector projector = new Projector();

    public static Projector getProjector(){
        return projector;
    }

    private Projector() {
    }

    public void on(){
        System.out.println("投影仪 打开");
    }

    public void off(){
        System.out.println("投影仪 关闭");
    }

    public void focus(){
        System.out.println("投影仪 聚焦");
    }
}
/**
 * @author 长名06
 * @version 1.0
 * 投影屏幕
 */
public class Screen {

    private static Screen screen = new Screen();

    public static Screen getScreen(){
        return screen;
    }

    private Screen() {
    }

    public void down(){
        System.out.println("放下 投影屏幕");
    }

    public void up(){
        System.out.println("升起 投影屏幕");
    }
}
/**
 * @author 长名06
 * @version 1.0
 * 立体声
 */
public class Stereo {

    private static Stereo stereo = new Stereo();

    public static Stereo getStereo() {
        return stereo;
    }

    private Stereo() {
    }

    public void on() {
        System.out.println("立体声 打开");
    }

    public void off() {
        System.out.println("立体声 关闭");
    }

    public void setVolume(){
        System.out.println("立体声 设置音量");
    }
}
/**
 * @author 长名06
 * @version 1.0
 * 灯光
 */
public class TheaterLight {
    private static TheaterLight theaterLight = new TheaterLight();

    public static TheaterLight getTheaterLight(){
        return theaterLight;
    }

    private TheaterLight() {
    }

    public void on(){
        System.out.println("打开灯光");
    }

    public void off(){
        System.out.println("关闭灯光");
    }

    public void dim(){
        on();//先打开再调暗
        System.out.println("调暗灯光");
    }

    public void bright(){
        System.out.println("调量灯光");
    }
}
/**
 * @author 长名06
 * @version 1.0
 * dvd播放器
 */
public class DVDPlayer {

    private static DVDPlayer dvdPlayer = new DVDPlayer();

    public static DVDPlayer getDvdPlayer(){
        return dvdPlayer;
    }

    private DVDPlayer(){

    }

    public void on(){
        System.out.println(" dvd播放器 打开");
    }

    public void off(){
        System.out.println(" dvd播放器 关闭");
    }

    public void pause(){
        System.out.println(" dvd播放器 暂停");
    }

    public void play(){
        System.out.println(" dvd播放器 播放");
    }
}
//调用者
public class Client {
    public static void main(String[] args) {
        HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();
        homeTheaterFacade.ready();
        System.out.println("--------");
        homeTheaterFacade.play();
        System.out.println("--------");
        homeTheaterFacade.pause();
        System.out.println("--------");
        homeTheaterFacade.end();
    }
}

外观模式在Mybatis框架的源码分析

  //org.apache.ibatis.session.Configuration类的方法
  public MetaObject newMetaObject(Object object) {
    return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
  }
//MetaObject的forObject方法
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);
    }
  }
 //会调用到MetaObject类中的该方法
 private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
    this.originalObject = object;
    this.objectFactory = objectFactory;
    this.objectWrapperFactory = objectWrapperFactory;
    this.reflectorFactory = reflectorFactory;

    if (object instanceof ObjectWrapper) {
      this.objectWrapper = (ObjectWrapper) object;
    } else if (objectWrapperFactory.hasWrapperFor(object)) {
      this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
    } else if (object instanceof Map) {
      this.objectWrapper = new MapWrapper(this, (Map) object);
    } else if (object instanceof Collection) {
      this.objectWrapper = new CollectionWrapper(this, (Collection) object);
    } else {
      this.objectWrapper = new BeanWrapper(this, object);
    }
  }

外观模式的注意事项和细节

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

只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/213075.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!