1. 定义
提供了一个统一的接口,用来访问子系统中的一组接口
2. 口语化表述
工厂里组装台灯,流程、配件等有多种方式,每种台灯有自己的生产线
现在,需要某一种台灯,一种方式是直接去找这个台灯的生产线生成,这会令人烦恼,因为寻找是一件无聊而繁琐的事情
另一种方式是成立一个工厂前台,需要什么台灯就只需要给前台说明,前台会告诉对应的生产线,并将生产好的台灯交付给你
这流程就简单多了,不管是谁来,他都只需和前台联系,然后工厂就会给他对应的产品,这就是外观模式,前台就是工厂的外观
上述情景表述的是产品创建,所以也是简单工厂模式的典型应用(简单工厂模式侧重于创建,而外观模式不局限于创建产品)
(下面的描述会沿用这个上述这个场景)
3. 源码示例
Cesium.js是一个著名的、基于WebGL的GIS前端框架
基于WebGL就不得不提WebGL(OpenGL)的基础概念,比如VAO(顶点数组对象)、VBO(顶点缓冲对象)等
Cesium.js在渲染模块中,有一个对象叫VertexArrayFacade
,该对象大致源码如下:
function VertexArrayFacade(context, attributes, sizeInVertices, instanced) {
// ...
const attrs = VertexArrayFacade._verifyAttributes(attributes);
sizeInVertices = defaultValue(sizeInVertices, 0);
// Bucket the attributes by usage.
const length = attrs.length;
for (let i = 0; i < length; ++i) {
const attribute = attrs[i];
usage = attribute.usage;
attributesForUsage = attributesByUsage[usage];
if (!defined(attributesForUsage)) {
attributesForUsage = attributesByUsage[usage] = [];
}
attributesForUsage.push(attribute);
}
for (usage in attributesByUsage) {
if (attributesByUsage.hasOwnProperty(usage)) {
attributesForUsage = attributesByUsage[usage];
attributesForUsage.sort(compare);
const vertexSizeInBytes = VertexArrayFacade._vertexSizeInBytes(
attributesForUsage
);
const bufferUsage = attributesForUsage[0].usage;
const buffer = {
vertexSizeInBytes: vertexSizeInBytes,
vertexBuffer: undefined,
usage: bufferUsage,
needsCommit: false,
arrayBuffer: undefined,
arrayViews: VertexArrayFacade._createArrayViews(
attributesForUsage,
vertexSizeInBytes
),
};
this._allBuffers.push(buffer);
}
}
// ...
this.resize(sizeInVertices);
}
代码片段看上去有点多,但是不难理解,这个VertexArrayFacade
对象主要就是对VertexArray
做一系列的处理
外部操作VertexArray
时,只需要调用这个VertexArrayFacade
对象即可
4. 总结
4.1 设计优点
-
让代码独立于复杂子系统
将复杂的过程对外隐藏,外部只需要联系外观对象即可
4.2 适用场景
- 需要一个指向复杂子系统的直接接口,且该接口的功能有限(对外暴露的函数数量不多)
5. 参考资料
[1] 外观设计模式(门面模式) (refactoringguru.cn)
[2] cesium/packages/engine/Source/Renderer/VertexArrayFacade.js at main · CesiumGS/cesium (github.com)
标签:外观,attributesForUsage,const,vertexSizeInBytes,模式,usage,attributesByUsage,设计模式,Ve From: https://www.cnblogs.com/jiujiubashiyi/p/17874661.html