龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > Javascript编程 >

JavaScript重构深入剖析(1)(4)

时间:2013-03-06 14:58来源:未知 作者:admin 点击:
分享到:
重用老代码 在Java中,有这样一段老代码: class Round{ public void drawRound(); //画圆 } 现在新代码希望能和它共存,使用一个Person的对象来控制,只不过,可能

重用老代码

在Java中,有这样一段老代码:

  1. class Round{   
  2.     public void drawRound(); //画圆   

现在新代码希望能和它共存,使用一个Person的对象来控制,只不过,可能drawRound,也可能drawRect啊:

  1. class Rect{   
  2.     public void drawRect(); //画方   

好,废话少说,我先想到了Adapter模式:

  1. interface Drawable{   
  2.     public void draw();   
  3. }  
  4.  
  5. public class RoundAdapter implements Drawable{   
  6.     private Round round;   
  7.     public void draw(){   
  8.         round.drawRound();   
  9.     }   
  10. }  
  11.  
  12. public class RectAdapter implements Drawable{   
  13.     private Rect rect;   
  14.     public void draw(){   
  15.         rect.drawRect();   
  16.     }   

然后,我再引入一个Person对象,就能搞定这一切了:

  1. class Person{   
  2.     private Drawable adapter;   
  3.     public Person(Drawable adapter){   
  4.         this.adapter = adapter;   
  5.     }   
  6.     public void draw(){   
  7.         this.adapter.draw();   
  8.     }   
  9. }  
  10.  
  11. Drawable rou = new RoundAdapter();   
  12. Drawable rec = new RectAdapter();   
  13. new Person(rou).draw(); //画圆   
  14. new Person(rec).draw(); //画方 

想必到此已经让你烦了,一个Adapter模式的最简单例子。再多看一看,这个模式的核心是什么?接口!对,正是例子中的Drawable接口――正是在接口的规约和领导下,我们才能让画圆和画方都变得那么听话。

现在JavaScript中,也有这样一段老代码:

  1. function Round(){   
  2.     this.drawRound = function(){   
  3.         alert("round");   
  4.     }   

我也想依葫芦画瓢,但是JavaScript没有接口了,怎么办?

……

接口的作用是什么?是对类的行为的规约,可是JavaScript的行为是动态的,无法用简单纯粹的接口来实现、来约束,即便模拟出这样一个接口(参见《JavaScript Design Pattern》),在此又有必要使用它么?强行做出一个接口来,这不是和JavaScript的初衷相违背了吗?

再回到这个问题上面,我原本希望Person的对象可以调用一个统一的draw方法,只是在通过构造Person对象的时候,传入一个不同实现的Drawable对象,做出了不同约束下的实现。

那么,JavaScript中,不仅仅方法的调用者可以作为一个参数传入,方法本身也可以作为参数传入(即所谓方法闭包),这样,所有变化点都控制在这个参数之中,不也实现了我想要的接口规约的效果吗:

  1. function Rect(){   
  2.     this.drawRect = function(){   
  3.         alert("rect");   
  4.     }   
  5. }  
  6.  
  7. function Person(obj){   
  8.     //obj参数的格式:{doWhat,who}   
  9.     for(var i in obj){   
  10.         this.doWhat = i;   
  11.         this.who = obj[i];   
  12.         break;   
  13.     }   
  14.     this.draw = function(){   
  15.         this.who[this.doWhat].call(this.who);   
  16.     };   
  17. }  
  18.  
  19. var rou = { drawRound : new Round() };   
  20. var rec = { drawRect : new Rect() };   
  21. (new Person(rou)).draw();   
  22. (new Person(rec)).draw();  
  23.  
  24.   

写到这里,我觉得很开心:

在Java中,通过接口的规约和适配器的帮助,我将变化点封装在Person构造器的参数之中;

JavaScript中,没有了接口、脱离了适配器的帮助,我依然能将变化点封装在Person的构造器参数之中。

精彩图集

赞助商链接