外观模式
为一组复杂的子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统接口的访问更容易。
外观模式本质
封装交互 简化调用
外观模式的核心思想
用户不需要关心里面是如何调用,如何使用的,我们只需要有一个能提供给我们实现功能的接口就行
外观模式的主要角色
1、外观(Facade)角色
:客户端可以调用这个角色的方法。此角色知晓相关子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
2、子系统(SubSystem)角色
:可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合。每个子系统都可以被客户端直接调用,或者被外观角色调用。子系统并不知道外观角色的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。
具体示例
一键完成多种操作
// 例子1:一键完成 装弹,打蛋,换蛋 三个操作
class A{
a1(){} // 装弹
a2(){} // 打蛋
a3(){} // 换蛋
a_init(){ // 一键操作
this.a1() // 调用装弹
this.a2() // 调用打蛋
this.a3() // 调用换蛋
}
}
let a = new A()
// 没有使用外观模式就需要这么繁琐
a.a1() // 装弹
a.a2() // 打蛋
a.a3() // 换蛋
// 使用外观模式
a.a_init() // 一键操作装弹打蛋换蛋
复制代码
浏览器事件监听函数的兼容
// 例子2:浏览器兼容事件监听函数
// 有的浏览器支持el.addEventListener(),而有的浏览器只支持el.attachEvent(),此时就需要用外观模式设计一个函数来兼容
function addMyEvent(el,type,fn){ // 接收参数:元素,事件类型,回调函数
if(浏览器支持addEventListener()){
// 就使用el.addEventListener()
}else{ // 否则就是支持attachEvent()
// 就使用attachEvent()
}
}
// 然后以后需要使用事件监听的时候,只需要执行该兼容函数即可
addMyEvent(el,type,fn)
复制代码
模拟jq源码
// 例子3:模拟jq源码
var A = {
get:function (id){
return document.getElementById(id)
},
css:function (id,key,value){
this.get(id).style[key] = value
},
html:function (id,content){
this.get(id).innerHTML = content
},
}
// 使用外观模式 直接打点调用封装好的方法 写的少
A.html("box","这是新添加的内容1")
A.html("box1","这是新添加的内容2")
A.html("box2","这是新添加的内容3")
A.html("box3","这是新添加的内容4")
A.html("box4","这是新添加的内容5")
A.html("box5","这是新添加的内容6")
// 不使用外观模式 需要一条一条调用各种方法 很繁琐
document.getElementById("box").innerHTML("这是新添加的内容1")
document.getElementById("box1").innerHTML("这是新添加的内容2")
document.getElementById("box2").innerHTML("这是新添加的内容3")
document.getElementById("box3").innerHTML("这是新添加的内容4")
document.getElementById("box4").innerHTML("这是新添加的内容5")
document.getElementById("box5").innerHTML("这是新添加的内容6")
复制代码
模拟电脑开机过程
// 例子4:模拟电脑开机
// 不使用外观模式的电脑开机,每启动一个硬件就要调用一个方法
function Cpu(){
this.startUp = function (){
console.log("Cpu启动")
}
}
function Memory(){
this.startUp = function (){
console.log("Memory启动")
}
}
function Disk(){
this.startUp = function (){
console.log("Disk启动")
}
}
// 使用外观模式,一个按键即可调用所有硬件进行启动
function Computer(){
var _cpu,_memory,_disk
_cpu = new Cpu()
_memory = new Memory()
_disk = new Disk()
this.start = function (){
_cpu.startUp() // cpu调用启动函数
_memory.startUp() // memory调用启动函数
_disk.startUp() // disk调用启动函数
}
}
let c = new Computer() // 实例化对象
c.start() // 对象直接打点调用方法就可一键操作电脑三个硬件启动
复制代码
外观模式优点
1、实现了子系统与客户端之间的松耦合关系。
2、客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易
外观模式适用场景
1、设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式。
2、开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口。
3、维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END