23种设计模式之外观模式

目录

  • [1. 简介](#1. 简介)
  • [2. 代码](#2. 代码)
    • [2.1 SelectFoodService (选择食品)](#2.1 SelectFoodService (选择食品))
    • [2.2 PayService (支付服务)](#2.2 PayService (支付服务))
    • [2.3 TakeService (制作服务)](#2.3 TakeService (制作服务))
    • [2.4 OrderService (下单服务)](#2.4 OrderService (下单服务))
    • [2.5 Food (食品)](#2.5 Food (食品))
    • [2.6 TackingSystem (外观类)](#2.6 TackingSystem (外观类))
    • [2.7 Test (测试类)](#2.7 Test (测试类))
  • [3. 优缺点](#3. 优缺点)
  • [3. 总结](#3. 总结)

1. 简介

外观模式是一种结构型设计模式。它为子系统中的一组接口提供了一个统一的高层接口,这个高层接口使得子系统更容易使用。就好像给一个复杂的机器(子系统)安装了一个简单的控制面板(外观类),用户通过操作这个控制面板就能轻松地使用机器的各种功能,而不需要了解机器内部复杂的结构和各个部件(子系统中的接口)是如何协同工作的。

例如,考虑一个计算机系统,它包含了 CPU、硬盘、内存等多个组件,每个组件都有自己复杂的操作接口。通过外观模式,可以创建一个 "计算机启动" 外观类,它内部封装了 CPU 初始化、硬盘加载系统文件、内存自检等操作。用户只需要调用 "计算机启动" 这个简单的操作,而不用去分别调用每个组件的复杂操作。

外观模式的结构组成

  • 外观类(Facade Class
    这是外观模式的核心。外观类知道哪些子系统类负责处理请求,并将客户的请求代理给适当的子系统对象。它简化了与子系统的交互方式,对外提供了一个更加简单、统一的接口。例如,在上述计算机启动的例子中,"计算机启动" 类就是外观类。
  • 子系统类(Sub - system Classes
    这些是实现具体功能的类,它们各自负责一个特定的、复杂的功能部分。在计算机系统中,CPU 类、硬盘类、内存类等都是子系统类。它们本身的操作可能很复杂,但外观类会对它们进行整合,使得用户不需要直接接触这些复杂的操作。

2. 代码

这里用点餐系统举例子。

2.1 SelectFoodService (选择食品)

java 复制代码
public class SelectFoodService {
    public void select(String foodName){
        System.out.println("正在选择" + foodName + "。。。");
    }
}

2.2 PayService (支付服务)

java 复制代码
public class PayService {
    public void pay(){
        System.out.println("正在支付。。。");
    }

    public boolean checkBanlance(){
        System.out.println("正在检查用户余额。。。");
        return true;
    }
}

2.3 TakeService (制作服务)

java 复制代码
public class TakeService {
    public void taking(){
        System.out.println("正在制作外卖。。。");
    }
}

2.4 OrderService (下单服务)

java 复制代码
public class OrderService {
    public void makeOrder(){
        System.out.println("正在下单。。。");
    }
}

2.5 Food (食品)

java 复制代码
public class Food {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2.6 TackingSystem (外观类)

java 复制代码
public class TackingSystem {
    private SelectFoodService selectFoodService;

    private PayService payService;

    private OrderService orderService;

    private TakeService takeService;

    public TackingSystem(){
        selectFoodService = new SelectFoodService();
        payService = new PayService();
        orderService = new OrderService();
        takeService = new TakeService();
    }
    public void orderTacking(Food food){
        // 点餐
        selectFoodService.select(food.getName());
        // 校验余额
        boolean isPay = payService.checkBanlance();
        // 支付
        if(isPay){
            payService.pay();
            takeService.taking();
            orderService.makeOrder();
        }
    }
}

2.7 Test (测试类)

java 复制代码
public class Test {
    public static void main(String[] args) {
        Food food = new Food();
        food.setName("西红柿鸡蛋面");
        TackingSystem tackingSystem = new TackingSystem();
        tackingSystem.orderTacking(food);
    }
}

输出结果:

正在选择西红柿鸡蛋面。。。
正在检查用户余额。。。
正在支付。。。
正在制作外卖。。。
正在下单。。。

3. 优缺点

外观模式的优点

  • 简化接口
    为复杂的子系统提供了一个简单的、统一的接口,降低了客户端与子系统之间的耦合度。客户端只需要和外观类交互,不需要了解子系统内部的复杂细节,就像在家庭影院系统中,用户只需要通过外观类的 "watchMovie" 和 "endMovie" 方法就能轻松控制整个系统,而不用分别去操作每个设备。
  • 提高可维护性和可扩展性
    当子系统内部的结构和功能发生变化时,只要外观类的接口保持不变,客户端代码就不需要修改。例如,如果要升级 DVD 播放器的内部软件,只要它的 "turnOn" 和 "turnOff" 接口不变,外观类和客户端代码都不需要调整。同时,新的子系统可以很容易地添加到外观类中,方便系统的扩展。
  • 实现了层次隔离
    外观模式可以将系统的高层逻辑和底层实现分离开来。高层逻辑通过外观类来体现,底层的子系统则负责具体的功能实现。这种层次隔离使得代码的结构更加清晰,便于不同层次的开发人员分别进行开发和维护。

外观模式的缺点

  • 不符合开闭原则的潜在风险
    如果外观类的接口需要修改,可能会影响到所有使用该外观类的客户端。因为外观类是客户端和子系统之间的桥梁,一旦这个桥梁的接口发生变化,就可能需要修改客户端代码。例如,如果要在家庭影院系统的外观类中添加一个新的功能,如 "暂停电影",那么所有使用这个外观类的客户端代码可能都需要相应地修改,这在一定程度上不符合开闭原则(对扩展开放,对修改关闭)。
  • 外观类可能会变得过于复杂
    如果子系统本身非常庞大和复杂,外观类需要整合大量的子系统接口,那么外观类可能会变得臃肿和复杂。这可能会导致外观类的维护成本增加,而且可能会降低代码的可读性。例如,一个大型企业级软件系统的外观类,如果要整合众多的子系统,如数据库管理系统、消息队列系统、文件存储系统等,外观类的代码可能会变得非常复杂。

3. 总结

其实就是定义多个子系统,一个总系统,随后总系统初始化多个子系统,然后使用就行了。

相关推荐
IT古董40 分钟前
【权限管理】Apache Shiro学习教程
java·apache·shiro·权限
风月歌42 分钟前
基于Spring Boot的海滨体育馆管理系统的设计与实现
java·spring boot·后端
ggdpzhk5 小时前
idea 编辑竖列:alt +shift+insert
java·ide·intellij-idea
hikktn5 小时前
Java 兼容读取WPS和Office图片,结合EasyExcel读取单元格信息
java·开发语言·wps
迪迦不喝可乐5 小时前
软考 高级 架构师 第十一章 面向对象分析 设计模式
java·设计模式
檀越剑指大厂6 小时前
【Java基础】使用Apache POI和Spring Boot实现Excel文件上传和解析功能
java·spring boot·apache
苹果酱05676 小时前
Golang的网络流量分配策略
java·spring boot·毕业设计·layui·课程设计
孑么6 小时前
GDPU Android移动应用 重点习题集
android·xml·java·okhttp·kotlin·android studio·webview
苹果7 小时前
C++二十三种设计模式之迭代器模式
c++·设计模式·迭代器模式
silver6877 小时前
迭代器模式详解
设计模式