The code should be written in a way that others cannot understand (17)

This article refers to the book "JavaScript Design Patterns"-Zhang Rongming

Article Directory

Preface

  As a front-end developer, have you ever encountered front-end storage. For example, when a user enters the program for the first time, there will be a personalized guide. Generally speaking, this function is given to back-end colleagues to do it, but sometimes it needs to be placed in The front end, to save the field of whether it is the first login.

  Then when we store locally, we may encounter many problems. Every time we add a set of data, we worry about whether it will overwrite other people's data, etc. The design pattern in this section introduces how to reasonably store the front-end.

Data access object model

  Abstract and encapsulate the access and storage of data sources. DAO facilitates the access and storage of data through the management of data source links .

  We can create a data access object class to solve the above problems. This data access object class is an encapsulation of local storage. To create a DAO class, you must first understand the current needs, and it is best to also consider the needs of others, so that the created DAO class is more robust.

  First of all, our data needs to have the functions of adding, deleting, modifying, and checking. Secondly, when others use local storage, they also need to know what data I have saved.

  Local storage uses the object localStorage . For the same site, there is no split library in it, so everyone uses the same localStorage . Therefore, you should add a field identifier to the front of the field of each stored data to split the localStorage library.

  The saving of data by local storage is actually a string attribute of localStorage . Sometimes for storage, understanding its time is very important to facilitate future management, so we also need a timestamp.

/**
* 本地存储类
* 参数 preId    本地存储数据库前缀
* 参数 timeSign 时间戳与数据之间的拼接符
*/
var BaseLocalStorage = function(preId, timeSign) {
    
    
	//定义本地存储数据库前缀
	this.preId = preId;
	//定义时间戳与数据之间的拼接符
	this.timeSign = timeSign || '|-|';
}

  In order to know the state of the data, we can save the return state of the operation in the DAO class for call when it is used by the flesh. We also need to save the reference of the local storage service in the DAO class for our convenience. Of course, the DAO class also needs to provide an interface method for adding, deleting, modifying, and checking the database.

//本地存储类原型方法
BaseLocalStorage.prototype = {
    
    
	//操作状态
	status: {
    
    
		SUCCESS: 0,   //成功
		FALLURE: 1,   //失败
		OVERFLOW: 2,   //溢出
		TIMEOUT: 3,   //过期
	},
	//保存本地存储链接
	stroge: localStorage || window.localStorage,
	//获取本地存储数据库真实字段
	getKey: function(key) {
    
    
		return this.preId + key;
	},
	//添加(修改)数据
	set: function(key, value, callback, time) {
    
    
		//省略操作
	},
	//获取数据
	get: function(key, callback) {
    
    
		//省略操作
	},
	//删除数据
	remove: function(key, callback) {
    
    
		//省略操作
	}
}

  For the following things, we only need to implement set , get , and remove . The first is the set method. We need to add a timestamp to the field. The data we add to the local storage essentially calls the setItem method of localStorage . Finally, we have to execute the callback function and pass the result of the operation into the callback function.

/**
* 添加(修改)数据
* 参数 key      数据字段标识
* 参数 value    数据值
* 参数 callback 回调函数
* 参数 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 *31;
	}
	try {
    
    
		//向数据库中添加数据
		this.storage.setItem(key, time + this.timeSign + value);
	}catch (e) {
    
    
		//溢出失败,返回溢出状态
		status = this.status.OVERFKOW;
	}
	//有回调函数则执行回调函数,并传入参数操作状态,真实数据字段标识以及存储数据值
	callback && callback.call(this, status, key, calue);
}

  With the setting data method, the method of obtaining data through the storage field is simple, or call the getItem method of localStorage , but it should be noted that there are four types of data query conditions that are compatible. The first is that the field data is not originally Exist, it should return a failed state; the second type, the operation is successful but no value is obtained, and it should return at this time; the third type, the value is obtained, but the time has expired, the data should be deleted at this time; finally One is to obtain data successfully and return successfully.

/**
* 获取数据
* 参数 key      数据字段标识
* 参数 callback 回调函数
*/
get: function(key, callback) {
    
    
		//默认操作状态时成功
	var status = this.status.SUCCESS,
		//获取
		key = this.getKey(key),
		//默认值为空
		value = null,
		//时间戳与存储数据之间的拼接符长度
		timeSignLen = this.timeSign.length,
		//缓存当前对象
		that = this,
		//时间戳与存储数据之间的拼接符起始位置
		index,
		//时间戳
		time,
		//最终获取的数据
		result;
	try {
    
    
		//获取字段对应的数据字符串
		value = that.storage.getItem(key);
	} catch (e) {
    
    
		//获取失败则返回失败状态,数据结果为null
		result = {
    
    
			status: that.status.FAILURE,
			value: null
		};
		//执行回调并返回
		callback && callback.call(this, result.status, result.value);
		return result;
	}
	//如果成功获取数据字符串
	if(value) {
    
    
		//获取时间戳与存储数据之间的拼接符起始位置
		index = value.indexOf(that.timeSign);
		//获取时间戳
		time = +value.slice(0, index);
		//如果时间为过期
		if(new Date(tiem).getTime() > newDate.getTime() || time == 0) {
    
    
			//获取数据结果(拼接符后面的字符串)
			value = value.slice(index + timeSignLen);
		} else {
    
    
			//过期则结果为null
			value = null;
			//设置状态为过期状态
			status = that.status.TIMEOUT;
			//删除该字段
			that.remove(key);
		}
	} else {
    
    
		//未获取数据字符串状态为失败状态
		status = that.status.FAILURE;
	}
	//设置结果
	result = {
    
    
		status: status,
		value: value
	};
	//执行回调函数
	callback && cakkback.call(this, result.status, result.value);
	//返回结果
	return result;
}

   The remove method is a picture of the cat. First, the removeItem method of localStorage should be used to delete. There will be 3 statesduring execution. The first one is that the field is not modified, so the operation result is a failed state. The second one isthat an exception occurs whendeleting (the removeItem methodis called). This should also be a failure. The last one is of course modification. success.

/**
* 删除数据
* 参数 key      数据字段标识
* 参数 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.timeSign) + this.timeSign.length))
}

  So that our entire DAO class is complete, the next test. There is a little trick above, I don’t know if you have found it. When we set the default state, the default operation of set and get is successful, but the operation state of remove is failed. Why?

  This is because when we set the default state, we should ensure that the default state appears as much as possible, so that our code execution efficiency will be higher, which also reflects an engineer's overall control over the code designed by himself.

var LS = new BaseLocalStorage('LS__');
LS.set('a', 'xiao ming', function() {
    
    console.log(arguments);});  //[0, "xiao ming", "LS__a", "xiao ming"]
LS.get('a', function() {
    
    console.log(arguments);});      //[0, "xiao ming"]
LS.remove('a', function() {
    
    console.log(arguments);});   //[0, "xiao ming"]
LS.remove('a', function() {
    
    console.log(arguments);});   //[1, null]
LS.get('a', function() {
    
    console.log(arguments);});      //[1, null]

  For browsers that do not support local storage, we sometimes store data through cookies or the userData storage area of ​​the browser . This requires reconstruction of our DAO to be compatible with more browsers. The reconstruction method can use what we have learned before Design patterns, everyone depends on your mastery. Specifically, you can do it as a practice question.




Guess you like

Origin blog.csdn.net/EcbJS/article/details/110954579