【Dn910】第 24 章 備忘錄模式 《Javascript 設(shè)計模式》
正常操作,正常分析,大家好,我是D1n910。
今天我繼續(xù)來學(xué)習(xí) 《JavaScript 設(shè)計模式》的第四篇 行為型設(shè)計模式
這是一個連續(xù)的讀書筆記,所以如果你之前的內(nèi)容沒有看的話,可以去看看(建議直接看書,當(dāng)然書的例子都比較早了,是2015年之前的代碼內(nèi)容,過了六年了,前端發(fā)展了很多,比如類的聲明可以直接用 Class 了)。
直接查看目錄就可以查看到所有的系列文章啦。

這里再次感謝 《Javascript 設(shè)計模式》及其作者 張榮銘,專欄內(nèi)容是在它的基礎(chǔ)上生成的。
現(xiàn)在會覺得很多設(shè)計模式離我們有點遙遠(yuǎn),是因為我們現(xiàn)在都在用大佬寫好的框架吧,很多設(shè)計模式都包含在框架里了。
后面有機(jī)會的話,我希望我可以查看目前主流框架的源代碼,然后進(jìn)行講解。
對應(yīng)的代碼,請查看
https://github.com/D1N910/JavaScript-design-patterns.git

第四篇 行為型設(shè)計模式
行為型設(shè)計模式用于不同對象之間職責(zé)劃分或算法抽象,行為型設(shè)計模式不僅僅涉及類和對象,還涉及類或?qū)ο笾g的交流模式并加以實現(xiàn)。
第 24?章 備忘錄模式(P164)
備忘錄模式(Memento):在不破壞對象的封裝性的前提下,在對象之外捕獲并保存該對象內(nèi)部的狀態(tài)以便日后對象使用或者恢復(fù)到以前的某個狀態(tài)。
這種場景一般用來緩存數(shù)據(jù),比如我們的新聞頁面請求數(shù)據(jù),用戶訪問第一頁的時候請求數(shù)據(jù),到了第二頁的時候再請求一次,然后回到第一頁,這時候還需要請求數(shù)據(jù)的話,用戶體驗就不是很好了。
如果我們能夠像有備忘錄一樣,存儲剛剛訪問的第一頁數(shù)據(jù),那么體驗就會好很多。
下見代碼:
var paper = 0, // 當(dāng)前頁數(shù)
num = 5, // 每頁顯示新聞數(shù)目
i = 0; // 創(chuàng)建新聞元素時保持變量
// 請求新聞
var requestNews = (function () {
? ?var newsCache = {};
? ?return {
? ? ? ?getNews(page, fn) {
? ? ? ? ? ?if (newsCache[page]) {
? ? ? ? ? ? ? ?fn(newsCache[page]);
? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?setTimeout(function () {
? ? ? ? ? ? ? ? ? ?newsCache[page] = (function () {
? ? ? ? ? ? ? ? ? ? ? ?var i = 0
? ? ? ? ? ? ? ? ? ? ? ?var data = []
? ? ? ? ? ? ? ? ? ? ? ?while(i < num) {
? ? ? ? ? ? ? ? ? ? ? ? ? ?data.push('新聞' + page + '_' + i);
? ? ? ? ? ? ? ? ? ? ? ? ? ?i++;
? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ?return data
? ? ? ? ? ? ? ? ? ?})();
? ? ? ? ? ? ? ? ? ?fn(newsCache[page]);
? ? ? ? ? ? ? ?}, 1000)
? ? ? ? ? ?}
? ? ? ?}
? ?}
})()
var flyWeight = function () {
? ?// 已創(chuàng)建的元素
? ?var created = [];
? ?// 創(chuàng)建一個新聞包裝元素
? ?function create() {
? ? ? ?var div = document.createElement('div');
? ? ? ?document.getElementById('container').appendChild(div);
? ? ? ?created.push(div);
? ? ? ?return div;
? ?}
? ?return {
? ? ? ?getDiv() {
? ? ? ? ? ?if (created.length < num) {
? ? ? ? ? ? ? ?return create();
? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?var div = created.shift();
? ? ? ? ? ? ? ?created.push(div);
? ? ? ? ? ? ? ?return div;
? ? ? ? ? ?}
? ? ? ?}
? ?}
}()
requestNews.getNews(++paper, function (params) {
? ?for (var k = 0; k < num; k++) {
? ? ? ?flyWeight.getDiv().innerHTML = params[k];
? ?}
})
// 上一頁面綁定事件
document.getElementById('pre_page').onclick = function() {
? ?requestNews.getNews(--paper, function (params) {
? ? ? ?for (var k = 0; k < num; k++) {
? ? ? ? ? ?flyWeight.getDiv().innerHTML = params[k];
? ? ? ?} ?
? ?})
}
// 下一頁綁定事件
document.getElementById('next_page').onclick = function() {
? ?requestNews.getNews(++paper, function (params) {
? ? ? ?for (var k = 0; k < num; k++) {
? ? ? ? ? ?flyWeight.getDiv().innerHTML = params[k];
? ? ? ?} ?
? ?})
}
備忘錄模式是非常用的設(shè)計,很多 MVC 模式也是用了備忘錄模式來緩存數(shù)據(jù)。當(dāng)然,我們也不能緩存太多數(shù)據(jù),所以可以更進(jìn)一步,比如時不時清理一下不常用的數(shù)據(jù)。這就等待后繼去拓展了。
本章 End
d1n910 于 2021年03月04日 寫于南山后海