Home  >  Article  >  Web Front-end  >  Detailed explanation of JS data access object pattern

Detailed explanation of JS data access object pattern

小云云
小云云Original
2018-01-27 17:19:181152browse

This article mainly brings you an example explanation of the data access object pattern of JS design pattern. The editor thinks it is quite good, so I will share it with you now and give it as a reference for everyone. Let’s follow the editor to take a look, I hope it can help everyone.

Question

Most websites will store some data (such as user token) on the front end to transfer values ​​​​between pages. For some large-scale web applications, It may store a lot of data, data management will become complicated, and a large project is jointly developed by multiple programmers. At this time, you will encounter a problem: how to ensure that your own data will not overwrite other data. What about humans? Because everyone uses the same WebStorage object on a page, you can't record the keys used by everyone. At this time, you can use the data access object pattern to solve the problem.

Introduction

HTML5 provides two new methods for storing data on the client: localStorage and sessionStorage. They are two storage mechanisms provided by the Web Storage API. The difference is that the former is permanent storage. , and the latter is data transfer limited to the current window, and the data stored in it will be deleted when the current session ends. The specific contents of localStorage and sessionStorage will not be introduced here. We will mainly discuss how to use them reasonably in actual development.

Data Access Object Pattern (DAO)

The data access object pattern encapsulates the access and storage of data sources and provides a data access object class responsible for managing and operating the stored data. Standardizes the data storage format, similar to the DAO layer in the background.

Since WebStorage uses Key-Value to access data and can only store strings (any type will be converted to a string when stored, and type conversion is required when reading), so we can Standardize the format of Key, such as module name + Key, developer + Key, etc. You can also add a prefix to the value to describe the data, such as adding a timestamp of the data expiration date to manage the life cycle of the data. The specific format project team can define it themselves, mainly to facilitate management and prevent conflicts. After agreeing on the specifications, they can start defining data access objects.

The following takes localStorage as an example to introduce the definition and use of data access object classes.

Code example

Basic structure of DAO class

The basic structure of the data access object class is as follows. We add a prefix to the key value to avoid key value conflicts, and in Add the data expiration timestamp and separator to the value, and then determine whether it has expired when obtaining the value. This allows for more flexible management of the life cycle of stored data. A callback method is also used here to facilitate obtaining the specific results of the data access process and performing related operations when necessary.

/**
 * 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) {
    ...
  }
}

Add (modify) data

/**
  * 添加(修改)数据
  * @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);
  }

Get data

/**
  * 获取数据
  * @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;
  }

Delete data

/**
  * 删除数据
  * @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));
  }

Usage

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); });

Write at the end

In fact, the data access object mode is more suitable for server-side database operations, such as operating MongoDB in nodejs. By encapsulating the database addition, deletion, modification and query operations, we can facilitate the management of front-end storage without having to worry about operating the database. DAO has provided us with a convenient and unified interface, so that we don’t have to worry about affecting other people’s data during team development.

Related recommendations:

php design pattern DAO (Data Access Object Pattern)

Yii Learning Summary Data Access Object (DAO), yiidao_PHP tutorial

javascript object-oriented analysis of two ways to access object properties_javascript skills

The above is the detailed content of Detailed explanation of JS data access object pattern. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn