`
yiminghe
  • 浏览: 1465460 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

利用Attribute重构:业务与UI分离

阅读更多

很简单的一个应用 通过按钮来限制输入范围 ,这样的话再配合服务器端检测就能在一定范围内限制输入数据,这次从重构的角度讲解如何一步步将代码变得更加优美:)


1.原始代码,业务逻辑与ui混合

 

function Increaser(domInput,domAction){
	this.input=domInput;
	this.domAction=domAction;
	this.domAction.on("click",this.increasing,this);
}


Increaser.prototype.increasing=function(e){
	
	if(this.input.get("value")=="3"){
		this.input.set("value",0);
	}else{
		this.input.set("value",parseInt(this.input.get("value"))+1);
	}
};


new Increaser(Y.one("#v"),Y.one("#r"));
 


2.利用Observer模式重构


改进类,区分业务domain与ui,duplicate observed data,
将数据复制到一个领域对象中,建立一个observer模式,用以同步领域对象和gui对象内的重复数据

 

function GuiIncreaser(domInput, domAction) {
    this.input = domInput;
    this.domAction = domAction;
    this.domainIncreaser = new DomainIncreaser(this.input.get("value"));
    this.domainIncreaser.addObserver(this);
    this.domAction.on("click", this.increasing, this);
}
GuiIncreaser.prototype = {
    constructor: GuiIncreaser,

    increasing: function (e) {
        this.domainIncreaser.increase();
    },

    //observer
    update: function (v) {
        this.input.set("value", v);
    }
}

function DomainIncreaser(v) {
    this.v = v;
    this.observers = [];
}

DomainIncreaser.prototype = {
    constructor: DomainIncreaser,
    addObserver: function (o) {
        if (Y.Array.indexOf(this.observers, o) == -1) {
            this.observers.push(o);
        }
    },

    checkChange: function () {
        if (this.v == "4") this.v = 0;
    },

    //observable
    notify: function () {
        for (var i = this.observers.length - 1; i >= 0; i--) {
            this.observers[i].update(this.v);
        }
    },

    increase: function () {
        this.v = parseInt(this.v) + 1;
        this.checkChange();
        this.notify();
    }
}


new GuiIncreaser(Y.one("#v"),Y.one("#r"));

 

3.利用 attribute 简化


利用 yui3 attribute 简化2,将domain和gui重新结合,利用yui3 attribute来实现属性与ui的分离与同步

 

function AttributeIncreaser(domInput, domAction) {
    this.input = domInput;
    this.domAction = domAction;
    var attrs = {
        "v": {
            value: this.input.get("value"),
            //domain业务逻辑
            setter: function (v) {
                if (v == "4") return 0;
            }
        }
    };
    this.addAttrs(attrs);

    //domain业务逻辑
    this.domAction.on("click", this.increase, this);

    //属性与gui同步
    this.after("vChange", this.afterVChange, this);
}

AttributeIncreaser.prototype = {
    constructor: AttributeIncreaser,
    increase: function () {
        this.set("v", parseInt(this.get("v")) + 1);
    },
    afterVChange: function (e) {
        this.input.set("value", e.newVal);
    }
};

Y.augment(AttributeIncreaser, Y.Attribute);


new AttributeIncreaser(Y.one("#v"), Y.one("#r"));

 

2,3 的另一个好处是尽可能少得 touch dom,提高了运行效率,这对于复杂应用至关重要。

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics