js策略模式vs状态模式
一.策略模式
1.定义:把一些小的算法,封装起来,使他们之间可以相互替换(把代码的实现和使用分离开来)
2.利用策略模式实现小方块缓动
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.优缺点
优点:避免多重条件判断语句;遵循开放-封闭原则,具有较好的扩展性,便于切换;可复用性;
缺点:违背最少知识原则(向用户暴露所有的实现)
二.状态模式
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()调用,达到和状态模式一样的效果
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无限膨胀
缺点:代码逻辑分散在各个类中,造成逻辑分散的问题
三.对比两种模式
相同点:这两种模式都只有一个上下文、一些策略类或者是状态类,上下文把请求委托给这些类来执行
不同点:这两种模式的目的是不同的;策略模式的策略类之间是相互平行平等的,而状态模式的状态类把状态和行为封装到一起,把逻辑实现封装到类中,状态之间的切换也早被规定完成.
js策略模式vs状态模式的更多相关文章
- Java 策略模式和状态模式
本文是转载的,转载地址:大白话解释Strategy模式和State模式的区别 先上图: 本质上讲,策略模式和状态模式做得是同一件事:去耦合.怎么去耦合?就是把干什么(语境类)和怎么干(策略接口)分开, ...
- 《大话》之 策略模式 Vs 状态模式
一.简介: 策略模式: 背景:商店要打折销售,各种版本的销售方式,让小菜心烦意乱 内容: 定义算法家族,分别封装起来,让他们之间可以户型替换,此模式让算法的变化,不会影响到使用算法的用户. 图文 ...
- Java设计模式之策略模式与状态模式
版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. ...
- java - 策略模式、状态模式、卫语句,避免多重if-else(转)
前言 当代码中出现多重if-else语句或者switch语句时.弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处 ...
- 【设计模式】 模式PK:策略模式VS状态模式
1.概述 行为类设计模式中,状态模式和策略模式是亲兄弟,两者非常相似,我们先看看两者的通用类图,把两者放在一起比较一下. 策略模式(左)和状态模式(右)的通用类图. 两个类图非常相似,都是通过Cont ...
- Java重构-策略模式、状态模式、卫语句
前言 当代码中出现多重if-else语句或者switch语句时.弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处 ...
- 【转】Java重构-策略模式、状态模式、卫语句
前言 当代码中出现多重if-else语句或者switch语句时.弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处 ...
- 设计模式之策略模式和状态模式(strategy pattern & state pattern)
本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过 ...
- 策略模式 VS 状态模式
策略模式 VS 状态模式 策略模式 VS 状态模式 | 菜鸟教程 https://www.runoob.com/w3cnote/state-vs-strategy.html
- 大熊君说说JS与设计模式之------状态模式State
一,总体概要 1,笔者浅谈 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式. 状态模式主要解决的是当控制一个对象状态的条件表达式过于 ...
随机推荐
- IDEA activate-power-mode插件
一 下载activate-power-mode插件 方法1:插件库下载: 地址:http://plugins.jetbrains.com/plugin/8330-activate-power-mode ...
- Unity3D热更新方案网摘总结
参考:http://blog.csdn.net/guofeng526/article/details/52662994 http://blog.csdn.net/u010019717/article/ ...
- 应用安全-Web安全-越权漏洞整理
login->register GetPhone->GetPasswd GetPwd->GetPassword 遍历https://xx.com/contacts/new?user_ ...
- Android 中三种启用线程的方法
在多线程编程这块,我们经常要使用Handler(处理),Thread(线程)和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢? 首先说明Android的CPU分配的最小单元是线程,Han ...
- MySQL错误信息语言设置为英文
MySQL错误信息语言设置为英文 安装的wamp环境中,mysql的错误提示信息默认不是英语(大概是法语) 这里说下改为英语的过程 第一步 找到以下文件夹,确保里面可以看到各种"国际方言&q ...
- jsp:useBean的属性class值一直报错的问题
先附上代码: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8 ...
- html中head示例
<!DOCTYPE html> <!-- #统一的规范--> <!--类似html这种 ,html标签<html>dasdasd</html>&g ...
- oracle ALL视图
select * from ALL_ALL_TABLES -- 用户可存取的所有表. select * from ALL_BASE_TABLE_MVIEWS -- 用户可存取的所有物化视 ...
- ssh-agent - 认证代理
总览 (SYNOPSIS) ssh-agent [-a bind_address ] [-c | -s ] [-t life ] [-d ] [command [args ... ] ] ssh-ag ...
- smbpasswd - Samba加密的口令文件。
总览 SYNOPSIS smbpasswd 描述 DESCRIPTION 此文件是 Samba(7) 套件的一部分. smbpasswd是Samba加密的口令文件.文件中包含了用户名,UNIX用户ID ...