數據訪問對象模式

數據訪問對象模式

數據訪問對象模式Data Access Object PatternDAO模式,用於把低級的數據訪問API或操做從高級的業務服務中分離出來,準確來講數據訪問對象模式不屬於一般定義的設計模式範疇,但數據訪問對象模式是一種很是有用的數據訪問管理構建技巧。javascript

描述

數據訪問對象模式就是對數據源的訪問與存儲進行封裝,提供一個數據訪問對象類負責對存儲的數據進行管理和操做,規範數據存儲格式,相似於後臺的DAO層。
HTML5提供了兩種在客戶端存儲數據的新方法: localStoragesessionStorage,他們是Web Storage API提供的兩種存儲機制,區別在於前者屬於永久性存儲,然後者是侷限於當前會話以及衍生窗口的數據傳遞。因爲WebStorage採用Key-Value的方式存取數據,並且只能存字符串(任何類型存儲的時候都會被轉爲字符串,讀取的時候須要進行類型轉換),因此咱們能夠對Key的格式進行規範,好比模塊名+Key,開發人員+Key等,還能夠在值中添加一段前綴用來描述數據,如添加數據過時日期的時間戳,用來管理數據的生命週期。具體格式項目組能夠本身定義,主要是便於管理,防止出現衝突,在前端方面其實主要是對於本地存儲進行了一次封裝,用以進行一個規範性約束,約定好規範後就能夠開始定義數據訪問對象了。html

實現

/**
 * LocalStorage數據訪問類
 * @param {string} prefix Key前綴
 * @param {string} timeSplit 時間戳與存儲數據之間的分割符
 */
var DAO = function (prefix, timeSplit) {
    this.prefix = prefix;
    this.timeSplit = timeSplit || "|-|";
}

// 原型方法
DAO.prototype = {
    constructor: DAO,
    // 操做狀態
    status: {
        SUCCESS: 0,     // 成功
        FAILURE: 1,     // 失敗
        OVERFLOW: 2,    // 溢出
        TIMEOUT: 3      // 過時
    },
    // 本地存儲對象
    storage: localStorage || window.localStorage,
    /**
     * 獲取帶前綴的真實鍵值
     * @param key 數據字段標識
     */
    getKey: function (key) {
        return this.prefix + key;
    },
    /**
     * 添加(修改)數據
     * @param key 數據字段標識
     * @param value 數據值
     * @param callback 回調函數
     * @param time 過時時間
     */
    set: function (oriKey, value, callback, time) {
        let status = this.status.SUCCESS; // 默認爲成功狀態
        let key = this.getKey(oriKey);
        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 (oriKey, callback) {
        let key = this.getKey(oriKey);
        let status = this.status.SUCCESS;    // 獲取數據狀態
        let value = null;    // 獲取數據值
        try{
            value = this.storage.getItem(key); // 從本地存儲獲取數據
        }catch(e){
            status = this.status.FAILURE; // 獲取數據失敗
            value = null;
        }
        // 若是成功獲取數據
        if (status !== this.status.FAILURE) {
            let index = value.indexOf(this.timeSplit);
            let timeSplitLen = this.timeSplit.length;
            let 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 (oriKey, callback) {
        let status = this.status.FAILURE; // 設置默認狀態爲失敗
        let key = this.getKey(oriKey);
        let value = null;
        try {
            value = this.storage.getItem(key); // 獲取數據值
        }catch(e){
            // 數據不存在,不採起操做
        }
        if(value){ // 若是數據存在
            try{
                // 刪除數據
                this.storage.removeItem(key);
                status = this.status.SUCCESS;
            }catch(e) {
                // 數據刪除失敗,不採起操做
            }
        }
        // 執行回調並傳入參數,刪除成功則傳入被刪除的數據值
        let param = status > 0 ? null : value.slice(value.indexOf(this.timeSplit) + this.timeSplit.length);
        callback && callback.call(this, status, param);
    }
};

(function(){
    let dao = new DAO("user-verify");
    dao.set("token", "111", (...args) => console.log(args)); // [0, "user-verifytoken", "111"]
    let value = dao.get("token", (...args) => console.log(args)); // [0, "111"]
    console.log(value); // 111
    dao.remove("token", (...args) => console.log(args)); // [0, "111"]
})();

每日一題

https://github.com/WindrunnerMax/EveryDay

參考

https://zhuanlan.zhihu.com/p/235136284
https://zkhdev.github.io/2017/07/31/js-dao/
https://www.runoob.com/design-pattern/data-access-object-pattern.html
相關文章
相關標籤/搜索