引言

HTML5 提供了两种在客户端存储数据的新方法:localStorage、sessionStorage,他们是Web Storage API 提供的两种存储机制,区别在于前者属于永久性存储,而后者是局限于当前窗口的数据传递,存储在其中的数据会在当前会话结束时被删除。localStorage、sessionStorage的具体内容在这里就不多做介绍了,我们主要探讨一下在实际开发中怎样合理使用他们。

问题

大部分网站会将一些数据(如:用户Token)存储在前端,用来实现页面间的传值,对于一些大型Web应用来说,其存储的数据可能会非常多,数据的管理会变得复杂,并且一个大型项目是由多位程序员共同开发的,这时就会遇到一个问题:怎样确保自己的数据不会覆盖掉其他人的呢?因为在一个页面中大家都是使用同一个WebStorage对象,总不能把大家使用过的Key记录下来吧。这时候就可以使用数据访问对象模式来解决了。

数据访问对象模式(DAO)

数据访问对象模式就是对数据源的访问与存储进行封装,提供一个数据访问对象类负责对存储的数据进行管理和操作,规范数据存储格式,类似于后台的DAO层。

由于WebStorage采用Key-Value的方式存取数据,而且只能存字符串(任何类型存储的时候都会被转为字符串,读取的时候需要进行类型转换),所以我们可以对Key的格式进行规范,比如模块名+Key,开发人员+Key等,还可以在值中添加一段前缀用来描述数据,如添加数据过期日期的时间戳,用来管理数据的生命周期。具体格式项目组可以自己定义,主要是便于管理,防止出现冲突,约定好规范后就可以开始定义数据访问对象了。

下面以localStorage为例,介绍一下数据访问对象类的定义和使用。

代码示例

DAO类基本结构

数据访问对象类的基本结构如下,我们给键值添加了一段前缀用来避免键值冲突,并且在值中加入数据过期时间戳以及分隔符,获取值的时候再进行判断是否过期,这样可以更灵活地管理存储数据的生命周期。这里还用到了回调的方式,方便获取数据访问过程的具体结果,以及在必要时执行相关操作。

/**
* LocalStorage数据访问类
* @param {string} prefix Key前缀
* @param {string} timeSplit 时间戳与存储数据之间的分割符
*/
var Dao = function (prefix, timeSplit) {
this.prefix = prefix;
this.timeSplit = timeSplit || '|-|';
}
// LocalStorage数据访问类原型方法
Dao.prototype = {
// 操作状态
status: {
SUCCESS: 0, // 成功
FAILURE: 1, // 失败
OVERFLOW: 2, // 溢出
TIMEOUT: 3 // 过期
},
// 本地存储对象
storage: localStorage || window.localStorage,
// 获取带前缀的真实键值
getKey: function (key) {
return this.prefix + key;
},
// 添加(修改)数据
set: function (key, value, callback, time) {
...
},
// 获取数据
get: function (key, callback) {
...
},
// 删除数据
remove: function (key, callback) {
...
}
}

添加(修改)数据

/**
* 添加(修改)数据
* @param key 数据字段标识
* @param value 数据值
* @param callback 回调函数
* @param time 过期时间
*/
set: function (key, value, callback, time) {
// 默认为成功状态
var status = this.status.SUCCESS,
key = this.getKey(key);
try {
// 获取过期时间戳
time = new Date(time).getTime() || time.getTime();
} catch (e) {
// 未设置过期时间时默认为一个月
time = new Date().getTime() + 1000 * 60 * 60 * 24 * 30;
}
try {
// 向本地存储中添加(修改)数据
this.storage.setItem(key, time + this.timeSplit + value);
} catch (e) {
// 发生溢出
status = this.status.OVERFLOW;
}
// 执行回调并传入参数
callback && callback.call(this, status, key, value);
}

获取数据

/**
* 获取数据
* @param key 数据字段标识
* @param callback 回调函数
*/
get: function (key, callback) {
var key = this.getKey(key),
status = this.status.SUCCESS, // 获取数据状态
value = null; // 获取数据值 try {
// 从本地存储获取数据
value = this.storage.getItem(key);
} catch (e) {
// 获取数据失败
status = this.status.FAILURE;
value = null;
} // 如果成功获取数据
if (status !== this.status.FAILURE) {
var index = value.indexOf(this.timeSplit),
timeSplitLen = this.timeSplit.length,
// 获取时间戳
time = value.slice(0, index);
// 判断数据是否未过期
if (new Date(1*time).getTime() > new Date().getTime() || time == 0) {
// 获取数据值
value = value.slice(index + timeSplitLen);
} else {
// 数据已过期,删除数据
value = null;
status = this.status.TIMEOUT;
this.remove(key);
}
} // 执行回调
callback && callback.call(this, status, value);
// 返回结果值
return value;
}

删除数据

/**
* 删除数据
* @param key 数据字段标识
* @param callback 回调函数
*/
remove: function (key, callback) {
// 设置默认状态为失败
var status = this.status.FAILURE,
key = this.getKey(key),
value = null;
try {
// 获取数据值
value = this.storage.getItem(key);
} catch (e) {
// 数据不存在,不采取操作
}
// 如果数据存在
if (value) {
try {
// 删除数据
this.storage.removeItem(key);
status = this.status.SUCCESS;
} catch (e) {
// 数据删除失败,不采取操作
}
}
// 执行回调并传入参数,删除成功则传入被删除的数据值
callback && callback.call(this, status, status > 0 ? null : value.slice(value.indexOf(this.timeSplit) + this.timeSplit.length));
}

用法

var dao = new Dao('myModule_');
// 添加/修改数据
dao.set('token', 'abc', function () { console.log(arguments); });
// 获取数据
var value = dao.get('token', function () { console.log(arguments); });
console.log(value);
// 删除数据
dao.remove('token', function () { console.log(arguments); });

写在最后

其实数据访问对象模式更适合与服务器端的数据库操作,比如在nodejs中操作MongoDB,通过对数据库增删改查操作的封装,可以方便我们对前端存储的管理,不必为操作数据库感到烦恼,DAO已经为我们提供了便捷统一的接口,这样在团队开发中就不用担心影响到其他人的数据了。

本文为作者kMacro原创,转载请注明来源:http://www.jianshu.com/p/ffdaa99dbde8。

JS设计模式(三) 数据访问对象模式的更多相关文章

  1. PHP设计模式系列 - 数据访问对象模式

    数据访问对象模式 数据访问对象模式描述了如何创建透明访问数据源的对象. 场景设计 设计一个BaseDao基类,实现数据库操作基本的一些query,insert,update方法 在实际使用的过程中,继 ...

  2. Java数据访问对象模式

    数据访问对象模式或DAO模式用于将低级数据访问API或操作与高级业务服务分离. 以下是数据访问对象模式的参与者. 数据访问对象接口 - 此接口定义要对模型对象执行的标准操作. 数据访问对象具体类 - ...

  3. JAVAWEB基础模块开发顺序与数据访问对象实现类步骤

    一.模块的开发的顺序 1. 定义数据表 2. 新建模型类 3. 新建"add.jsp" 4. 实现AddServlet中的doGet()方法 5. 定义Dao.Service接口 ...

  4. Yii的学习(2)--数据访问对象 (DAO)

    摘自Yii官网:http://www.yiiframework.com/doc/guide/1.1/zh_cn/database.dao Yii提供了强大的数据库编程支持.Yii数据访问对象(DAO) ...

  5. winform中利用反射实现泛型数据访问对象基类(1)

    考虑到软件使用在客户端,同时想简化代码的实现,就写了一个泛型的数据访问对象基类,并不是特别健全,按道理应该参数化的方式实现insert和update,暂未使用参数化,抽时间改进. /// <su ...

  6. 解析大型.NET ERP系统数据访问 对象关系映射框架LLBL Gen Pro

    LLBL Gen Pro是一个为.NET开发人员设计的的对象关系映射(ORM)框架,与NHibernate,Entity Framework等框架一样,通过实体与数据表的映射,实现关系数据库持久化. ...

  7. Php设计模式(三):行为型模式part2

    原文详见:http://www.ucai.cn/blogdetail/7023?mid=1&f=5 可以在线运行查看效果哦! <接上文> 5.中介者模式(Mediator) : 用 ...

  8. 设计模式のNullObjectPattern(空对象模式)----行为模式

    一.产生背景 在空对象模式(Null Object Pattern)中,一个空对象取代 NULL 对象实例的检查.Null 对象不是检查空值,而是反应一个不做任何动作的关系.这样的 Null 对象也可 ...

  9. JS设计模式(3)代理模式

    什么是代理模式? 情景:小明追女生 A 非代理模式:小明 =花=> 女生A 代理模式:小明 =花=> 让女生A的好友B帮忙 =花=> 女生A 定义:为其他对象提供一种代理以控制对这个 ...

随机推荐

  1. 深入剖析C++多态、VPTR指针、虚函数表

    在讲多态之前,我们先来说说关于多态的一个基石------类型兼容性原则. 一.背景知识 1.类型兼容性原则 类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代.通过公有继承,派 ...

  2. 移动端rem使用

    let $html=document.documentElement,windowW = window.innerWidth,ratio = windowW / 750if (windowW > ...

  3. 我的hibernate学习记录(一)

    之前已经过滤一下hibernate的简单的用法,但是近期有点时间,所以重新看下视频,敲下代码,翻下笔记,写博客与大家分享一下. hibernate简介 Hibernate是一个开放源代码的对象关系映射 ...

  4. 误删libc.os.6共享库的解决办法

    在我们使用系统的过程中,要注意各个共享库的使用,万一不小心删掉了什么,就可能出现各种问题.如果你把libc.os.6删掉了,那可就悲剧了,因为你的大部分命令都不能够正常使用了(╥╯^╰╥) 接下来呢, ...

  5. linux一周学习总结

    对于linux,之前也完全没有接触过,完全零基础小白.来到马哥以后,进入学习也有一周时间 ,一周里老师带我们学习了很多指令,下面,我就自己的理解和老师讲授的内容对linux中的一些指令做一个简单的小总 ...

  6. 转:【Java集合源码剖析】Vector源码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/35793865   Vector简介 Vector也是基于数组实现的,是一个动态数组,其容量 ...

  7. java记事本1.2版

    功能:实现了新建,打开,保存,退出,复制,剪切,粘贴等功能 效果图:

  8. 个人作业(3)----个人总结(Alpha阶段)

    一.个人总结. 个人完成的任务:在此阶段我完成了用户调研.部分测试以及部分博客书写. 个人及团队心得:经过几周Alpha阶段开发后,我大致了解了开发软件的过程,开发一个软件并没有以往想象中那么简易,在 ...

  9. 201521123003《Java程序设计》第3周学习总结

    1. 本章学习总结 你对于本章知识的学习总结 了解和学会使用更多已有的类,如Calendar类.Math类.Arrays类等等 public.private的权限修饰 学会使用在Eclipse工具栏中 ...

  10. 201521123039 《java程序设计》第一周学习总结(新)

    1.本章学习总结 -Java是面向对象的程序语言,它一切定义都是对象.我们所编写的Java程序经过编译后生成了.class的文件,再经过JVM对.class解释运行就可以得到Java程序,所以Java ...