JavaScript设计模式-----命令模式的简单应用

命令模式是最简单和优雅的模式之一,命令模式中的命令(command)是指一个执行某些特定事情的指令。

应用场景:有时候需要向某些对象发送请求,但是并不知道请求的接受者是谁,也不知道被请求的操作是什么,此时希望用一种

松解耦的方式来设计软件,使得请求发送者和请求接受者能够消除彼此之间的耦合关系。

一个简单JavaScript例子:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>命令模式</title>
  6     <style>
  7         body{
  8             padding:  0;
  9             margin: 0;
 10         }
 11         .ball{
 12             position: absolute;
 13             background: #000;
 14              50px;
 15             height: 50px;
 16             top:  200px;
 17         }
 18     </style>
 19 </head>
 20 <body>
 21     <div id="ball" class="ball"></div>
 22     输入小球移动后的位置:<input type="text" id="pos">
 23     <button id="moveBtn">开始移动</button>
 24     <button id="cancelBtn">cancel</button>
 25     <script>
 26 
 27         // 营运策略模式封装一系列缓动算法
 28         // t:已消耗的时间 b:小球的原始位置   c:小球的目标位置  d:动画持续的总时间
 29         // 返回当前位置
 30         var tween = {
 31             linear: function(t, b, c, d) {
 32                 return c*t/d + b;
 33             },
 34             easeIn: function(t, b, c, d) {
 35                 return c * (t /= d) * t + b;
 36             },
 37             strongEaseIn: function(t, b, c, d) {
 38                 return c * (t /= d) * t * t * t + b;
 39             },
 40             strongEaseOut: function(t, b, c, d) {
 41                 return c * (( t = t / d - 1 ) * t * t * t * t + 1) + b;
 42             },
 43             sineaseIn: function(t, b, c, d) {
 44                 return c * (t /= d) * t * t + b;
 45             },
 46             sineaseOut: function(t, b, c, d) {
 47                 return c * (( t = t / d - 1) * t * t + 1) + b;
 48             }
 49         };
 50 
 51         // 定义动画类
 52         var Animate = function(dom) {
 53             this.dom = dom;
 54             this.startTime = 0;
 55             this.startPos = 0;
 56             this.endPos = 0;
 57             this.propertyName = null;
 58             this.easing = null;
 59             this.duration = null;
 60         }
 61 
 62         // 动画启动
 63         Animate.prototype.start = function(propertyName, endPos, duration, easing) {
 64             this.propertyName = propertyName;
 65             this.startTime = +new Date();
 66             this.startPos = this.dom.getBoundingClientRect()[propertyName];
 67             this.endPos = endPos;
 68             this.duration = duration;
 69             this.easing = tween[easing];
 70 
 71             var self = this;
 72             var timeId = setInterval(function() {
 73                 if (self.step() === false) {
 74                     clearInterval(timeId);
 75                 }
 76             }, 1000/60)
 77         }
 78 
 79         Animate.prototype.step = function() {
 80             var t = +new Date();
 81             if (t > this.startTime + this.duration) {
 82                 this.update(this.endPos);
 83                 return false;
 84             }
 85             var pos = this.easing(t - this.startTime, 
 86                 this.startPos, this.endPos - this.startPos, this.duration);
 87             this.update(pos);
 88         }
 89 
 90         Animate.prototype.update = function( pos ) {
 91             this.dom.style[ this.propertyName ] = pos + 'px';
 92         }
 93 
 94 
 95         var ball = document.getElementById('ball');
 96         var pos = document.getElementById('pos');
 97         var moveBtn = document.getElementById('moveBtn');
 98         var cancelBtn = document.getElementById('cancelBtn');
 99 
100         // 使用命令模式实现事件和dom的解耦
101         var MoveCommand = function(receiver, pos) {
102             this.receiver = receiver;
103             this.pos = pos;
104             this.oldPos = null;
105         }
106 
107         MoveCommand.prototype.excute = function() {
108             this.receiver.start('left', this.pos, 1000, 'strongEaseOut');
109             this.oldPos = this.receiver.dom.getBoundingClientRect()[this.receiver.propertyName];
110         }
111 
112         MoveCommand.prototype.undo = function() {
113             this.receiver.start('left', this.oldPos, 1000, 'strongEaseOut');
114         }
115 
116         var moveCommand;
117 
118         moveBtn.onclick = function() {
119             var animate = new Animate( ball );
120             moveCommand = new MoveCommand(animate, pos.value);
121             moveCommand.excute();
122         }
123 
124         cancelBtn.onclick = function() {
125             console.log(moveCommand);
126             moveCommand.undo();
127         }
128     </script>
129 </body>
130 </html>
原文地址:https://www.cnblogs.com/cangqinglang/p/9795646.html