结构型设计模式03-外观模式

news2024/10/7 6:50:10

✨作者:猫十二懿

❤️‍🔥账号:CSDN 、掘金 、个人博客 、Github

🎉公众号:猫十二懿

外观模式(门面模式)

1、外观模式介绍

外观模式(Facade Pattern),也称门面模式,是一种结构型设计模式,它==为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用,==从而使子系统更易用、更易懂、更易扩展。

外观模式的核心思想是封装,即将一组复杂的类或接口封装在一个外观类中,客户端只与外观类进行交互,而不直接与复杂的子系统进行交互。外观类隐藏了子系统的复杂性,客户端只需要知道如何使用外观类提供的接口即可。

1.2 外观模式结构图

image-20230423224113890

四个子系统的类:

外观类:

客户端调用:

image-20230423224238714

对于面向对象有一定基础的朋友,即使没有听说过外观模式,也完全有可能在很多时候使用它,因为它完美地体现了依赖倒转原则和迪米特法则的思想

2、案例说明

例子:牛市股票,购买不同的股票、债卷等(不是教大家去炒股哦,禁止黄赌毒!!!

2.1 不使用外观模式

先来看看这个炒股程序的UML 类图

image-20230423221609095

具体实现程序:

/**
 * @author Shier
 * CreateTime 2023/4/23 22:18
 */
public class FacadeTest {
    public static void main(String[] args) {
        Stock1 stock1 = new Stock1();
        Stock2 stock2 = new Stock2();
        NationDebt1 nationDebt = new NationDebt1();
        Realty1 realty1 = new Realty1();
        // 用户需要了解了股票这些的情况,并且参与了这些项目的具体买和卖,之间的耦合性高
        realty1.buy();
        stock2.buy();
        stock1.buy();
        nationDebt.buy();

        stock1.sell();
        stock2.sell();
        nationDebt.sell();
        realty1.sell();
    }
}
// 股票一
class Stock1{
    // 卖股票
    public void sell(){
        System.out.println("股票一售出");
    }
    //买股票
    public void buy(){
        System.out.println("股票一买入");
    }
}
// 股票二
class Stock2{
    // 卖股票
    public void sell(){
        System.out.println("股票二售出");
    }
    //买股票
    public void buy(){
        System.out.println("股票二买入");
    }
}
// 国债一
class NationDebt1{
    // 卖国债
    public void sell(){
        System.out.println("国债一售出");
    }
    //买国债
    public void buy(){
        System.out.println("国债一买入");
    }
}

// 房地厂一
class Realty1{
    // 卖房地厂
    public void sell(){
        System.out.println("房地产一售出");
    }
    // 买房地厂
    public void buy(){
        System.out.println("房地厂一买入");
    }
}

由于众多投资者对众多股票的联系太多,反而不利于操作,导致了耦合性过高。

2.2 使用外观模式

再来修改投资的UML 结构类图

image-20230423222923354

基金类:

package com.shier.facade;

import java.util.Scanner;

/**
 * @author Shier
 * CreateTime 2023/4/23 22:30
 * 买入卖出的操作在基金类完成,就不用用户关心
 * 也就是说基金类需要了解到市场股票等项目的买入卖出情况,以备用户知道
 */
public class Fund {
    Stock1 stock1;
    Stock2 stock2;
    NationDebt1 nationDebt1;
    Realty1 realty1;

    public Fund() {
        stock1 = new Stock1();
        stock2 = new Stock2();
        nationDebt1 = new NationDebt1();
        realty1 = new Realty1();
    }

    //基金类购买
    public void buyFund() {
        stock1.buy();
        stock2.buy();
        nationDebt1.buy();
        realty1.buy();
    }
    //基金类销售
    public void sellFund() {
        stock1.sell();
        stock2.sell();
        nationDebt1.sell();
        realty1.sell();
    }
}

客户端调用基金类的买入卖出:

/**
 * @author Shier
 * CreateTime 2023/4/23 22:18
 */
public class FacadeTest {
    public static void main(String[] args) {
        Fund fund = new Fund();
        // 基金完成购买
        fund.buyFund();
        // 基金赎回
        fund.sellFund();
    }
}

其他的股票等类就不要再去修改了。

最后的结果:

image-20230423223636413

而有了基金以后,变成众多用户只和基金打交道,关心基金的上涨和下跌就可以了,而实际上的操作却是基金经理人在与上千支股票和其他投资产品打交道。

这样就通过了基金类完成了所有的买入卖出操作,用户就不要再去关心那么多信息,降调了耦合度。

3、总结

3.1 何时使用外观模式

  1. 在设计初期阶段,应该要有意识地将不同的两个层分离。比如经典的三层架构,就需要考虑在数据访问层和业务逻辑层、业务逻辑层和表示层的层与层之间建立外观Facade,这样可以为复杂的子系统提供一个简单的接口,使得耦合大大降低。
  2. 在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂。大多数的模式使用时也都会产生很多很小的类,这本是好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观Facade可以提供一个简单的接口,减少它们之间的依赖。
  3. 在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为它包含非常重要的功能,新的需求开发必须要依赖于它。此时用外观模式Facade也是非常合适的。

为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。

3.2 外观模式优缺点

外观模式的优点包括:

  1. 简化了客户端代码:外观模式提供了一个统一的接口,客户端只需要调用外观类提供的方法即可完成复杂的操作,避免了直接调用多个子系统类的情况,从而简化了客户端代码。

  2. 降低了耦合度:由于外观模式将客户端与子系统解耦,使得子系统的变化对客户端的影响降到最低,从而提高了系统的可维护性、可扩展性和灵活性。

  3. 隐藏了复杂性:外观模式将复杂的子系统封装在外观类中,客户端不需要了解子系统的实现细节,从而降低了系统的复杂度,让客户端能够更加轻松地使用该系统。

外观模式的缺点包括:

  1. 不能很好地限制客户端使用子系统类:由于外观模式只是封装了一部分子系统的功能,而并未限制客户端直接使用子系统类,所以客户端可能会绕过外观类直接使用子系统类,从而导致系统的混乱和不稳定。

  2. 增加了系统的复杂度:外观模式需要增加一个外观类来封装子系统,这样就会增加系统的复杂度和代码量。

3.3 外观模式适用情况

  1. 当一个复杂的子系统需要被简化并分层时,可以使用外观模式来定义其关键子系统之间的接口,从而保证它们之间的协作和互操作。

  2. 当客户端与一个复杂的子系统的通信过程较为复杂时,可以使用外观模式来隐藏子系统的复杂性,以便客户端能够更加轻松地与该系统进行通信。

  3. 当需要将一个复杂的系统划分为多个子系统时,可以使用外观模式来分别定义这些子系统之间的关系和通信方式,从而让系统更加可维护和易扩展。

在外观模式中,关键角色包括外观类(Facade)、子系统类(Subsystem)、客户端(Client)等。其中,外观类是使用该模式的核心,它封装了子系统的各种复杂操作,并向客户端提供简单的接口。客户端只需要调用外观类的接口,就可以完成相应的操作。子系统类则是实现了各种具体操作的类,外观类会调用子系统类来完成实际的业务逻辑。

要将一个复杂的系统划分为多个子系统时,可以使用外观模式来分别定义这些子系统之间的关系和通信方式,从而让系统更加可维护和易扩展。

在外观模式中,关键角色包括外观类(Facade)、子系统类(Subsystem)、客户端(Client)等。其中,外观类是使用该模式的核心,它封装了子系统的各种复杂操作,并向客户端提供简单的接口。客户端只需要调用外观类的接口,就可以完成相应的操作。子系统类则是实现了各种具体操作的类,外观类会调用子系统类来完成实际的业务逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/593268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

外贸高手揭秘:心理学在谈判中的秘密武器!

在我看来,谈判与心理学密切相关,研究谈判就是研究心理学!大学期间,我几乎读完了所有的心理学著作,我必须承认,这为我后来的外贸谈判打下了良好的基础。 有人说:为什么要用谈判这个词?这只是一个…

go语言学习——2.x

文章目录 控制结构if-elseswitchfor(range)break和continue标签与goto 函数参数与返回值传递变长参数defer内置函数递归函数函数作为参数闭包计算函数的执行时间 控制结构 if-else if condition{//do something }if condition{//do something }else{//do something }if condi…

SpringMVC03:Restfule和控制器

目录 一、控制器Controller 二、实现controller接口 三、使用注解Controller 四、RequestMappinng 五、RestFul风格 六、学习测试 1.再新建一个类RestfulController 2.在SPring MVC种可以使用PathVariable注解,让方法参数的值对应绑定到一个URI模板变量上。…

【hello C++】类和对象(中)

目录 1. 类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3. 析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 5.3 前置和后置重载 7.const成员 8.取地址及const取地址操作符重载 类和对象&#x1f337…

《Java并发编程实战》课程笔记(六)

管程:并发编程的万能钥匙 什么是管程 Java 采用的是管程技术,synchronized 关键字及 wait()、notify()、notifyAll() 这三个方法都是管程的组成部分。 管程和信号量是等价的,所谓等价指的是用管程能够实现信号量,也能用信号量实…

通用AppKey签名验证软件

一、 需求说明 签名验证是一种技术,用于确保数据完整性和身份验证。在Java应用程序中,签名通常是由开发人员提供的一个字符串,它基于请求的内容和一些密钥信息生成。这个签名可以被认为是一种指纹,它唯一地标识了请求的内容&…

BLECommonTool通用测试工具介绍

工具下载地址:BLECommonTool通用工具资源-CSDN文库 大家在使用过程中,如有发现bug或有更好的建议,欢迎留言或发我QQ邮箱:1255033066qq.com. 工具界面 以下是关于GMBLETool工具的详细使用说明: 蓝牙适配器状态检测&…

springcloudAlibaba整合knife4j整合swagger整合gateway,并且同步到Yapi上

springcloudAlibaba整合knife4j整合swagger整合gateway&#xff0c;并且同步到Yapi上 1.gateway模块 1.pom引入 <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version&g…

什么是七专,电子元器件分级详细总结

🏡《电子元器件高级指南》 目录 0,概述1,商业级元器件2,工业级元器件3,汽车工业级元器件4,七专级元器件5,军级元器件6,航天级元器件0,概述 随着科学技术的发展,以及集成电路技术的不断进步。电子元器件的应用越来越广泛。在不同的应用场景下,往往需要不同等级的电子…

(双指针 ) 15. 三数之和 ——【Leetcode每日一题】

❓15. 三数之和 难度&#xff1a;中等 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a…

pip安装python库速度慢、失败及超时报错解决办法

背景&#xff1a; 随着人工智能的不断兴起&#xff0c;python作为最接近人工智能的语言&#xff0c;变得越来越流行&#xff0c;人生苦短&#xff0c;python要学起来。之所以越来用的人喜欢学习python和研究Python&#xff0c;除了python本身便于学些、语法简短、面向对象等特点…

静态库与动态库的区别

静态库与动态库的区别 静态库动态库 首先用OpenCV的开源库来举个例子了解一下库文件的分类&#xff1a; bin文件夹里面放的都是dll文件&#xff1b; lib文件夹里面放的都是伴随dll文件的动态lib文件&#xff1b; staticlib文件夹里面放的才是真正的静态lib文件&#xff0c;和…

专利费减备案操作流程——让你申请专利时的官费大大打折

【系列专栏】&#xff1a;博主结合工作实践输出的&#xff0c;解决实际问题的专栏&#xff0c;朋友们看过来&#xff01; 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C语言开发基础总结》 《从0到1学习嵌入式Linux开发》 《QT开发实战》 《Android开发实…

【为什么控件的引用和控件的代理要用weak Objective-C语言】

一、还记得我们给大家说过,UI控件,当用一个属性,引用UI控件的时候,那个标记要用weak, 1.为什么,但是用strong,是不是也行, 但是,如果是控件的代理对象,是不是一定得用weak, 我现在就告诉你,为什么, 注意听,现在,比如说,这个是控制器, 我先解释,为什么UI控…

Java实战-基于JDK的LRU算法实现、优雅的实现代码耗时统计(Spring AOP、AutoCloseable方式)

场景 Java中基于JDK的LRU算法实现 LRU算法-缓存淘汰算法-Least recently used,最近最少使用算法 根据数据的历史访问记录来进行淘汰数据&#xff0c;其核心思想是&#xff1a;如果有数据最近被访问过&#xff0c;那么将来被访问的几率也更高 在Java中可以利用LinkedHashMap…

34. Linux系统下打包qt应用程序

1. 说明 对程序进行打包前需要在Release模式对程序代码进行编译,然后得到编译后的可执行文件,正常情况下这个可执行文件是可以双击打开运行的,如果无法双击运行,可在**.pro**文件内加入下面的代码: QMAKE_LFLAGS += -no-pie TEMPLATE = app同时将main.qml文件中的Window…

【总结】对接达梦数据库DM8详细教程

目录 1.达梦数据库-技术文档2.软件安装包下载2.1 iso 安装版2.2 docker 安装版 3.DM8单机安装部署规范4.安装操作步骤4.1 安装docker4.2 docker安装dameng&#xff08;推荐&#xff09; 5. 启动/停止数据库6.客户端连接使用7.DDL SQL实践7.1 创建表空间7.2 建表语句 8.DML SQL实…

「2023大学生就业报告 」出炉,应届生都去了哪些行业?

2023年的应届毕业生人数再创新高&#xff0c;达到1158万人&#xff0c;是不是开始担忧他们的就业了&#xff1f;别急&#xff0c;最近Boss直聘发布的一组数据&#xff0c;会让这样的担忧有所缓解。 期望薪资有所下降 和增长明显的毕业人数相反的是&#xff0c;这一届大专、本…

网络流量监控及流量异常检测

当今的企业面临着许多挑战&#xff0c;尤其是在监控其网络基础设施方面&#xff0c;需要确保随着网络规模和复杂性的增长&#xff0c;能够全面了解网络的运行状况和安全性。为了消除对网络性能的任何压力&#xff0c;组织应该采取的一项重要行动是使用随组织一起扩展的工具监控…

探究工业设备状态监测的典型对象和常用方法

工业设备状态监测的目的是实时掌握设备的健康状况&#xff0c;及时发现潜在故障迹象&#xff0c;并采取相应的维修和维护措施。通过有效的状态监测&#xff0c;企业可以降低设备故障风险&#xff0c;减少计划外停机时间&#xff0c;提高生产效率&#xff0c;节约维护成本&#…