首页 > 文章列表 > Java设计模式中的外观模式实例分析

Java设计模式中的外观模式实例分析

java
162 2023-04-27

Java设计模式中的外观模式实例分析

模式介绍

  • 外观模式(Facade) ,也叫“过程模式:外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

  • 外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节。

UML类图

类图解析:

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

  • Client:外观接口的调用者。

  • SubSystem集合:指模块或者子系统,处理Facade对象指派的任务,他是功能的实际提供者。

外观模式案例:

背景介绍:

组建一个家庭影院:DVD播放器、投影仪、自动屏幕、环绕立体声、爆米花机,要求完成使用家庭影院的功能,通过直接用遥控器(统筹各设备开关)进行控制,其过程为:

  • 开爆米花机

  • 放下屏幕

  • 开投影仪

  • 开音响

  • 开DVD,选dvd

  • 拿爆米花

  • 调暗灯光

  • 播放

  • 观影结束后,关闭各种设备.

DVD、Popcorn、Projector、Screen、Stereo、TheaterLight代码如下:

public class DVDPlayer {

    // 使用单例模式

    private static  final DVDPlayer instance = new DVDPlayer();

    private DVDPlayer() {}

    public static DVDPlayer getInstance() {

        return instance;

    }

    public void on() {

        System.out.println("dvd 打开了...");

    }

    public void off() {

        System.out.println("dvd 关闭了...");

    }

    public void play() {

        System.out.println("dvd 播放中...");

    }

    public void pause() {

        System.out.println("dvd 暂停了...");

    }

}
public class Popcorn {

    private static final Popcorn instance = new Popcorn();

    private Popcorn(){}

    public static Popcorn getInstance() {

        return instance;

    }

    public void on() {

        System.out.println("爆米花机打开了...");

    }

    public void off() {

        System.out.println("爆米花机关闭了...");

    }

    public void pop() {

        System.out.println("爆米花做好了...");

    }

}
public class Projector {

    private static final Projector instance = new Projector();

    private Projector(){}

    public static Projector getInstance() {

        return instance;

    }

    public void on() {

        System.out.println("投影仪打开了...");

    }

    public void off() {

        System.out.println("投影仪关闭了...");

    }

    public void focus() {

        System.out.println("投影仪聚焦中...");

    }

}
public class Screen {

    private static final Screen instance = new Screen();

    private Screen(){}

    public static Screen getInstance() {

        return instance;

    }

    public void up() {

        System.out.println("屏幕上升...");

    }

    public void down() {

        System.out.println("屏幕下降...");

    }

}
public class Stereo {

    private static final Stereo instance = new Stereo();

    private Stereo(){}

    public static Stereo getInstance() {

        return instance;

    }

    public void on() {

        System.out.println("立体音响打开...");

    }

    public void off() {

        System.out.println("立体音响关闭...");

    }

    public void up() {

        System.out.println("立体音响音量+...");

    }

    public void down() {

        System.out.println("立体音响音量-...");

    }

}
public class TheaterLight {

    private static final TheaterLight instance = new TheaterLight();

    private TheaterLight(){}

    public static TheaterLight getInstance() {

        return instance;

    }



    public void on() {

        System.out.println("灯光打开...");

    }

    public void off() {

        System.out.println("灯光关闭...");

    }

    public void dim() {

        System.out.println("灯光亮度调暗...");

    }

    public void bright() {

        System.out.println("灯光亮度调亮...");

    }

}

HomeTheaterFacade(统筹各设备开关)

public class HomeTheaterFacade {

    private DVDPlayer dvdPlayer;

    private Popcorn popcorn;

    private Projector projector;

    private Stereo stereo;

    private Screen screen;

    private TheaterLight theaterLight;

    public HomeTheaterFacade() {

        this.dvdPlayer = DVDPlayer.getInstance();

        this.popcorn = Popcorn.getInstance();

        this.projector = Projector.getInstance();

        this.stereo = Stereo.getInstance();

        this.screen = Screen.getInstance();

        this.theaterLight = TheaterLight.getInstance();

    }



    /**

     * 准备开始

     */

    public void ready() {

        popcorn.on();

        popcorn.pop();

        screen.down();

        projector.on();

        projector.focus();

        stereo.on();

        dvdPlayer.on();

        theaterLight.dim();

    }



    /**

     * 播放

     */

    public void play() {

        dvdPlayer.play();

    }



    /**

     * 暂停

     */

    public void pause() {

        dvdPlayer.pause();

    }



    /**

     * 结束

     */

    public void end() {

        popcorn.off();

        theaterLight.bright();

        screen.up();

        projector.off();

        stereo.off();

        dvdPlayer.off();

    }

}

Client(测试)

public class Client {

    public static void main(String[] args) {

        HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade();

        System.out.println("----------准备开始-----------");

        homeTheaterFacade.ready();

        System.out.println("----------开始播放-----------");

        homeTheaterFacade.play();

        System.out.println("----------播放暂停-----------");

        homeTheaterFacade.pause();

        System.out.println("----------播放结束-----------");

        homeTheaterFacade.end();

    }

}

实现结果:

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

  • 外观模式对外屏蔽了子系统的细节,因此外观模式降低了客户端对子系统使用的复杂性。

  • 外观模式对客户端与子系统的耦合关系-解耦,让子系统内部的模块更易维护和扩展

  • 通过合理的使用外观模式,可以帮我们更好的划分访问的层次

  • 当系统需要进行分层设计时,可以考虑使用Facade模式。

  • 在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展,此时可以考虑为新系统开发一个Facade类,来提供遗留系统的比较清晰简单的接口,让新系统与Facade类交互,提高复用性。

  • 不能过多的或者不合理的使用外观模式,使用外观模式好,还是直接调用模块好。要以让系统有层次,利于维护为目的。