1.定義:把一些小的算法,封裝起來,使他們之間能夠相互替換(把代碼的實現和使用分離開來)
2.利用策略模式實現小方塊緩動css
html代碼:html
<div id="container" style="width:500px;margin:0 auto;background-color: silver;"> <div id="move" style="position: absolute;background-color:blue;width:20px;height:20px"></div> </div>
js代碼:算法
var container = document.getElementById('container'); container.style.height = window.innerHeight +"px"; var tween = {//t動畫已消耗時間、b原始位置、c目標位置、d持續時間 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; } }; var animate = function(dom){ this.dom = dom; this.startTime = 0; this.startPos = 0; this.endPos = 0; this.duration = 0;//小球運動的時間 this.propertyName = null;//要改變的css屬性,例如top,left this.easing=null;//緩動算法 }; animate.prototype.start = function(endPos,duration,propertyName,easing){ //記錄開始位置,並設置定時器是否有要執行的步數 this.startTime = new Date(); this.startPos = this.dom.getBoundingClientRect()[propertyName]; this.endPos = endPos; this.duration = duration; this.propertyName = propertyName; this.easing = tween[easing]; var setTime = setInterval(function(){ if(this.step()){ clearsetInterval(setTime); } this.step(); }.bind(this),20) } animate.prototype.step = function(){//動畫執行一步須要的操做 var t = +new Date(); if(t>this.startTime+this.duration){ this.update(this.endPos); return false; } var pos = this.easing(t-this.startTime,this.startPos,this.endPos,this.duration);//t動畫已消耗時間、b原始位置、c目標位置、d持續時間 this.update(pos); } animate.prototype.update = function(pos){//更新div的css屬性 if(pos > window.innerWidth || pos>window.innerHeight){ this.dom.style[this.propertyName] = this.endPos +'px'; return false; } this.dom.style[this.propertyName] = pos +'px'; } //調用 var move = document.getElementById('move'); var a = new animate(move); a.start(100,1000,'bottom','sineaseIn')
3.優缺點
優勢:避免多重條件判斷語句;遵循開放-封閉原則,具備較好的擴展性,便於切換;可複用性;
缺點:違背最少知識原則(向用戶暴露全部的實現)dom
1.定義:容許一個對象在其狀態改變時改變他的行爲,對象看起來視乎修改了他的類
2.狀態模式例子:電源開關三種狀態的互相變化(狀態驅動行爲)動畫
var Light = function(){ this.offState = new offLightState(this); this.weakState = new weakLightState(this); this.strongState = new strongLightState(this); this.button = null; } Light.prototype.start = function(){ this.button = document.getElementById('change'); this.current = this.offState; this.button.onclick = function(){ this.current.btnPressed(); }.bind(this); } Light.prototype.setState = function(newState){//改變狀態 this.current = newState; } //狀態模式的關鍵是把每種狀態都封裝成一個類 var offLightState = function(light){ this.light = light; }; offLightState.prototype.btnPressed = function(){ console.log('調弱'); this.light.setState(this.light.weakState); } var weakLightState = function(light){ this.light = light; }; weakLightState.prototype.btnPressed = function(){ console.log('調強'); this.light.setState(this.light.strongState); } var strongLightState = function(light){ this.light = light; }; strongLightState.prototype.btnPressed = function(){ console.log('關閉'); this.light.setState(this.light.offState); } var light = new Light(); light.start();//調弱 調強 關閉
3.狀態模式是狀態機的一種實現方式,還能夠直接將狀態委託給字面量,利用Function.prototype.call()調用,達到和狀態模式同樣的效果this
var FMC = { on:{ buttonWasPressed:function(){ console.log('變弱') this.current = FMC.weak; } }, weak:{ buttonWasPressed:function(){ console.log('變強') this.current = FMC.strong; } }, strong:{ buttonWasPressed:function(){ console.log('變動強') this.current = FMC.superstrong; } }, superstrong:{ buttonWasPressed:function(){ console.log('關閉') this.current = FMC.off; } }, off:{ buttonWasPressed:function(){ console.log('打開') this.current = FMC.on; } } } var light = function(){ this.current = FMC.off; this.button = null; } light.prototype.start = function(){ this.button = document.getElementById('change'); console.log("current",this.current) this.button.onclick = function(){ this.current.buttonWasPressed.call(this); }.bind(this); } var l = new light(); l.start();
4.優缺點
優勢:可擴展性較好,能夠方便的增長新的狀態;相比冗餘的if else判斷,狀態模式將邏輯封裝在類中,避免Context無限膨脹
缺點:代碼邏輯分散在各個類中,形成邏輯分散的問題prototype
相同點:這兩種模式都只有一個上下文、一些策略類或者是狀態類,上下文把請求委託給這些類來執行
不一樣點:這兩種模式的目的是不一樣的;策略模式的策略類之間是相互平行平等的,而狀態模式的狀態類把狀態和行爲封裝到一塊兒,把邏輯實現封裝到類中,狀態之間的切換也早被規定完成.code