这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
本文主要介绍了 JS 中的工厂模式实践。具有一定的参考价值,下面跟着小编一起来看下吧
一. 写在前面
工厂模式和抽象工厂在后台代码中的使用,相信你一定非常熟悉,所以关于概念的东西也用不着我多说。你可以用其做为类与类之间,层与层之间的解耦。工厂模式没有什么难点,在 JS 中其实思想也是一样的,所以废话不多说,直接上实践的场景和代码。
二. 场景描述
1. 最近的项目的登陆使用了 Owin 认证,所以 token 必须找好地方进行存储,鉴于 token 需要在请求 API 资源的时候放到请求头的 Authorization 当中,以便在进入 webAPI 前进行身份验证。所以我不想在主流浏览器中的 cookie 中存储 token,因为这样一来,每次 Cookie 中带一份 token,Authorization 中又带一份 token. 多传输一次不说,还让人感到很 low. 这么 这么 low 的行为,你忍心使用吗。所以我希望把 token 存储于 localStorage 当中。那么问题来了,不支持 H5 的浏览器怎么办?
2. 为了将来把所有前端资源置于 CDN, 前端仅拥有 html,CSS 和 js。页面加载到浏览器客户端后,所有动态资源走 AJAX, 并且所有资源均跨域。那么问题又来了,跨域很容易解决,在 IE8,IE9 这种默认关闭跨域功能的浏览器怎么办
三. 公共 JS 结构一览
我通常会给应用定义一个全局 Application.js。其中大概包括如下内容。 先上整体代码结构,供参考
四. 引入工厂思想解决问题
为了解决上述两个问题,所以引入工厂模式,在工厂中创建对象,工厂中根据不同浏览器类型,创建不同对象。
也就是说在解决问题一上,在浏览器支持 H5 的时候,存储 token 于 localStorage。在不支持 h5 的浏览器中还是存于 cookie.
所以产生了两个 JS 对象,CookieStorageUtil 对象,LocalStorageUtil 对象。并且他们应该实现相同的 "接口", 在这里我没有使用 JS 代码来模仿接口,而是采用注释的形式,标注两个对象需要实现相同的接口,实现接口中的两个方法 write() 和 get()。并规范代码,下划线开头的为私有方法,这样一来今后修改内部代码的时候,私有方法随便改,对外部暴露的方法名称不变就好,是不是有点像后台的面向接口编程呢?其实 JS 也是一样的。再多费一句话,如果我不使用 JS 的 function 模拟类的话,是无法达到真正的方法私有,所以如果有人调用下划线'_'开头的私有方法,在今后私有方法有变动的时候影响了功能,那就不是我的锅咯?
还是上代码靠谱:
- /**
- * Storage Factory -Author 吴双 cnblogs.com/tdws
- */
- StorageUtilManager: new Object({
- createStorageUtil: function () {
- if (window.applicationCache) {
- return AppUtil.LocalStorageUtil;
- } else {
- return AppUtil.CookieStorageUtil;
- }
- }
- }),
- /**
- * implement Storage -Author 吴双
- * write()
- * get()
- */
- CookieStorageUtil: {
- write: function (key, dataObj) {
- this._clearCookie(key);
- //写入的字符串
- var dataObjStr = JSON.stringify(dataObj);
- this._setCookie(key, dataObjStr, 15);
- },
- get: function (key) {
- return this._getCookie(key);
- },
- _setCookie: function (cname, cvalue, exdays) {
- var d = new Date();
- d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
- var expires = "expires=" + d.toUTCString();
- var path = "path=/";
- document.cookie = cname + "=" + cvalue + "; " + expires + "; " + path;
- },
- _getCookie: function (cname) {
- var name = cname + "=";
- var ca = document.cookie.split(';');
- for (var i = 0; i < ca.length; i++) {
- var c = ca[i];
- while (c.charAt(0) == ' ') c = c.substring(1);
- if (c.indexOf(name) != -1) return c.substring(name.length, c.length);
- }
- return null;
- },
- _clearCookie: function (key) {
- this._setCookie(key, "", -1);
- }
- },
- /**
- * implement Storage cnblogs.com/tdws
- * write()
- * get()
- */
- LocalStorageUtil: {
- write: function (key, dataObj) {
- this._writeLocalStorage(key, dataObj);
- },
- get: function (key) {
- return this._getFromLocalStorage(key);
- },
- _writeLocalStorage: function (key, dataObj) {
- var localStorage = window.localStorage;
- localStorage.removeItem(key);
- //对象转化为字符串,将objStr按正常的方式存入localStorage中
- var dataObjStr = JSON.stringify(dataObj);
- localStorage.setItem(key, dataObjStr);
- },
- _getFromLocalStorage: function (key) {
- var localStorage = window.localStorage;
- return localStorage.getItem(key);
- },
- _removeLocalStorage: function (key) {
- var localStorage = window.localStorage;
- localStorage.removeItem(key);
- }
- }
这样第二个问题也得到了解决,在不支持跨域的浏览器创建 XDomainRequest 对象来做请求,两个 HttpUtil 对象依然实现相同的接口中的方法。在这个跨域问题上,推荐使用 gayhub 中的一个 1.8k 的 JS https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
对了,为了避免使用工厂模式,使代码调用复杂,我们可以简化 JS
- AppUtil.currentHttpUtil = AppUtil.HttpUtilManager.createHttpUtil();
五. 写在最后
所以有了这样的方式,问题平滑的解决了,两个 StorageUtil 与调用方,通过工厂 StorageUtilManager 完成解耦。可能你看完代码后说,不就是多了一个 Manager 吗?这也很简单啊,是啊,就是这么简单,这就是设计模式,它仅仅是前人的经验模式,它更平滑的解决我们的实际问题。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持 phperz!
来源: http://www.phperz.com/article/17/0703/328409.html