最下面是周五懒懒分享的PPT,不得不承认,强大如斯的keynote,也能让我做出这么丑的PPT。。
09年就买了《JavaScript设计模式》,前后看了几次(是“次”,不是“遍”),刚开始看没什么收获,后来随着编码经验、遇到的问题越来越多,看这本书也越来越觉得好。现在都快当成了工具书,遇到难题就去翻翻,常看常新。
设计模式是编码的最佳实践,它应用在两个层次:解决特定编码问题、设计程序架构。
简单记录一下“享元模式”及其在解决特定问题上的应用。
应用场景
1. 页面存在大量资源密集型对象;
2. 这些对象具备一定的共性,可以抽离出公用的操作和数据。
场景举例
例1. 倒计时
具备校准功能的倒计时组件,校准、定时操作耗费大量的系统资源。如果页面中存在多个倒计时对象,显然要考虑把校准、定时抽离出来,统一控制所有的实例对象。
例2. 弹层交互
页面中多处的按钮、链接、Ajax操作可能触发相同的弹层,虽然触发方式各异,但同时只存在一个弹层且样式相近。这时可以考虑把创造、弹出弹层的操作从各处抽离出来统一管理。
例3. 数据交互
页面存在多种类似的数据交互,每个交互作为独立的对象,可以把数据发送、接收、处理、显示等相同的操作抽离出来形成“享元”。
组成部分
“享元”:抽离出来的外部操作和数据;
“工厂”:创造对象的工厂;
“存储器”:存储实例对象的对象或数组,供“享元”来统一控制和管理。
关键
1. 合理划分内部和外部数据。
既要保持每个对象的模块性、保证享元的独立、可维护,又要尽可能多的抽离外部数据。
如何权衡?极限编程中有个YAGNI原则 —— you ain’t gonna need it,放在这里即是说,设计系统时,把精力放在最需要的地方,而忽略一些无关紧要的细节。一个优美的系统,完全可以遮盖其中一些小hack带来的瑕疵。不多说了,重在权衡。
2. 管理所有实例
既然抽离出了外部数据和操作,那享元就必须可以访问和控制实例对象。在JavaScript这种动态语言中,这个需求是很容易实现的:我们可以把工厂生产出的对象简单的扔在一个数组中。为每个对象设计暴露给外部的方法,便于享元优雅的控制。
3. 享元的职责开关
例如倒计时的享元,如果页面中所有的倒计时都跑完了,所有的对象都已停止工作,那显然享元不应继续做这些高能耗的工作。使用一个外部标记变量,每个对象起始时都来设置这个标记,享元则通过这个标记来决定是否继续进行例行工作。
优点
1. 将能耗大的操作抽离成一个,在资源密集型系统中,可大大减少资源和内存占用;
2. 职责封装,这些操作独立修改和维护;
缺点
1. 增加了实现复杂度。
将原本由一个工厂方法实现的功能,修改为了一个享元+一个工厂+一个存储器。
2. 对象数量少的情况,可能会增大系统开销。
原因同上,权衡参照优点1。
实现
下面是一个带校准功能的倒计时组件的基本代码结构,该学学画图了。。
Keynote