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),状态模式是对象的行为模式. 状态模式主要解决的是当控制一个对象状态的条件表达式过于 ...
随机推荐
- python装饰器(基础中的重点)
一.简单的装饰器 1.为什么要使用装饰器呢? 装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展 装饰器的本质:就是一个闭包函数 那么我们先来看一个简单的装饰器:实现计算每个函数的执 ...
- HDU 1255 覆盖的面积 ( 扫描线 + 离散 求矩阵大于k次面积并 )
覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- 完善Hikari连接池扩展项目HikariApi(ORM)
以前介绍类自定义的Hikari项目,定位于数据库连接池:后扩展了,根据文件名称,以数据库配置文件为基础,支持按照名称多数据操作. 在使用中,发现扩展了SQL语句参数化操作,在管理类中,以扩展方法存在. ...
- [三下五除二]在Eclipse上的JFinal_Demo
承接上回在IDEA的JFinal的项目的导入,今次同样是同一个文件,但在Eclipse上运行.在Eclipse上运行官网的JFinal的例子是及其快捷. 打开Eclipse,并进入如下的界面. 点击导 ...
- elasticsearch 基础 —— Common Terms Query常用术语查询
常用术语查询 该common术语查询是一个现代的替代提高了精确度和搜索结果的召回(采取禁用词进去),在不牺牲性能的禁用词. 问题 查询中的每个术语都有成本.搜索"The brown fox& ...
- 【知识强化】第四章 指令系统 4.3 CISC和RISC的基本概念
那么我们进入本章的最后一节,CISC和RISC. 我们先来回顾一下,我们这一章的一个概览.我们之前已经把指令格式和指令的寻址方式都讲完了,这两部分呢是本章的一个重点.而本章的这一部分,CISC和RIS ...
- 实现多线程的三种方法:Thread、Runnable和Callable
继承Thread类,重写run()方法 步骤: (1) 定义类继承Thread类 (2) 复写Thread类中的run方法. (3) 调用线程的start方法 (start方法有两种含义:1. 启动多 ...
- spring boot集成mongodb的增删改查
添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...
- 牛客网NOIP赛前集训营-提高组(第六场)B-选择题
题目描述 有一道选择题,有 a,b,c,d 四个选项. 现在有 n 个人来做这题,第 i 个人有 pi,j 的概率选第 j 个选项. 定义\(cnt(x)\)为选第$ x $个选项的人数. 令\(mx ...
- cornerNet部分学习内容记录
cornerNet来源灵感是基于多人姿态估计的从下往上思想,预测角的热图,根据嵌入式向量对角进行分组,其主干网络也来自于姿态估计的环面网络. cornerNet的总体框架结构图如下: CornerN ...