欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
js自定義消息機制研究學(xué)習(三)——插件化我們js開(kāi)發(fā)

js自定義消息機制研究學(xué)習(三)——插件化我們js開(kāi)發(fā)

前兩篇

js自定義消息機制研究學(xué)習(一) ——看百度搜索輸入提示

js自定義消息機制研究學(xué)習(二)——做一些改動(dòng),定制自己的消息機制

研究了一些基礎的自定義消息機制,對一些簡(jiǎn)單的開(kāi)發(fā)已經(jīng)足夠。

現在我們來(lái)嘗試面對一些稍微復雜一些的架構設計。

首先,增加了一個(gè)插件模式:

plugs
var plugs=(function(){
function addPlugs(name,plug)
{
var __plugs=this.__plugs=this.__plugs || {};
if(name && plug)
{
__plugs[name]
={
installed:
false,
instance:plug
};
}

}

function installPlugs()
{
var plugs=this.__plugs=this.__plugs || {};
for(var i in plugs)
{
var plug=plugs[i];
if(!plug.installed)
{
plug.instance.install(
this);
plug.installed
=true;
}
}
}

return {
ini:
function(X)
{
X
=monitor.ini(X);
if(X.live)
{
var proto=X.prototype;
proto.addPlugs
=addPlugs;
proto.installPlugs
=installPlugs;
}

X.__plugs
={};
X.addPlugs
=addPlugs;
X.installPlugs
=installPlugs;


}
}
})();

如果你看過(guò)前兩篇代碼,這段代碼是比較容易看懂的。它為傳入的對象(或函數)首先綁定了monitor模式,然后為對象增加了兩個(gè)方法:addPlugs,installPlugs

addPlugs 添加插件

installPlugs 安裝插件

添加插件很簡(jiǎn)單,只是把實(shí)體裝到一個(gè){}鍵值對中

安裝插件,就會(huì )調用每個(gè)插件對象的:install方法




為什么要有插件模式呢?我們舉個(gè)例子來(lái)說(shuō)明

虛構一個(gè)需求:

1. 在頁(yè)面上動(dòng)畫(huà)展示龜兔賽跑

2.兔子和烏龜可以說(shuō)話(huà)

3.展示他們比賽過(guò)程

這里我沒(méi)什么素材,只簡(jiǎn)單展示一下這個(gè)程序設計

第一步,我們構造一個(gè)Animal函數,作為兔子、烏龜的類(lèi),代碼如下

Animal
    ///動(dòng)物
function Animal(config)
{
config
=config || {};
var othis=this;
this.name=config["name"] || "Anonymous";
this.x=config["x"] || 0;
var toward=1;//右:1,左-1
var __timeout=0;
var __speed=5;
//說(shuō)
this.say=function(str)
{
this.trigger({type:"say",msg:str});
return str;
}
//
this.stop=function()
{
clearTimeout(__timeout);
this.trigger({type:"stop",x:this.x});
return this.x;
}
//跑動(dòng)
this.run=function(speed)
{
__speed
=speed || __speed;
this.x+=__speed*toward;
__timeout
=setTimeout(function(){ othis.run();},100);
this.trigger({type:"run",x:this.x,toward:toward,speed:__speed});
return {x:this.x,toward:toward,speed:__speed};
}
//向左轉
this.turnLeft=function()
{
toward
=-1;
this.trigger({type:"turn",toward:toward});
return toward;
}
//向右轉
this.turnRight=function()
{
toward
=1;
this.trigger({type:"turn",toward:toward});
return toward;
}
}



我們現在有一個(gè)動(dòng)物的類(lèi)(Animal),它有一些行為:說(shuō)(say),停(stop),跑(run),左轉(turnLeft),右轉(turnRight) 

因為我在代碼里使用了trigger的方法,我們先使用上一篇講到monitor,初始化一下:

monitor.ini(Animal);




第二步 我們先寫(xiě)一個(gè)記錄的功能,用來(lái)記錄動(dòng)物對象的言行,這里只記錄say,stop,turn的消息,代碼如下:

View Code
///記錄器
function Logger()
{
this.dom=document.getElementById("log");
}

Logger.prototype
={
log:
function(str)
{
var time=new Date();
this.dom.innerHTML+="<br/>"+str+'<span style="color:gray">('+time.getHours()+":"+time.getMinutes()+":"+time.getSeconds()+")</span>";
},
handler:
function(data,p){
switch(data.type)
{
case "say":
this.log(p.name+" 說(shuō):"+data.msg);
break;
case "stop":
this.log('<span style="color:green">'+p.name+" 停在了"+data.x+'</span>');
break;
case "turn":
this.log(p.name+" 轉向了"+(data.toward==1?"":""));
break;
}

}
}

我們這里用id=log的一個(gè)頁(yè)面元素(div)來(lái)顯示動(dòng)物的言行

第三步,我們來(lái)創(chuàng )建兔子與烏龜這兩個(gè)對象:

var hare=new Animal({name:"兔子"});
var tortoise=new Animal({name:"烏龜"});




第四步,我們將記錄器綁定到兩個(gè)對象上

如果你要綁定到所有動(dòng)物對象上,你可以使用上一篇講到的live方法。在這里為了說(shuō)明為什么要用插件,我們限定一下需求,假設live是不允許使用的,因為我們還要創(chuàng )建其他的一些動(dòng)物,Logger是不需要記錄這些非主角的行為。那么我們要編寫(xiě)如下的代碼:

View Code
var log=new Logger(); 
hare.bind(
"say",log);
hare.bind(
"stop",log);
hare.bind(
"turn",log);
tortoise.bind(
"say",log);
tortoise.bind(
"stop",log);
tortoise.bind(
"turn",log);




現在提出一個(gè)問(wèn)題,你如果仔細看的話(huà),我們發(fā)現在介于live和bind之間,比如有100個(gè)Animal對象,我們只要求記錄50個(gè)Animal的行為,那么我們該有多郁悶,我們需要寫(xiě)很多的bind,假如我們Animal不只這幾個(gè)行為,我們?yōu)樗鼣U展了100個(gè)行為,都要做記錄,如果一行行的寫(xiě)bind,該多恐怖

好吧,改進(jìn)一下,你或許會(huì )建議要函數,例如這樣:

View Code
function bindLog(ani)
{
ani.bind(
"say",log);
ani.bind(
"stop",log);
ani.bind(
"turn",log);
}
bindLog(hare);
bindLog(tortoise);

如果只有一兩個(gè)這樣的需求,這樣也是不錯的。那么再擴展呢?要寫(xiě)很多個(gè),比如十個(gè),類(lèi)似于Logger的類(lèi),他們要去綁定100個(gè)Animal一個(gè),數個(gè),或者全部(全部當然可以考慮live)

假設這個(gè)十個(gè)類(lèi),有些需要每一個(gè)Animal對象都綁定單獨的對象,比如我們寫(xiě)一個(gè)類(lèi)Display,它來(lái)代表顯示在屏幕上的動(dòng)物,那么一個(gè)動(dòng)物對象就需要對應一個(gè)Display

很快我們就會(huì )發(fā)現,我們需要寫(xiě)很多的類(lèi)似于bindLog的方法。如bindDisplay,bindRun等等充斥在我們的主代碼中

那么用開(kāi)篇寫(xiě)插件,我們會(huì )怎么做?

首先把monitor.ini(Animal);修改為:plugs.ini(Animal)讓它支持插件模式,因為插件模式默認綁定了monitor,所以我們不需要再初始化一次monitor




然后我們在Logger的prototype中,添加方法install




View Code
install:function(main){
main.bind(
"say",this);
main.bind(
"stop",this);
main.bind(
"turn",this);
}




我們的綁定代碼,修改成如下:

View Code
//添加安裝插件
var log=new Logger();
hare.addPlugs(
"log",log);
tortoise.addPlugs(
"log",log);
hare.installPlugs();
tortoise.installPlugs();

我們把一系列的bind,修改成為先使用addPlugs,最后調用installPlugs來(lái)完成。

這樣做的優(yōu)勢?

你的主代碼很清晰,完整如下:

View Code
var hare=new Animal({name:"兔子"});
var tortoise=new Animal({name:"烏龜"});
//記錄器
var log=new Logger();

hare.addPlugs(
"log",log);
tortoise.addPlugs(
"log",log);
hare.installPlugs();
tortoise.installPlugs();

這樣,你很快就能看明白對象與對象之間的關(guān)系,也能從更高一點(diǎn)抽象層次上去組織你的對象,組織你的代碼,而不需要頭疼寫(xiě)一堆一堆的bind了,如果你要換掉一個(gè)Logger,比如換成一個(gè)只記錄say的Logger 或者說(shuō)你要把動(dòng)物說(shuō)的話(huà)以氣泡的形式顯示在他們的頭頂。

當我們有很多的組件拼裝時(shí),這樣模式很給我們帶來(lái)很大的便利。

更重要的:

Animal 可以看做一個(gè)業(yè)務(wù)邏輯,我們很好的將它與顯示進(jìn)行了分離,在測試中,我們可以很簡(jiǎn)單的調用hare.run hare.say,而完全不用關(guān)心他們的顯示表現,這樣可以讓我們在更高的抽象層次構建我們的js程序。對于一些復雜的業(yè)務(wù),既可以讓我們專(zhuān)注于業(yè)務(wù),也可以讓我們彼此分工合作,各寫(xiě)一塊。




PS:

也許有人要問(wèn),為什么要addPlugs,然后再installPlugs,而不是一個(gè)addPlugs直接搞定。

在例子寫(xiě)完以后我發(fā)現了這個(gè)問(wèn)題,這是我的疏忽,慣性思維讓我沿用了我的實(shí)際使用的plugs。

其實(shí)我應用的plugs,還有一些擴展方法,如getPlug等等,在實(shí)際開(kāi)發(fā)中插件的install方法后還會(huì )觸發(fā)trigger一個(gè)消息等等

這樣做的目的是,在installPlugs時(shí),部分插件的安裝,是需要知道其他插件的存在

還有一個(gè)原因,是涉及懶加載的,在addPlugs時(shí),有時(shí)我會(huì )addPlugs一個(gè)配置,或者一個(gè)簡(jiǎn)稱(chēng),然后有他們實(shí)際指向的js文件此時(shí)并未加載

直到installPlugs時(shí),它才會(huì )真正加載js并創(chuàng )建plug對象。所以我是在插件配置都準備好的情況下,才請求相應的js文件(比如直接請求一個(gè)服務(wù)器合并多個(gè)js后的壓縮文件)

希望不要給大家造成困擾。

我的建議是,如果你對這樣的編程方式感興趣,使用monitor,plugs(當然,他們也可以直接用來(lái)解決一些問(wèn)題)之前最好根據自己的情況修改一下

完整代碼示例:下載

在完整代碼示例中,我增加了一個(gè)Display用于顯示動(dòng)物,然后抱著(zhù)玩的心態(tài)加了段簡(jiǎn)單的故事腳本,博君一笑

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Layered Technologies Helpdesk :: Support Port...
console.log簡(jiǎn)寫(xiě)
Javascript通過(guò)bind()掌控this
bind98
使用Strophe連接xmpp,輕松構建web即時(shí)聊天工具
Linux下sshd啟動(dòng)失敗及Squid啟動(dòng)失敗問(wèn)題解決一例
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久