当前位置:首页 > JS > JavaScript设计模式 – 策略模式

JavaScript设计模式 – 策略模式

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

做了一个demo,给你们上一张图片,就是你选择哪一个它就会不同的走。

javascript

策略模式指的是定义一些列的算法,把他们一个个封装起来,目的就是将算法的使用与算法的实现分离开来。
以策略模式的思路实现上边例子的效果的js代码:
1. 首先封装移动节点的缓动算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * 缓动算法: 接收4个参数,分别表示: 动画已消失的时间, 小球原始位置, 小球目标位置, 动画持续的总时间
 */
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;
    }
};

2. HTML 部分

1
2
3
4
5
6
7
8
9
10
11
12
<div style="position: relative;border: 1px solid #ff0000; width: 560px;min-height: 30px">
        <div style="position:absolute;background:rgba(0,0,255,.3);width: 60px;line-height: 30px;" id="div">我是 div</div>
    </div>
    <div>
        <label><input type="radio" name="tween" value="linear" checked="checked">linear</label>
        <label><input type="radio" name="tween" value="easeIn">easeIn</label>
        <label><input type="radio" name="tween" value="strongEaseIn">strongEaseIn</label>
        <label><input type="radio" name="tween" value="strongEaseOut">strongEaseOut</label>
        <label><input type="radio" name="tween" value="sineaseIn">sineaseIn</label>
        <label><input type="radio" name="tween" value="sineaseOut">sineaseOut</label><br/>
        <input type="button" id="btnRun" value="run">
    </div>

3. 定义一个构造函数接收一个参数:即将运动起来的dom节点

1
2
3
4
5
6
7
8
9
10
11
12
/*
 *    Animate 的构造函数接收一个参数:即将运动起来的 dom 节点。
 */
var Animate = function( dom ){
    this.dom = dom; // 进行运动的 dom 节点
    this.startTime = 0; // 动画开始时间
    this.startPos = 0; // 动画开始时, dom 节点的位置,即 dom 的初始位置
    this.endPos = 0; //
    this.propertyName = null; // dom 节点需要被改变的 css 属性名
    this.easing = null; // 缓动算法
    this.duration = null; // 动画持续时间
};

4. 启动方法,负责启动这个动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * 负责启动运动动画
 */
Animate.prototype.start = function( propertyName, endPos, duration, easing ){
    this.startTime = +new Date; // 启动动画的时间
    this.startPos = this.dom.getBoundingClientRect()[ propertyName ]; // dom 节点的初始位置
    this.propertyName = propertyName; // dom 节点需要被改变的 CSS 属性名
    this.endPos = endPos; // dom 节点的目标位置
    this.duration = duration; // 动画的持续时间
    this.easing = tween[ easing ]; // 缓动算法
 
    // 启动动画定时器
    var self = this;
    var timeId = setInterval(function(){
        if( self.step() === false){
            clearInterval(timeId);
        }
    },20);
};

javascript

5. 动画定时器运行的步骤,setp方法,节点运动的每一帧要做的事情

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * step 表示节点运动的每一帧要做的事情。 负责计算节点的当前位置和调整更新 CSS 属性值
 */
Animate.prototype.step = function(){
    var t = +new Date; // 取得当前时间
    if( t >= this.startTime + this.duration){ // 如果动画结束
        this.update( this.endPos ); // 更新节点的 CSS 属性
        return false;
    }
    var pos = this.easing( t - this.startTime, this.startPos, this.endPos - this.startPos, this.duration);
    // pos 为节点当前位置
    this.update( pos ); // 更新节点的 CSS 属性
};

6. 更新节点的CSS属性值

1
2
3
4
5
6
 /*
 * 负责更新节点 CSS 属性值
 */
 Animate.prototype.update = function(pos){
    this.dom.style[ this.propertyName ] = pos + "px";
 };

7. 测试运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
     * 创建要运动的节点
     */
    var div = document.getElementById("div");
    var animate = new Animate(div);
    // 设置运行事件
    var btnRun = document.getElementById("btnRun");
    var radios = document.getElementsByName("tween"); // 获取单选框
    btnRun.onclick = function(){
        for(var i= 0,lengh=radios.length;i<lengh;i++){
            // 查找被选中要执行的算法策略
            if(radios[i].checked){
                animate.reset(); // 重置节点运动属性
                // 设置动画的基本属性
                animate.start( "left", 500, 1000, radios[i].value);
                break;
            }
        }
    };

8. 重置节点的CSS属性为0,reset()方法

1
2
3
4
Animate.prototype.reset = function(){
        // 重置为 0
    this.dom.style[this.propertyName] = "0px";
};

策略模式总结

策略模式的优点:

  1. 策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重条件选择语句
  2. 策略模式提供了对开放-封闭原则的完美支持,将算法封装在独立的 strategy 中,使得它们易于切换,易于理解,易于扩展.

策略模式的缺点:

  1. 会在程序中增加许多策略类或者策略对象,但实际上比把他们负责的逻辑堆砌在 Context 中要好
  2. 使用策略模式,必须了解所有的策略,才能更好的选择一个合适的策略

  • << Objective-C多态学习
  • 关于程序员面试的那些事 >>
  • 作者:
    除非注明,本文原创:知道91,欢迎转载!转载请以链接形式注明本文地址,谢谢。
    原文链接:http://www.zhidao91.com/javascript-model/

    相关文章 近期热评 最新文章

    • HTML+CSS+JS 实现图标旋转效果
      本文讲解了使用HTML+CSS+JS 实现图标旋转效果。
    • js怎样获取和设置元素的属性
      本文讲解了js获取和设置元素的属性的方法,有需要的朋友可以看看
    • Node.Js 不一般的JavaScript
      互联网的火热使得JavaScript风光无限,且服务端的JavaScript也并不是什么新技术了,相关的框架也有不少,只是node.js的成功让他爆发式的出现在我们的视线中,让很多前端...
    • 前端程序员必须知道的优化小知识
      前端开发人员的一些小知识,Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多网站无情忽视的技术。除了后台需要在性能上做优化外,其实前端的页面...
    • HTML5与CSS3的完美搭配
      TML5将会取代1999年制定的HTML 4.01、XHTML 1.0标准,以期能在互联网应用迅速发展的时候,使网络标准达到符合当代的网络需求,为桌面和移动平台带来无缝衔接的丰富内容。
    • 前端程序员必须知道的chrome开发者技巧
      在Web开发者中,Google Chrome是使用最广泛的浏览器。六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具。你可能已经熟悉了它的部分功能...
    • 怎样在WordPress中安装Google Analytics
      就算你积累了多年网站建设的经验,你都不可能一开始就建一个外观,速度,功能以及转化都很完美的网站。你能做的并且也是各个站长正在做的,无非是通过不断的监测来改进...
    • 怎样在WordPress中安装Google Analytics
      就算你积累了多年网站建设的经验,你都不可能一开始就建一个外观,速度,功能以及转化都很完美的网站。你能做的并且也是各个站长正在做的,无非是通过不断的监测来改进...
    • oracle数据库相关操作注意事项
      修改Oracle SGA(共享内存) 很多网站说修改Oracle的内存通过命令 如果你这么做了,那么恭喜你,你的Oracle数据库无法启动了。如果你已经这么做了,恢复Oracle启动的方...
    • 使用微信JDK实现微信接口签名验证
      要使用微信的接口必须在绑定的域名下测试;签名必须先向微信请求到access_token,然后用access_token再去请求jsapi_ticket,最后用jsapi_ticket和相关的参数按照ASCII码...
    • ABP开发指南系列教程(2) – 多层架构...
      为了减少复杂性和提高代码的可重用性,采用分层架构是一种被广泛接受的技术。为了实现分层的体系结构,ABP遵循DDD(领域驱动设计)的原则,将工程分为四个层: 展现层(...
    • ABP开发指南系列教程(1) – 入...
      ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。 ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WE...
    • Windows下 JIRA + Agile + Mysql 破解...
      本文讲述了Windows下 JIRA + Agile + Mysql 破解安装示例教程