设计模式之外观模式

设计模式中的外观模式(Facade Pattern)是一种简化系统接口的模式,它通过提供一个统一的高层接口来访问子系统中的一群接口。这种模式可以提高系统的可维护性和可扩展性,同时降低了客户端与多个子系统之间的耦合度。下面是一个详细的介绍和Java代码示例,该示例描述了一个家庭影院系统,包括电视、DVD播放机、立体声音响等多个组件,以及一个外观类来简化这些组件的操作。

一、外观模式的作用

外观模式主要用于以下几种情况:

1、简化接口

当一个系统变得非常复杂,并且客户端需要一个简单的接口来与之交互。

2、降低依赖

通过引入外观类,可以减少系统之间的依赖性。

3、封装变化

如果子系统中的接口发生变化,可以通过调整外观类来应对,而不需要改变客户端代码。

4、遵循迪米特法则

一个软件实体应当尽可能少地与其他实体发生相互作用。

二、外观模式的角色

1、子系统类(Subsystem Classes):

它们可以接受请求。

2、外观类(Facade Class):

提供一个简单的接口给客户端。

三、java代码示例

1、子系统类定义

首先定义各个子系统类:

java 复制代码
public class DVDPlayer {
    private String description;

    public DVDPlayer(String description) {
        this.description = description;
    }

    public void on() {
        System.out.println(description + " 开启");
    }

    public void off() {
        System.out.println(description + " 关闭");
    }

    public void eject() {
        System.out.println(description + " 弹出光盘");
    }

    public void playMovie(String movie) {
        System.out.println(description + " 播放电影 " + movie);
    }
}

public class TV {
    private String description;

    public TV(String description) {
        this.description = description;
    }

    public void on() {
        System.out.println(description + " 开启");
    }

    public void off() {
        System.out.println(description + " 关闭");
    }

    public void setChannel(int channel) {
        System.out.println(description + " 设置频道到 " + channel);
    }
}

public class Amplifier {
    private String description;

    public Amplifier(String description) {
        this.description = description;
    }

    public void on() {
        System.out.println(description + " 开启");
    }

    public void off() {
        System.out.println(description + " 关闭");
    }

    public void setVolume(int level) {
        System.out.println(description + " 设置音量到 " + level);
    }
}

public class PopcornPopper {
    private String description;

    public PopcornPopper(String description) {
        this.description = description;
    }

    public void on() {
        System.out.println(description + " 开启");
    }

    public void off() {
        System.out.println(description + " 关闭");
    }

    public void pop() {
        System.out.println(description + " 开始爆米花制作");
    }
}

2、外观类定义

接下来定义一个遥控器的外观类,用来简化用户对家庭影院系统的操作:

java 复制代码
public class HomeTheaterFacade {
    private DVDPlayer dvdPlayer;
    private TV tv;
    private Amplifier amplifier;
    private PopcornPopper popcornPopper;

    public HomeTheaterFacade(DVDPlayer dvdPlayer, TV tv, Amplifier amplifier, PopcornPopper popcornPopper) {
        this.dvdPlayer = dvdPlayer;
        this.tv = tv;
        this.amplifier = amplifier;
        this.popcornPopper = popcornPopper;
    }

    public void watchMovie(String movie) {
        System.out.println("准备观看电影 " + movie);
        popcornPopper.on();
        popcornPopper.pop();
        dvdPlayer.on();
        dvdPlayer.playMovie(movie);
        tv.on();
        tv.setChannel(1); // 假设频道1是HDMI输入
        amplifier.on();
        amplifier.setVolume(5);
    }

    public void endMovie() {
        System.out.println("电影结束,关闭所有设备...");
        popcornPopper.off();
        dvdPlayer.off();
        tv.off();
        amplifier.off();
    }
}

3、使用外观模式

最后,在主程序中使用这个外观模式:

java 复制代码
public class HomeTheaterTestDrive {
    public static void main(String[] args) {
        DVDPlayer dvdPlayer = new DVDPlayer("DVD播放机");
        TV tv = new TV("电视机");
        Amplifier amplifier = new Amplifier("音响");
        PopcornPopper popcornPopper = new PopcornPopper("爆米花机");

        HomeTheaterFacade homeTheater = new HomeTheaterFacade(dvdPlayer, tv, amplifier, popcornPopper);

        homeTheater.watchMovie("Matrix");
        homeTheater.endMovie();
    }
}

4、详细解释

在这个家庭影院系统中,我们有四个主要的组件:DVD播放机、电视机、立体声音响以及爆米花机。每个组件都有自己的开关、播放等功能。如果我们想要看一部电影,我们需要分别操作这些设备,这可能会很麻烦。因此,我们创建了一个HomeTheaterFacade类来简化这个过程。
HomeTheaterFacade类充当了客户端和子系统之间的中介者,它负责协调子系统中的各个部分,以便客户端可以通过一个简单的接口来控制整个家庭影院系统。这样做的好处是显而易见的:首先,客户端的代码变得更简单,因为它们只需要与一个对象打交道;其次,如果未来需要更改子系统的行为,只需要修改HomeTheaterFacade类,而不需要改动客户端代码。

四、扩展

在现实世界的应用中,外观模式是非常有用的。例如,在一个大型企业级应用程序中,可能有许多不同的模块和服务,每个模块都有一组复杂的API。对于外部用户来说,直接使用这些API可能是困难的。这时候就可以使用外观模式来提供一个友好的接口,使得外部用户可以更容易地使用这些服务。

此外,外观模式还可以用来实现分层的设计。例如,在一个Web应用程序中,前端页面可能需要从多个后端服务获取数据。通过创建一个外观层,可以将这些服务的调用抽象化,使得前端页面只需要与一个统一的服务接口进行交互,而不需要关心具体的数据是从哪里来的。

五、总结

外观模式过提供一个统一的接口来简化对多个子系统的调用,从而使得系统的使用变得更加容易。在实际项目中,您可以根据需要扩展更多子系统以及它们的功能,从而减少代码的复杂度和长度。

相关推荐
桦说编程2 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
lifallen2 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研2 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
快乐的划水a3 小时前
组合模式及优化
c++·设计模式·组合模式
没有bug.的程序员3 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
甄超锋4 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Zyy~4 小时前
《设计模式》装饰模式
java·设计模式
A尘埃4 小时前
企业级Java项目和大模型结合场景(智能客服系统:电商、金融、政务、企业)
java·金融·政务·智能客服系统
青云交4 小时前
Java 大视界 -- 基于 Java 的大数据可视化在城市交通拥堵治理与出行效率提升中的应用(398)
java·大数据·flink·大数据可视化·拥堵预测·城市交通治理·实时热力图