设计模式-外观模式(门面模式)

外观模式(门面模式)

外观模式介绍

定义

通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。 该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

好比我们去封装工具类。

优点

  • 简化客户端的调用
  • 代码复用,整合

应用场景

  • 需要使用复杂的子系统,但想避免重复且复杂的调用过程
  • 子系统需要组织成层结构时

经典案例

  • org.apache.catalina.connector.RequestFacade

外观模式结构与实现

其实外观模式就是在底层上封装一层接口,避免上层用户直接调用底层接口,提供一些简单的接口给用户使用!

结构

可以通过添加一个抽象外观角色来遵循开闭原则

外观(Facade)角色:为多个子系统对外提供一个共同的接口。
子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
客户(Client)角色:通过一个外观角色访问各个子系统的功能。
外观模式

模板实现

本来我们需要实现一个功能需要依次执行三个系统类的三个方法,用户使用非常麻烦,因此可以封装一层 外观 类,它来负责与系统交互,用户只需要调用它提供的简单接口即可实现复杂的系统功能!!!


/**
 * 外观角色
 */
class Facade {
    private SubSystem01 subSystem01 = new SubSystem01();
    private SubSystem02 subSystem02 = new SubSystem02();
    private SubSystem03 subSystem03 = new SubSystem03();

    public void method() {
        subSystem01.method1();
        subSystem02.method2();
        subSystem03.method3();
    }
}

/**
 * 子系统角色1
 */
class SubSystem01 {
    public void method1() {
        System.out.println("子系统01的method1()被调用!");
    }
}

/**
 * 子系统角色2
 */
class SubSystem02 {
    public void method2() {
        System.out.println("子系统02的method2()被调用!");
    }
}

/**
 * 子系统角色3
 */
class SubSystem03 {
    public void method3() {
        System.out.println("子系统03的method3()被调用!");
    }
}

/**
 * 客户端角色
 */
public class FacadeTemplateTest {
    public static void main(String[] args) {
        Facade f = new Facade();
        f.method();
    }
}

/*
	子系统01的method1()被调用!
	子系统02的method2()被调用!
	子系统03的method3()被调用!
*/

示例 DVD播放电影

这个示例中我添加了 抽象外观角色,是为了遵循开闭原则,便于以后在不改变原有类的前提下扩展外观角色!

播放电影需要涉及到 DVD机、显示屏、音箱三个子系统,避免用户接触底层系统,创建外观角色提供简单的接口操作电影的开启、暂停与关闭

/**
 * 子系统3
 * 用于声音播放
 */
class SoundBox {
    private boolean isRun;

    public void on() {
        if (!isRun) {
            System.out.println("开启音箱");
        }
    }

    public void off() {
        if (isRun) {
            System.out.println("关闭音箱");
        }
    }
}

/**
 * 子系统2 屏幕
 * 用于画面显示
 */
class Screen {
    private boolean isRun;

    public void on() {
        if (!isRun) {
            isRun = true;
            System.out.println("开启显示屏");
        }
    }

    public void off() {
        if (isRun) {
            isRun = false;
            System.out.println("关闭显示屏");
        }
    }
}

/**
 * 子系统1 DVD
 * 用于读取光盘
 */
class DVD {
    private boolean isOpen;
    private boolean hasCD;
    private boolean isScanning;

    public boolean isScanning() {
        return isScanning;
    }

    public void on() {
        if (!isOpen) {
            isOpen = true;
            System.out.println("打开DVD");
        }
    }

    public void put() {
        if (!hasCD) {
            hasCD = true;
            System.out.println("放入光碟");
        } else {
            System.out.println("已经有光盘了");
        }
    }

    public void take() {
        if (hasCD) {
            hasCD = false;
            System.out.println("取出光碟");
        } else {
            System.out.println("DVD中不存在光盘");
        }
    }

    public void scan() {
        if (!isScanning) {
            isScanning = true;
            System.out.println("DVD读取光盘");
        }
    }

    public void pause() {
        if (isScanning) {
            isScanning = false;
            System.out.println("DVD暂停读取光盘");
        }
    }

    public void off() {
        if (isOpen) {
            isOpen = false;
            System.out.println("关闭DVD");
        }
    }
}

/**
 * 抽象门面:电影播放门面接口
 */
interface MovieFacade {
    /**
     * 播放电影
     */
    void playMovie();

    /**
     * 暂停电影播放
     */
    void pauseMovie();

    /**
     * 关闭电影播放
     */
    void closeMovie();
}

/**
 * 具体门面:电影播放门面实现类
 */
class MovieFacadeConcrete implements MovieFacade {
    private DVD dvd = new DVD();
    private SoundBox soundBox = new SoundBox();
    private Screen screen = new Screen();

    @Override
    public void playMovie() {
        // 开启各个设备
        dvd.on();
        soundBox.on();
        screen.on();
        // 放入光碟
        dvd.put();
        // 读取光碟
        dvd.scan();
    }

    @Override
    public void pauseMovie() {
        if (dvd.isScanning()) {
            dvd.pause();
        } else {
            dvd.scan();
        }
    }

    @Override
    public void closeMovie() {
        // 暂停读取后再取出光盘
        if (dvd.isScanning()) {
            dvd.pause();
        }
        dvd.take();
        // 关闭各个设备
        screen.off();
        soundBox.off();
        dvd.off();
    }
}

/**
 * 客户端
 */
public class MovieClient {
    public static void main(String[] args) {
        MovieFacade movie = new MovieFacadeConcrete();
        movie.playMovie();// 开启设备并播放电影
        System.out.println("----------------");
        movie.pauseMovie();// 暂停播放
        System.out.println("----------------");
        movie.pauseMovie();// 继续播放
        System.out.println("----------------");
        movie.closeMovie();// 停止播放电影并关闭设备

        /*
         * 打开DVD
         * 开启音箱
         * 开启显示屏
         * 放入光碟
         * DVD读取光盘
         * ----------------
         * DVD暂停读取光盘
         * ----------------
         * DVD读取光盘
         * ----------------
         * DVD暂停读取光盘
         * 取出光碟
         * 关闭显示屏
         * 关闭DVD
         */
    }
}

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值