外观模式
时间:2022-07-25
本文章向大家介绍外观模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
外观模式
外观模式Facade Pattern
又称为门面模式,它是一种对象结构型模式,外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用,外观模式在Js
中常常用于解决浏览器兼容性问题。
描述
根据单一职责原则,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,其为子系统的访问提供了一个简单而单一的入口。外观模式也是迪米特法则的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度。外观模式还要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道,能够降低系统的复杂程度。
模式结构
-
Facade
: 外观角色。 -
SubSystem
: 子系统角色。
优点
- 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
- 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
- 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
- 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。
缺点
- 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
- 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了开闭原则。
实现
/*
* 注册元素事件 addEvent函数即为外观角色 将各种浏览器作为子系统角色
* @param element [必填] 要绑定的元素
* @param type [必填] 事件类型
* @param fn [必填] 回调函数
*/
function addEvent(element, type, fn) {
if (element.addEventListener) { // DOM2级事件支持addEventListener方法
element.addEventListener(type, fn, false)
} else if (element.attachEvent) { // 支持attachEvent方法
element.attachEvent("on" + type, fn)
} else {
element["on" + type] = fn // 都不支持的浏览器以DOM0级事件绑定
}
}
每日一题
https://github.com/WindrunnerMax/EveryDay
参考
https://segmentfault.com/a/1190000014132789
https://www.runoob.com/design-pattern/facade-pattern.html
https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/facade.html
- What is "Type" in managed heap?
- 一个特殊场景的 LR 预测优化 Trick
- 你知道Unity IoC Container是如何创建对象的吗?
- 发布一个锁定行列的一种方法。(实现Excel里的冻结窗格的功能)
- IoC+AOP的简单实现
- 使用了继承、多态还有工厂模式和反射,但是还是没有OO的感觉。[已经增加了实现的代码]
- OO——从不知到知道一点,从迷茫到豁然开朗 (迟来的我的2002到2007)
- 只在UnitTest和WebHost中的出现的关于LogicalCallContext的严重问题
- TEST LAB V8在线渗透实验室教程(三)
- CMQ请求域名
- 在Entity Framework中使用存储过程(一):实现存储过程的自动映射
- 在Entity Framework中使用存储过程(二):具有继承关系实体的存储过程如何定义?
- 表单控件的副产品——查询控件
- 表单控件续(1)——应用接口来简化和分散代码
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- springboot开发之使用外部servlet容器及对jsp的支持
- java之内部类
- 关于我博客中的猫是怎么设置的说明
- LeetCode | 2.两数相加
- java之异常
- IDEA 下 SpringBoot 自动重启
- java之集合(Set、List、Map)
- springboot配置之在配置文件中配置debug=true开启自动配置类报告
- java之操作集合的工具类--Collections
- spinrgboot配置之@PropertySource和@ImportResource
- java之泛型
- java之枚举和注解
- java之注解
- 剑指offer(16-18)题解
- java之java.io.File的相关方法