09.外观模式设计思想

09.外观模式设计思想

目录介绍
  • 01.外观模式基础
    • 1.1 外观模式由来
    • 1.2 外观模式定义
    • 1.3 外观模式场景
    • 1.4 外观模式思考
    • 1.5 解决的问题
  • 02.外观模式实现
    • 2.1 罗列一个场景
    • 2.2 外观结构
    • 2.3 外观基本实现
    • 2.4 有哪些注意点
    • 2.5 设计思想
  • 03.外观实例演示
    • 3.1 需求分析
    • 3.2 代码案例实现
    • 3.3 是否可以优化
  • 04.外观模式场景
  • 05.外观模式分析
    • 5.1 外观模式优点
    • 5.2 外观模式缺点
    • 5.3 适用环境
    • 5.4 模式拓展
  • 06.外观代理总结
    • 6.1 总结一下学习
    • 6.2 更多内容推荐

推荐一个好玩网站

一个最纯粹的技术分享网站,打造精品技术编程专栏!编程进阶网

https://yccoding.com/

01.外观模式基础

1.0 本博客AI摘要

外观模式设计思想:为了解决软件系统中的复杂性和耦合性问题,外观模式提供了一组统一的接口,简化客户端与子系统的交互。主要内容包括外观模式的基础、实现、实例演示、应用场景、优缺点及适用环境。通过创建外观类,将复杂系统的内部实现细节隐藏起来,只暴露出简化的接口给客户端,从而降低耦合度,提高系统的可维护性和可扩展性。

1.1 外观模式由来

外观模式的由来是为了解决软件系统中的复杂性和耦合性问题。在大型软件系统中,各个子系统之间可能存在复杂的依赖关系和交互逻辑,这导致了系统的可维护性和可扩展性变得困难。为了简化客户端与子系统之间的交互,外观模式被引入。

门面模式原理和实现都特别简单,应用场景也比较明确,主要在接口设计方面使用。更多内容

1.2 外观模式定义

门面模式,也叫外观模式,英文全称是 Facade Design Pattern。

在 GoF 的《设计模式》一书中,门面模式是这样定义的:Provide a unified interface to a set of interfaces in a subsystem. Facade Pattern defines a higher-level interface that makes the subsystem easier to use.

翻译成中文就是:门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。

外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

1.3 外观模式场景

应用场景:

  1. 医院接待:医院的接待人员简化了挂号、门诊、划价、取药等复杂流程。
  2. Java三层架构:通过外观模式,可以简化对表示层、业务逻辑层和数据访问层的访问。

1.4 外观模式思考

外观模式的核心思想主要是通过创建一个外观类,将复杂系统的内部实现细节隐藏起来,只暴露出一个简化的接口给客户端。客户端只需要与外观类进行交互,而不需要直接与子系统的组件进行交互,从而达到想要的效果。

在思考外观模式时,可以考虑以下几个方面:

  1. 系统的复杂性:外观模式适用于系统的复杂性较高,包含多个子系统或模块的情况。
  2. 客户端的便利性:外观模式旨在提供一个简化的接口给客户端使用,使得客户端可以更方便地使用系统的功能,而不需要了解系统的内部实现细节。
  3. 系统的灵活性和可扩展性:外观模式可以提供系统的灵活性和可扩展性。
  4. 设计的一致性和封装性:外观模式可以提供设计的一致性和封装性。

1.5 解决的问题

主要解决的问题

  1. 降低客户端与复杂子系统之间的耦合度。
  2. 简化客户端对复杂系统的操作,隐藏内部实现细节。更多内容

02.外观模式实现

2.1 罗列一个场景

下面通过一个简单的例子来演示。假设有一个电脑系统,包含了多个子系统,如音乐功能、视频功能和联网功能。可以打开或者关闭某功能。

2.2 外观结构

外观模式包含如下角色:

  1. Facade: 外观角色。提供一个简化的接口,封装了系统的复杂性。外观模式的客户端通过与外观对象交互,而无需直接与系统的各个组件打交道。
  2. SubSystem:子系统角色。由多个相互关联的类组成,负责系统的具体功能。外观对象通过调用这些子系统来完成客户端的请求。
  3. Client:客户端。使用外观对象来与系统交互,而不需要了解系统内部的具体实现。

2.3 外观基本实现

实现方式

  1. 创建外观类:定义一个类(外观),作为客户端与子系统之间的中介。提供Facade接口,抽象出通用方法打开和关闭。
  2. 封装子系统操作:外观类将复杂的子系统操作封装成简单的方法。三个子系统类(Subsystem):音乐功能、视频功能和联网功能

提供一个简化的接口

public interface Facade {void open();void close();
}

创建三个子系统类(Subsystem):音乐功能、视频功能和联网功能。更多内容

public class Music implements Facade{@Overridepublic void open() {System.out.println("加载音乐");}@Overridepublic void stop() {System.out.println("关闭音乐");}
}public class Video implements Facade{@Overridepublic void open() {System.out.println("打开视频");}@Overridepublic void stop() {System.out.println("关闭视频");}
}public class Internet implements Facade{@Overridepublic void open() {System.out.println("连接网络");}@Overridepublic void stop() {System.out.println("断开网络");}
}

创建外观类(Facade) - 电脑系统

public class Computer {private Music music;private Video video;private Internet internet;public Computer() {this.music = new Music();this.video = new Video();this.internet = new Internet();}public void openVideo() {internet.open();music.open();video.open();}public void stopVideo() {video.stop();music.stop();internet.stop();}
}

创建客户端(Client)

private void test() {Computer computer = new Computer();System.out.println("播放视频步骤:");// 播放视频computer.openVideo();System.out.println("关闭视频步骤:");// 关闭视频computer.stopVideo();
}

在上述例子中,音乐功能、视频功能和联网功能是子系统,Computer是外观类,封装了对这些子系统的调用,并提供了简化的接口给客户端。

在客户端中,我们使用外观模式简化了电脑系统的使用。通过调用外观类的方法,客户端无需直接与多个子系统交互,而是通过外观类来管理对子系统的调用。直接一个接口调用打开视频,打开音乐,连接网络功能

该案例中思考:如果不使用外观模式,客户端通常需要和子系统内部的多个模块交互,也就是说客户端会和这些模块之间都有依赖关系,任意一个模块的变动都可能会引起客户端的变动。

使用外观模式后,客户端只需要和外观类交互,即只和这个外观类有依赖关系,不需要再去关心子系统内部模块的变动情况了。更多内容,这样一来,客户端不但简单,而且这个系统会更有弹性。

2.4 有哪些注意点

外观模式并不是为了解决系统的性能问题,而是为了提供一个简化的接口和封装系统的复杂性。在使用外观模式时,需要权衡封装的程度和灵活性,并根据具体的需求和情况做出决策。

2.5 设计思想

比如该案例中:

  1. 针对音乐,视频,联网抽象出通用功能,定义成接口【打开和关闭】。充分体现出面向对象中抽象的设计思想!
  2. 针对音乐,视频,联网各个子系统之间的交互,将他们的逻辑封装到外观类中,充分体现出封装的原则!

外观模式的设计思想是基于封装和抽象的原则,通过将子系统的复杂性隐藏起来,提供一个简化的接口给客户端使用。这样可以提高系统的可维护性、可扩展性和可重用性,同时也使得客户端代码更加简洁和易于理解。

03.外观实例演示

3.1 需求分析

有个需求:我们知道在UI开发中,可以绘制很多图像。比如可以绘制圆形,绘制矩形,绘制椭圆形,绘制……来达到绘制显示的效果。

我们将创建一个 Shape 接口和实现了 Shape 接口的实体类。下一步是定义一个外观类 ShapeMaker。更多内容

3.2 代码案例实现

创建一个接口。

public interface Shape {void draw();
}

创建实现接口的实体类。

public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Rectangle::draw()");}
}public class Square implements Shape {@Overridepublic void draw() {System.out.println("Square::draw()");}
}public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Circle::draw()");}
}

创建一个外观类。

public class ShapeMaker {private Shape circle;private Shape rectangle;private Shape square;public ShapeMaker() {circle = new Circle();rectangle = new Rectangle();square = new Square();}public void drawCircle(){circle.draw();}public void drawRectangle(){rectangle.draw();}public void drawSquare(){square.draw();}
}

使用该外观类画出各种类型的形状。

private void test() {ShapeMaker shapeMaker = new ShapeMaker();shapeMaker.drawCircle();shapeMaker.drawRectangle();shapeMaker.drawSquare();
}

3.3 是否可以优化

比如,现在增加一个需求,绘制各种素材,不管是圆形,矩形,或者椭圆等,都需要创建画笔和画板,可以给绘制设置不同的颜色。如果是你,该如何设计!更多内容

05.外观模式分析

5.1 外观模式优点

  1. 简化接口:外观模式为子系统提供了一个简化的接口,使得调用者无需关心子系统的内部细节和复杂性,降低了系统的学习成本和使用难度。
  2. 降低耦合度:通过引入外观类,子系统与调用者之间的耦合度得到了降低。外观类作为中间层,屏蔽了子系统的具体实现,使得子系统内部的修改不会影响到调用者。
  3. 提高灵活性:由于外观类提供了统一的接口,调用者可以更加灵活地使用子系统,而无需关心子系统的具体实现细节。这有助于增加系统的可扩展性和可维护性。
  4. 易于维护:当子系统内部发生变更时,只需要修改外观类即可,而无需修改所有调用者的代码。这大大降低了系统的维护成本。

5.2 外观模式缺点

  1. 可能违背开闭原则:当需要添加新的子系统功能时,可能需要修改外观类或者增加新的外观类。这在一定程度上违背了开闭原则(即对扩展开放,对修改封闭),可能导致系统的稳定性和可维护性受到影响。
  2. 可能增加不必要的复杂性:在某些情况下,如果子系统本身就很简单或者调用者需要直接访问子系统的某些功能,引入外观模式可能会增加不必要的复杂性。

5.3 适用环境

在以下情况下可以使用外观模式:

  1. 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。
  2. 客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
  3. 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。

5.4 模式拓展

不要试图通过外观类为子系统增加新行为

不要通过继承一个外观类在子系统中加入新的行为,这种做法是错误的。外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,新的行为的增加应该通过修改原有子系统类或增加新的子系统类来实现,不能通过外观类来实现。

外观模式与迪米特法则

外观模式创造出一个外观对象,将客户端所涉及的属于一个子系统的协作伙伴的数量减到最少,使得客户端与子系统内部的对象的相互作用被外观对象所取代。外观类充当了客户类与子系统类之间的“第三者”,降低了客户类与子系统类之间的耦合度,外观模式就是实现代码重构以便达到“迪米特法则”要求的一个强有力的武器。

抽象外观类的引入

外观模式最大的缺点在于违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。

06.外观代理总结

6.1 总结一下学习

01.外观模式基础

外观模式的由来是为了解决软件系统中的复杂性和耦合性问题。在大型软件系统中,各个子系统之间可能存在复杂的依赖关系和交互逻辑,这导致了系统的可维护性和可扩展性变得困难。为了简化客户端与子系统之间的交互,外观模式被引入。

定义是:门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。更多内容

主要解决的问题

  1. 降低客户端与复杂子系统之间的耦合度。
  2. 简化客户端对复杂系统的操作,隐藏内部实现细节。

02.外观模式实现

假设有一个电脑系统,包含了多个子系统,如音乐功能、视频功能和联网功能。可以打开或者关闭某功能。

实现方式

  1. 创建外观类:定义一个类(外观),作为客户端与子系统之间的中介。提供Facade接口,抽象出通用方法打开和关闭。
  2. 封装子系统操作:外观类将复杂的子系统操作封装成简单的方法。三个子系统类(Subsystem):音乐功能、视频功能和联网功能

比如该案例中:

  1. 针对音乐,视频,联网抽象出通用功能,定义成接口【打开和关闭】。充分体现出面向对象中抽象的设计思想!
  2. 针对音乐,视频,联网各个子系统之间的交互,将他们的逻辑封装到外观类中,充分体现出封装的原则!

03.外观实例演示

有个需求:我们知道在UI开发中,可以绘制很多图像。比如可以绘制圆形,绘制矩形,绘制椭圆形,绘制……来达到绘制显示的效果。更多内容

05.外观模式分析

外观模式优点:1.简化接口;2.降低耦合;3.提高灵活性;4.方便维护

外观模式缺点:1.当添加新的子类系统,可能需要修改外观类,或者破坏开闭原则;

使用建议:建议1不要通过外观类给子类系统加入新的行为。

6.2 更多内容推荐

模块描述备注
GitHub多个YC系列开源项目,包含Android组件库,以及多个案例GitHub
博客汇总汇聚Java,Android,C/C++,网络协议,算法,编程总结等YCBlogs
设计模式六大设计原则,23种设计模式,设计模式案例,面向对象思想设计模式
Java进阶数据设计和原理,面向对象核心思想,IO,异常,线程和并发,JVMJava高级
网络协议网络实际案例,网络原理和分层,Https,网络请求,故障排查网络协议
计算机原理计算机组成结构,框架,存储器,CPU设计,内存设计,指令编程原理,异常处理机制,IO操作和原理计算机基础
学习C编程C语言入门级别系统全面的学习教程,学习三到四个综合案例C编程
C++编程C++语言入门级别系统全面的教学教程,并发编程,核心原理C++编程
算法实践专栏,数组,链表,栈,队列,树,哈希,递归,查找,排序等Leetcode
Android基础入门,开源库解读,性能优化,Framework,方案设计Android

23种设计模式

23种设计模式 & 描述 & 核心作用包括
创建型模式
提供创建对象用例。能够将软件模块中对象的创建和对象的使用分离
工厂模式(Factory Pattern)
抽象工厂模式(Abstract Factory Pattern)
单例模式(Singleton Pattern)
建造者模式(Builder Pattern)
原型模式(Prototype Pattern)
结构型模式
关注类和对象的组合。描述如何将类或者对象结合在一起形成更大的结构
适配器模式(Adapter Pattern)
桥接模式(Bridge Pattern)
过滤器模式(Filter、Criteria Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)
外观模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
行为型模式
特别关注对象之间的通信。主要解决的就是“类或对象之间的交互”问题
责任链模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
解释器模式(Interpreter Pattern)
迭代器模式(Iterator Pattern)
中介者模式(Mediator Pattern)
备忘录模式(Memento Pattern)
观察者模式(Observer Pattern)
状态模式(State Pattern)
空对象模式(Null Object Pattern)
策略模式(Strategy Pattern)
模板模式(Template Pattern)
访问者模式(Visitor Pattern)

6.3 更多内容

  • GitHub:https://github.com/yangchong211
  • 我的编程网站:https://yccoding.com
  • 博客汇总:https://github.com/yangchong211/YCBlogs
  • 设计模式专栏:https://github.com/yangchong211/YCDesignBlog
  • Java高级进阶专栏:https://github.com/yangchong211/YCJavaBlog
  • 网络协议专栏:https://github.com/yangchong211/YCNetwork
  • 计算机基础原理专栏:https://github.com/yangchong211/YCComputerBlog

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

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

相关文章

电机轴设计的技术参数研究

电机轴作为电机的关键组件之一,其设计不仅关系到电机的性能和效率,还直接影响到整个机械系统的可靠性与使用寿命。电机轴的设计涉及众多技术参数,这些参数通常包括但不限于尺寸参数、材料选择、强度分析、转动平衡、轴承选择以及制造公差等。…

个人开发三步走

一、开发准备 1.需求分析:需求是开发的起点。第一步要做的就是明确需求,具体来说就是分析目标用户、他们的需求(功能需求、性能需求、安全需求)和痛点。 2.技术选型:综合开发需求、个人能力(能熟练使用&a…

C++ | Leetcode C++题解之第541题反转字符串II

题目&#xff1a; 题解&#xff1a; class Solution { public:string reverseStr(string s, int k) {int n s.length();for (int i 0; i < n; i 2 * k) {reverse(s.begin() i, s.begin() min(i k, n));}return s;} };

一个由Deno和React驱动的静态网站生成器

大家好&#xff0c;今天给大家分享一个由 Deno React 驱动的静态网站生成器Pagic。 项目介绍 Pagic 是一个由 Deno React 驱动的静态网站生成器。它配置简单&#xff0c;支持将 md/tsx 文件渲染成静态页面&#xff0c;而且还有大量的官方或第三方主题和插件可供扩展。 核心…

如何才能实时监测Mac的运行状态

实时监测Mac的运行状态&#xff0c;能够让我们更好的了解Mac的情况&#xff0c;因此如何才能监测Mac的运行状态很重要 State&#xff0c;实时监测你的Mac运行状态&#xff0c;能够直观的展示当前Mac的CPU、内存、硬盘、温度、风扇、网络信息以及开机时间等重要信息 除此之外&a…

BERT的中文问答系统28

为了使GUI界面更加人性化&#xff0c;我们从以下几个方面进行改进&#xff1a; 美化界面&#xff1a;使用更现代的样式和布局&#xff0c;增加图标和颜色。 用户反馈&#xff1a;增加更多的提示信息和反馈&#xff0c;让用户知道当前的操作状态。 功能增强&#xff1a;增加一些…

python之正则表达式总结

正则表达式 对于正则表达式的学习&#xff0c;我整理了网上的一些资料&#xff0c;希望可以帮助到各位&#xff01;&#xff01;&#xff01; 我们可以使用正则表达式来定义字符串的匹配模式&#xff0c;即如何检查一个字符串是否有跟某种模式匹配的部分或者从一个字符串中将与…

练习LabVIEW第三十八题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十八题&#xff1a; 创建一个VI&#xff0c;实现对按钮状态的指示和按钮“按下”持续时间简单计算功能&#xff0c;按…

众测遇到的一些案列漏洞

文章中涉及的敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打码处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行…

nacos快速启动

预备环境准备&#xff1a; 确保是64 bit OS&#xff08;推荐Linux/Unix/Mac&#xff09;&#xff0c;安装64 bit JDK 1.8并下载&配置&#xff0c;安装Maven 3.2.x并下载&配置。 下载源码或者安装包&#xff1a; 从Github上下载源码方式&#xff1a; git clone https://…

CanMV-K230 案例1 DSP框架初版

CanMV-K230的DSP框架 DSP框架一般可以表示为ADC采集——DSP处理——DAC输出 首先&#xff0c;针对上面的框架应该不要限制想象能力&#xff1a; 1&#xff09;ADC可以是采集电压的ADC&#xff0c;也可以是采集声音、振动等&#xff1b; 2&#xff09;DSP只是可以处理DSP功能的…

道可云人工智能元宇宙每日资讯|《河南省推动“人工智能+”行动计划》发布

道可云元宇宙每日简报&#xff08;2024年10月30日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 《河南省推动“人工智能”行动计划&#xff08;2024—2026年&#xff09;》发布 河南省政府办公厅近日印发了《河南省推动“人工智能”行动计划&#xff08;2024—…

C#:强大而优雅的编程语言

在当今的软件开发领域&#xff0c;C#作为一种广泛应用的编程语言&#xff0c;以其强大的功能、优雅的语法和丰富的生态系统&#xff0c;受到了众多开发者的喜爱。本文将深入探讨 C#的各个方面&#xff0c;展示它的魅力和优势。 一、C#的历史与发展 C#是由微软公司开发的一种面…

#渗透测试#SRC漏洞挖掘# 操作系统-windows系统bat病毒

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

【OJ题解】在字符串中查找第一个不重复字符的索引

&#x1f4b5;个人主页: 起名字真南 &#x1f4b5;个人专栏:【数据结构初阶】 【C语言】 【C】 【OJ题解】 目录 1. 引言2. 题目分析示例&#xff1a; 3. 解题思路思路一&#xff1a;双重循环思路二&#xff1a;哈希表 4. C代码实现5. 代码详解6. 时间和空间复杂度分析7. 优化方…

el-date-picker日期选择器动态设置日期

需求&#xff1a;选择开始时间&#xff0c;或者在开始时间已存在的情况下&#xff1b;结束时间下拉日期选择框展示从开始日期展示&#xff1b;而不是当前日期&#xff0c;并且结束时间下拉框日期要禁用开始时间之前的日期。 <el-form-item label"开始时间" prop&q…

「C/C++」C/C++的区别

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

Redis-基本了解

一、Redis 初识 Redis 是⼀种基于键值对&#xff08;key-value&#xff09;的NoSQL数据库&#xff0c;与很多键值对数据库不同的是&#xff0c;Redis 中的值可以是由string&#xff08;字符串&#xff09;、hash&#xff08;哈希&#xff09;、list&#xff08;列表&#xff09…

大模型面试题持续更新_Moe(2024-10-30)

获取更多面试真题的集合&#xff0c;请移步至 https://i.afbcs.cn/naPbNYhttps://pica.zhimg.com/80/v2-7fd6e77f69aa02c34ca8c334870b3bcd_720w.webp?sourced16d100b Moe和集成学习方法有什么异同&#xff1f; MoE和集成学习的思想异曲同工&#xff0c;都是集成了多个模型的…

centos插U盘在什么路径访问

在CentOS系统中&#xff0c;插入U盘后&#xff0c;通常需要挂载U盘才能访问其中的文件。以下是挂载U盘并访问的步骤&#xff1a; 查看U盘设备&#xff1a; 使用fdisk -l命令查看U盘的设备名称&#xff0c;例如/dev/sdb1。 创建挂载点&#xff1a; 在/mnt目录下创建一个用于挂载…