細品 javascript 設計模式(策略模式)
我儘量用最少的文字,最少的篇幅,講明白設計模式的方方面面。
理解策略模式
把 演算法 和 呼叫演算法 的部分做拆分開
我舉個例子吧:你想要去三亞旅遊,途徑有很多種:飛機,火車,自駕遊。這幾種方法都可以到達目的地,但是過程是有所不同的。
- 飛機:適合緊急不差錢的情況
- 火車:適合不緊急,並且目的明確(公司團建,中老年旅遊)
- 自駕遊:這種比較隨性,和朋友家人一起出門,一起欣賞路過的風景。
每一種選擇,都是一種策略。
在程式中策略的意義在於,把處理不同任務但目的相同的程式碼整合在一起。再用一層函式委託他們來處理具體的演算法。這樣可以消除原本程式中大片的條件分支語句
上程式碼: 策略模式(計算不同的旅行方式到達時間)
// 定義策略
var strategies = {
'plane': function(distance) {
return distance * 1; // 假設飛機的速度最快
},
'train': function(distance) {
return distance * 4; // 飛機的速度是火車的4倍
},
'roadTrip': function(distance) {
return distance * 10; // 飛機的速度是自駕遊的10倍
},
}
// Context
var calculateBonus = function(mode, distance) {
if (typeof strategies[mode] === 'function') {
return strategies[mode](distance);
}
return -1;
}
// 呼叫策略
console.log(calculateBonus('plane', 1000));
console.log(calculateBonus('train', 1000));
console.log(calculateBonus('roadTrip', 1000));
策略模式是比較好理解的,我們們先看一段即將被策略模式改造的程式碼
使用策略模式之前
var calculateBonus = function(mode, distance) {
if (mode === 'plane') {
return distance * 1;
} else if (mode === 'train') {
return distance * 4;
} else if (mode === 'roadTrip') {
return distance * 10;
}
return -1;
}
這段程式碼最大的問題是, 程式碼可複製性差, 不利於維護。每次有新的改動都必須扒開程式碼,找到具體的某個函式去修改。效率低,容易引發連貫性錯誤。
使用策略模式,實現緩懂動畫函式
為了更加明確策略模式的使用場景,我們一起來實現一個動畫函式。
js 動畫原理改變 dom 的 css 屬性,比如 left, top, background-position。所以至少要提供一下一些資訊。
- dom 最初的位置
- 目標位置
- 開始時間
- 結束時間
然後配合定時器 setInterval 在定時器中每個 19 毫秒改變一次 dom 的 css 屬性,每次修改 dom 時把上面的4個引數傳給演算法。演算法會計算出當前應該所在的位置。最後在更新 dom 的 css 屬性。這樣動畫就完成了。
演算法部分,這裡最初來自 Flash 但現在 css3 部分也是這樣實現的
// 先定義動畫緩動演算法
var tween = {
linear: function(t, b, c, d) {
return c * t / d + b;
},
easeIn: function(t, b, c, d) {
return c * (t /= d) * t + b;
},
strongEaseIn: function(t, b, c, d) {
return c * (t /= d) * t * t * t * t + b;
},
strongEaseOut: function(t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
},
sineaseIn: function(t, b, c, d) {
return c * (t /= d) * t * t + b;
},
sineaseOut: function(t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
}
}
然後在 body 中新增入下節點
<div style="position: absolute; background:yellow;">im div</div>
接下來定義動畫類
let Animate = function(dom) {
this.dom = dom;
this.startTime = 0;
this.startPos = 0;
this.endPos = 0;
this.propertyName = null;
this.esing = null;
this.duratin = null;
}
Animate.prototype.start = function(propertyName, endPos, duratin, esing) {
this.startTime = Date.now();
this.startPos = this.dom.getBoundingClientRect()[propertyName];
this.propertyName = propertyName;
this.endPos = endPos;
this.duratin = duratin;
this.esing = tween[esing];
let self = this;
let timeId = setInterval(function() {
if (self.step() === false) {
clearInterval(timeId)
}
}, 19)
}
Animate.prototype.step = function() {
var t = Date.now();
if (t >= this.startTime + this.duratin) {
this.update(this.endPos)
return false
}
var pos = this.esing(
t - this.startTime, // 時間
this.startPos, // 開始值
this.endPos - this.startPos, // 運動距離
this.duratin // 總耗時
)
this.update(pos);
}
Animate.prototype.update = function(pos) {
this.dom.style[this.propertyName] = pos + 'px';
}
來測試一下!
var div = document.getElementsByTagName('div')[0];
var animate = new Animate(div);
animate.start('left', 500, 1000, 'linear')
// animate.start('left', 500, 1000, 'easeIn')
// animate.start('left', 500, 1000, 'strongEaseIn')
// animate.start('left', 500, 1000, 'strongEaseOut')
// animate.start('left', 500, 1000, 'sineaseIn')
// animate.start('left', 500, 1000, 'sineaseOut')
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/854/viewspace-2825695/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Javascript設計模式(四)策略模式JavaScript設計模式
- JavaScript 設計模式之策略模式JavaScript設計模式
- Javascript設計模式之策略模式JavaScript設計模式
- javascript設計模式 之 2 策略模式JavaScript設計模式
- 【技巧篇】JavaScript設計模式之策略模式應用JavaScript設計模式
- JavaScript設計模式之策略模式【組合委託】JavaScript設計模式
- 設計模式(策略模式)設計模式
- 設計模式-策略模式設計模式
- 設計模式——策略模式設計模式
- 《JavaScript設計模式與開發實踐》模式篇(2)—— 策略模式JavaScript設計模式
- 小白設計模式:策略模式設計模式
- 設計模式之策略模式設計模式
- 設計模式🔫---策略模式設計模式
- js設計模式--策略模式JS設計模式
- 設計模式之【策略模式】設計模式
- 設計模式 #5 (策略模式、代理模式)設計模式
- 【設計模式】漢堡中的設計模式——策略模式設計模式
- PHP設計模式(3)—— 策略模式PHP設計模式
- JS設計模式六:策略模式JS設計模式
- 《Head First 設計模式》:策略模式設計模式
- PHP 設計模式之策略模式PHP設計模式
- python設計模式之策略模式Python設計模式
- Java設計模式-策略模式分析Java設計模式
- 設計模式專題-策略模式設計模式
- 設計模式(一) 支付策略模式設計模式
- 極簡設計模式-策略模式設計模式
- 略懂設計模式之策略模式設計模式
- GoLang設計模式15 - 策略模式Golang設計模式
- JAVA設計模式之策略模式Java設計模式
- 23種設計模式(二)---策略設計模式設計模式
- 設計模式第二講--策略模式設計模式
- 設計模式漫談之策略模式設計模式
- Head First 設計模式(1)-----策略模式設計模式
- c/c++設計模式---策略模式C++設計模式
- Java設計模式之(十四)——策略模式Java設計模式
- Java設計模式之策略模式示例Java設計模式
- Javascript設計模式之代理模式JavaScript設計模式
- Javascript設計模式(五)代理模式JavaScript設計模式