JavaScript重构(七):重用老代码
2011-04-22 23:51
288 查看
在Java中,有这样一段老代码:
class Round{
public void drawRound(); //画圆
}
现在新代码希望能和它共存,使用一个Person的对象来控制,只不过,可能drawRound,也可能drawRect啊:
class Rect{
public void drawRect(); //画方
}
好,废话少说,我先想到了Adapter模式:
interface Drawable{
public void draw();
}
public class RoundAdapter implements Drawable{
private Round round;
public void draw(){
round.drawRound();
}
}
public class RectAdapter implements Drawable{
private Rect rect;
public void draw(){
rect.drawRect();
}
}
然后,我再引入一个Person对象,就能搞定这一切了:
class Person{
private Drawable adapter;
public Person(Drawable adapter){
this.adapter = adapter;
}
public void draw(){
this.adapter.draw();
}
}
Drawable rou = new RoundAdapter();
Drawable rec = new RectAdapter();
new Person(rou).draw(); //画圆
new Person(rec).draw(); //画方
想必到此已经让你烦了,一个Adapter模式的最简单例子。再多看一看,这个模式的核心是什么?接口!对,正是例子中的Drawable接口——正是在接口的规约和领导下,我们才能让画圆和画方都变得那么听话。
现在JavaScript中,也有这样一段老代码:
function Round(){
this.drawRound = function(){
alert("round");
}
}
我也想依葫芦画瓢,但是JavaScript没有接口了,怎么办?
……
接口的作用是什么?是对类的行为的规约,可是JavaScript的行为是动态的,无法用简单纯粹的接口来实现、来约束,即便模拟出这样一个接口(参见《JavaScript Design Pattern》),在此又有必要使用它么?强行做出一个接口来,这不是和JavaScript的初衷相违背了吗?
再回到这个问题上面,我原本希望Person的对象可以调用一个统一的draw方法,只是在通过构造Person对象的时候,传入一个不同实现的Drawable对象,做出了不同约束下的实现。
那么,JavaScript中,不仅仅方法的调用者可以作为一个参数传入,方法本身也可以作为参数传入(即所谓方法闭包),这样,所有变化点都控制在这个参数之中,不也实现了我想要的接口规约的效果吗:
function Rect(){
this.drawRect = function(){
alert("rect");
}
}
function Person(obj){
//obj参数的格式:{doWhat,who}
for(var i in obj){
this.doWhat = i;
this.who = obj[i];
break;
}
this.draw = function(){
this.who[this.doWhat].call(this.who);
};
}
var rou = { drawRound : new Round() };
var rec = { drawRect : new Rect() };
(new Person(rou)).draw();
(new Person(rec)).draw();
写到这里,我觉得很开心:
在Java中,通过接口的规约和适配器的帮助,我将变化点封装在Person构造器的参数之中;
JavaScript中,没有了接口、脱离了适配器的帮助,我依然能将变化点封装在Person的构造器参数之中。
class Round{
public void drawRound(); //画圆
}
现在新代码希望能和它共存,使用一个Person的对象来控制,只不过,可能drawRound,也可能drawRect啊:
class Rect{
public void drawRect(); //画方
}
好,废话少说,我先想到了Adapter模式:
interface Drawable{
public void draw();
}
public class RoundAdapter implements Drawable{
private Round round;
public void draw(){
round.drawRound();
}
}
public class RectAdapter implements Drawable{
private Rect rect;
public void draw(){
rect.drawRect();
}
}
然后,我再引入一个Person对象,就能搞定这一切了:
class Person{
private Drawable adapter;
public Person(Drawable adapter){
this.adapter = adapter;
}
public void draw(){
this.adapter.draw();
}
}
Drawable rou = new RoundAdapter();
Drawable rec = new RectAdapter();
new Person(rou).draw(); //画圆
new Person(rec).draw(); //画方
想必到此已经让你烦了,一个Adapter模式的最简单例子。再多看一看,这个模式的核心是什么?接口!对,正是例子中的Drawable接口——正是在接口的规约和领导下,我们才能让画圆和画方都变得那么听话。
现在JavaScript中,也有这样一段老代码:
function Round(){
this.drawRound = function(){
alert("round");
}
}
我也想依葫芦画瓢,但是JavaScript没有接口了,怎么办?
……
接口的作用是什么?是对类的行为的规约,可是JavaScript的行为是动态的,无法用简单纯粹的接口来实现、来约束,即便模拟出这样一个接口(参见《JavaScript Design Pattern》),在此又有必要使用它么?强行做出一个接口来,这不是和JavaScript的初衷相违背了吗?
再回到这个问题上面,我原本希望Person的对象可以调用一个统一的draw方法,只是在通过构造Person对象的时候,传入一个不同实现的Drawable对象,做出了不同约束下的实现。
那么,JavaScript中,不仅仅方法的调用者可以作为一个参数传入,方法本身也可以作为参数传入(即所谓方法闭包),这样,所有变化点都控制在这个参数之中,不也实现了我想要的接口规约的效果吗:
function Rect(){
this.drawRect = function(){
alert("rect");
}
}
function Person(obj){
//obj参数的格式:{doWhat,who}
for(var i in obj){
this.doWhat = i;
this.who = obj[i];
break;
}
this.draw = function(){
this.who[this.doWhat].call(this.who);
};
}
var rou = { drawRound : new Round() };
var rec = { drawRect : new Rect() };
(new Person(rou)).draw();
(new Person(rec)).draw();
写到这里,我觉得很开心:
在Java中,通过接口的规约和适配器的帮助,我将变化点封装在Person构造器的参数之中;
JavaScript中,没有了接口、脱离了适配器的帮助,我依然能将变化点封装在Person的构造器参数之中。
相关文章推荐
- javascript 命名空间以提高代码重用性
- 代码重构-------ListView与GridView的适配器重用篇
- JavaScript进阶之路——认识和使用Promise,重构你的Js代码
- 一段实现选择框javascript代码的重构
- JavaScript进阶之路——认识和使用Promise,重构你的Js代码
- javascript 命名空间以提高代码重用性
- JavaScript代码重构技巧
- 重构Javascript代码示例(重构前后对比)
- 面向对象的javascript系列文章(3)继承——代码重用
- 重构Javascript代码
- Javascript中的Trait与代码重用
- Javascript 公共代码(可重用)
- 原生javascript开发打字游戏---代码重构版本
- 重构一段基于原生JavaScript的表格绘制代码
- javascript代码的小小重构
- 精通javascript 第三章: 创建可重用的代码
- MVC设计模式带来更好的软件结构和代码重用
- Javascript 代码摘录,应习惯使用“with”和“setArrtubut”
- JavaScript实现对话框效果的代码实例