>웹 프론트엔드 >JS 튜토리얼 >JS 데이터 액세스 개체 패턴에 대한 자세한 설명

JS 데이터 액세스 개체 패턴에 대한 자세한 설명

小云云
小云云원래의
2018-01-27 17:19:181192검색

이 글에서는 주로 JS 디자인 패턴의 데이터 액세스 객체 패턴에 대한 예제 설명을 제공합니다. 편집자님이 꽤 좋다고 생각하셔서 지금 공유하고 모두에게 참고용으로 드리고자 합니다. 편집자를 따라가서 모두에게 도움이 되기를 바랍니다.

문제

대부분의 웹사이트는 페이지 간에 값을 전송하기 위해 일부 데이터(예: 사용자 토큰)를 프런트 엔드에 저장합니다. 일부 대규모 웹 애플리케이션의 경우 저장되는 데이터가 매우 클 수 있습니다. 복잡해지고 여러 프로그래머가 공동으로 대규모 프로젝트를 개발할 때 문제에 직면하게 됩니다. 자신의 데이터가 다른 사람의 데이터를 덮어쓰지 않도록 하려면 어떻게 해야 할까요? 모든 사람이 페이지에서 동일한 WebStorage 개체를 사용하기 때문에 모든 사람이 사용하는 키를 기록할 수는 없습니다. 이때 데이터 액세스 개체 패턴을 사용하여 문제를 해결할 수 있습니다.

소개

HTML5는 클라이언트 측에 데이터를 저장하는 두 가지 새로운 방법인 localStorage와 sessionStorage를 제공합니다. 이는 웹 저장소 API에서 제공하는 두 가지 저장 메커니즘이지만 전자는 영구 저장소로 제한됩니다. 현재 창에서 데이터 전송을 수행하면 현재 세션이 끝나면 여기에 저장된 데이터가 삭제됩니다. 여기서는 localStorage와 sessionStorage의 구체적인 내용에 대해서는 소개하지 않겠습니다. 실제 개발에서 어떻게 합리적으로 사용할 수 있는지에 대해 주로 논의하겠습니다.

데이터 액세스 개체 패턴(DAO)

데이터 액세스 개체 패턴은 데이터 소스의 액세스 및 저장을 캡슐화하고 저장된 데이터의 관리 및 운영을 담당하는 데이터 액세스 개체 클래스를 제공하며 데이터 저장 형식을 표준화합니다. 백엔드 DAO 레이어.

WebStorage는 Key-Value 방식을 사용하여 데이터에 액세스하고 문자열만 저장할 수 있으므로(모든 유형은 저장 시 문자열로 변환되며 읽을 때는 유형 변환이 필요함) Key Standardize의 형식을 변경할 수 있습니다. , 모듈 이름 + 키, 개발자 + 키 등과 같은 값에 접두사를 추가하여 데이터 만료 날짜의 타임스탬프를 추가하여 데이터의 수명 주기를 관리하는 등 데이터를 설명할 수도 있습니다. 특정 형식 프로젝트 팀은 주로 관리를 용이하게 하고 충돌을 방지하기 위해 이를 직접 정의할 수 있으며 사양에 동의한 후 데이터 액세스 개체 정의를 시작할 수 있습니다.

다음은 데이터 액세스 개체 클래스의 정의와 사용을 소개하기 위해 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));
  }

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

마지막에 작성

사실 데이터 액세스 개체 모드는 다음과 같은 서버 측 데이터베이스 작업에 더 적합합니다. Nodejs에서 MongoDB를 운영하는 것처럼 데이터베이스의 추가, 삭제, 수정 및 쿼리 작업을 캡슐화함으로써 프런트엔드 스토리지 관리를 용이하게 할 수 있으며 DAO가 제공하는 데이터베이스 운영에 대해 걱정할 필요가 없습니다. 편리하고 통일된 인터페이스를 제공하므로 팀 개발 중에 다른 사람의 작업에 영향을 미칠 염려가 없습니다.

관련 권장 사항:

php 디자인 패턴 DAO(데이터 액세스 개체 패턴)

Yii 학습 요약 데이터 액세스 개체(DAO), yiidao_PHP 튜토리얼

자바스크립트의 두 가지 유형의 개체 지향 액세스 개체 속성 방법분석_자바스크립트 능력

위 내용은 JS 데이터 액세스 개체 패턴에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.