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),状态模式是对象的行为模式. 状态模式主要解决的是当控制一个对象状态的条件表达式过于 ...
随机推荐
- Vmware 15 新建虚拟机黑屏
win10 的磁盘大小设置60的倍数 centos 使用 40g
- JSP+JavaBean 登陆验证
1.java package cn.gs.ly; import java.util.HashMap; import java.util.Map; public class Register { pri ...
- MySQL5.7的搭建以及SSL证书
Centos7 安装MySQL 5.7 (通用二进制包) 1.1 下载软件包 https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.17-l ...
- 如何创建linux虚拟机
一.安装配置linux虚拟机 第1步:运行"Vmware WorkStation",看到主页面. 第2步:创建新的虚拟机,新建虚拟机向导——典型(推荐). 第3步:选择稍后安装操作 ...
- C#=> 栈模仿堆的操作
//原理,利用两个栈,互相作用,来模仿堆的效果,先进先出.. using System; using System.Collections.Generic; using System.Linq; us ...
- 转 python 字符串前加r
在打开文件的时候open(r'c:\....') 加r和不加''r是有区别的 'r'是防止字符转义的 如果路径中出现'\t'的话 不加r的话\t就会被转义 而加了'r'之后'\t'就能保留原有的样子 ...
- Socket编程半双工
服务器 package com.test; import java.io.IOException; import java.net.*; import java.io.*; public class ...
- spring-第十八篇之spring AOP基于XML配置文件的管理方式
1.在XML配置文件中配置切面.切入点.增强处理.spring-1.5之前只能使用XML Schema方式配置切面.切入点.增强处理. spring配置文件中,所有的切面.切入点.增强处理都必须定义在 ...
- [poj3074]Sudoku(舞蹈链)
题目链接:http://poj.org/problem?id=3074 舞蹈链精确覆盖的经典题目,一个数独每个位置的要求,可以得到以下四个约束1.每个位置有且只有一个数字2.每个位置的数字在一行只能出 ...
- python学习第十五天字典的创建及增删改查操作方法
字典是python比较常见的数据类型,跟列表一样,比如的字典的创建,字典的常见的操作的方法,增加,删除,修改,查找等方法,字典的一共的数据方法为 keys() values() fromkeys() ...