Java设计模式——外观模式

⚪外观模式(Facade)是一种结构型设计模式,外观模式通过引入一个外观类来隐藏系统的复杂性,使客户端不需要了解子系统的内部工作细节。

⚪意图:为复杂的子系统提供一个简化的接口,以便客户端可以更容易地与子系统交互。

⚪以下是工厂方法模式的关键要点:

        ▷ 角色和责任

  1. 外观(Facade):这是外观模式的核心,提供了一个简化的接口,它知道如何与一个或多个子系统进行交互。外观将客户端的请求委派给适当的子系统对象。
  2. 子系统(Subsystem):子系统是完成实际工作的一组类或对象。外观模式的目标是将客户端与这些子系统的复杂性隔离开来。

        ▷ 工作流程

  1. 客户端通过外观类访问子系统。
  2. 外观类将客户端的请求转发给一个或多个子系统。
  3. 子系统执行请求,并将结果返回给外观类。
  4. 外观类将结果返回给客户端。

        ▷ 示例

// 子系统:音响系统
class Amplifier {
    void on() {
        System.out.println("Amplifier is on");
    }

    void setVolume(int volume) {
        System.out.println("Setting volume to " + volume);
    }
}

// 子系统:投影仪
class Projector {
    void on() {
        System.out.println("Projector is on");
    }

    void setInput(String input) {
        System.out.println("Setting input to " + input);
    }
}

// 子系统:DVD 播放器
class DVDPlayer {
    void on() {
        System.out.println("DVD Player is on");
    }

    void play(String movie) {
        System.out.println("Playing movie: " + movie);
    }
}

// 外观类:家庭影院外观
class HomeTheaterFacade {
    private Amplifier amplifier;
    private Projector projector;
    private DVDPlayer dvdPlayer;

    public HomeTheaterFacade(Amplifier amp, Projector projector, DVDPlayer dvd) {
        this.amplifier = amp;
        this.projector = projector;
        this.dvdPlayer = dvd;
    }

    void watchMovie(String movie) {
        System.out.println("Get ready to watch a movie...");
        amplifier.on();
        amplifier.setVolume(5);
        projector.on();
        projector.setInput("DVD");
        dvdPlayer.on();
        dvdPlayer.play(movie);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        // 创建子系统对象
        Amplifier amplifier = new Amplifier();
        Projector projector = new Projector();
        DVDPlayer dvdPlayer = new DVDPlayer();

        // 创建外观对象
        HomeTheaterFacade facade = new HomeTheaterFacade(amplifier, projector, dvdPlayer);

        // 使用外观启动电影
        facade.watchMovie("The Shawshank Redemption");
    }
}

⚪适用性

  1. 要为一个复杂子系统提供一个简单接口时,子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类,这使得子系统更具有可重用性,也更容易对子系统进行定制,但也给那些不需要定制子系统的用户带米一些使用上的困难。Facade 可以提供一个简单的默认视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过 Facade 层。
  2. 客户程序与抽象类的实现部分之间存在若很大的依赖性。引入 Facade 将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
  3. 当需要构建一个层次结构的子系统时,使用 Facade 模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,则可以让它们仅通过 Facade 进行通信,从而简化了它们之间的依赖关系。

⚪应用场景

  1. 简化复杂系统的接口:当一个系统非常复杂,包含多个子系统或组件,而客户端希望能够以更简单的方式与系统交互时,外观模式非常有用。它提供了一个统一的接口,隐藏了系统内部的复杂性。
  2. 解耦客户端和子系统:外观模式可以将客户端与子系统解耦,使得客户端不需要了解子系统的内部结构,从而降低了耦合度。
  3. 提供更高级的接口:外观模式可以为客户端提供更高级别的接口,使得客户端更容易使用系统,而不必处理系统的底层细节。

⚪实际已有场景

  1. Java API中的应用:Java标准库中包含了许多使用外观模式的类和接口。例如,Java的网络通信API(如java.net包)提供了URLConnection类,它是一个外观,用于简化与各种网络协议的通信。客户端可以使用URLConnection来发送HTTP请求,而无需了解底层协议的复杂性。
  2. Spring框架中的应用:Spring框架本身使用了外观模式来隐藏底层的复杂性。例如,Spring的ApplicationContext接口就是一个外观,它简化了Spring容器的配置和使用,使得开发者可以更容易地管理依赖注入和应用程序的组件。
  3. Spring Security:Spring Security是Spring家族中的一个子项目,用于处理应用程序的安全性。它提供了一个外观,简化了身份验证和授权过程,使得开发人员可以更轻松地集成安全功能到他们的应用程序中。
  4. Spring Data:Spring Data是Spring家族中的另一个子项目,用于简化数据访问层的开发。它提供了外观类和接口,使得开发人员可以使用一种通用的方式与各种数据存储(如关系数据库、NoSQL数据库)进行交互,而不必关心底层数据访问的细节。
posted @ 2023-10-04 10:31  xiaogh  阅读(61)  评论(0)    收藏  举报