JavaScript常用設(shè)計(jì)模式

開(kāi)放封閉原則:

開(kāi)放性:當(dāng)有新需求時(shí)疚顷,可以對(duì)現(xiàn)有代碼進(jìn)行擴(kuò)展壮池,在不影響現(xiàn)有功能的前提下,來(lái)實(shí)現(xiàn)新需求份乒;

封閉性:模塊的源代碼不能被修改恕汇,神圣不可侵犯(前提是功能是完整無(wú)誤的,修復(fù)bug不算破壞封閉性原則)或辖;

內(nèi)聚性/耦合性

內(nèi)聚性:表示單個(gè)模塊內(nèi)功能性強(qiáng)度性的度量瘾英;若一個(gè)模塊各個(gè)元素之間聯(lián)系很強(qiáng),那么該模塊就具有高內(nèi)聚颂暇,相反就是低內(nèi)聚缺谴;

耦合性:表示各個(gè)模塊之間聯(lián)系性的度量;若各個(gè)模塊聯(lián)系性很強(qiáng)耳鸯,那么各個(gè)模塊的耦合性很高湿蛔,相反就是低耦合;

總結(jié):一個(gè)好的程序架構(gòu)县爬,一般遵循高內(nèi)聚低耦合阳啥,這樣就能對(duì)各模塊進(jìn)行擴(kuò)展和復(fù)用,代碼質(zhì)量就比較高财喳;

1.工廠/構(gòu)造者/原型模式

工廠/構(gòu)造者/原型模式的共同點(diǎn)在于實(shí)現(xiàn)封裝性察迟,達(dá)到程序的復(fù)用。提高開(kāi)發(fā)效率耳高;不同點(diǎn)在于實(shí)現(xiàn)的方式不一致扎瓶;代碼如下:

    /*
    *定義工廠模式
    *通過(guò)函數(shù)封裝某功能代碼,以達(dá)到復(fù)用
    */
    function testOne(){
        var obj={
            name:"工廠模式"
        };
        obj.setName=function(name){
            this.name=name;
        }
        return obj;
    }
    //執(zhí)行函數(shù)
    testOne().setName("改變了");
    /*
    *定義構(gòu)造者模式
    *學(xué)過(guò)Java的知道泌枪,每個(gè)類中都有構(gòu)造函數(shù)概荷,JavaScript不是面向?qū)ο笳Z(yǔ)言
    *但是它也可以實(shí)現(xiàn),并通過(guò)new關(guān)鍵字實(shí)例化
    */
    function testTwo(){
        this.name="構(gòu)造者模式";
        this.setName=function(name){
            this.name=name;
        }
    }
    //執(zhí)行
    var testObj=new testTwo();
    testObj.setName("改變了");
    /*
    *定義原型模式
    *通過(guò)原型鏈的形式實(shí)現(xiàn)功能的封裝
    */
    function testTwo(){
        this.name="原型模式";
    }
    testTwo.prototype.setName=function(name){
        this.name=name;
    }
    //執(zhí)行
    var testObj=new testTwo();
    testObj.setName("改變了");

2.單例模式:

保證一個(gè)類只有一個(gè)實(shí)例碌燕,在實(shí)例化類之前先判斷該實(shí)例是否存在误证,如果存在直接引入继薛,不存在就進(jìn)行實(shí)例化類;在JavaScript中雷厂,單例模式類作為一個(gè)命名空間提供者,從全局命名空間里提供一個(gè)唯一的訪問(wèn)點(diǎn)來(lái)訪問(wèn)該對(duì)象叠殷;通常采用自執(zhí)行匿名函數(shù)和閉包方式實(shí)現(xiàn)改鲫;代碼如下:

/*定義單例模式*/
var single=(function(){//自執(zhí)行匿名函數(shù)
    var obj=null;
    /*1.訪問(wèn)函數(shù)外面的變量;2.把變量保存在內(nèi)存中林束,不讓變量被回收像棘;
    **2.特點(diǎn):函數(shù)1里面套函數(shù)2,然后函數(shù)1返回函數(shù)2壶冒;
    **3.缺點(diǎn):容易吃內(nèi)存缕题,性能毛病胖腾;故閉包不用就將里面的變量全部null掉
    */
    function Constructor(){ 
        //dothing~~~
    }
    return {
        testSingle:function(){
            if(obj==null){
                obj=new Constructor();
            }
            return obj;
        }
    }
})();
//執(zhí)行單例模式代碼
single.testSingle();

以上是單例模式的一種烟零,具體根據(jù)需求衍生出不同的單例模式;記住單例模式的核心:一個(gè)類只能有一個(gè)實(shí)例咸作;以上單例模式不管在什么時(shí)候都會(huì)執(zhí)行一次锨阿;因?yàn)椴捎昧俗詧?zhí)行匿名函數(shù)。如果想在有需要的時(shí)候執(zhí)行记罚,該怎么做墅诡?
惰性單例模式

    var signle=function(funs){
        var obj=null;
        return function(){
                return obj || (obj=funs.apply(this,arguments));
            }
    }

3.代理模式

“代理”生產(chǎn)商和消費(fèi)者之間有個(gè)代理商,用來(lái)聯(lián)系生產(chǎn)商和消費(fèi)者的聯(lián)系桐智,進(jìn)行商品交易末早。代理商要有生產(chǎn)商所提供的的信息展示給消費(fèi)者(程序中稱為接口);

  1. 真實(shí)角色:代理角色所代表的真實(shí)對(duì)象说庭,是我們最終要引用的對(duì)象然磷。
  2. 代理角色:代理對(duì)象角色內(nèi)部含有對(duì)真實(shí)對(duì)象的引用,從而可以操作真實(shí)對(duì)象刊驴,同時(shí)代理對(duì)象提供與真實(shí)對(duì)象相同的接口以便在任何時(shí)刻都能代替真實(shí)對(duì)象样屠。同時(shí),代理對(duì)象可以在執(zhí)行真實(shí)對(duì)象操作時(shí)缺脉,附加其他的操作痪欲,相當(dāng)于對(duì)真實(shí)對(duì)象進(jìn)行封裝。

代理模式的一個(gè)好處就是對(duì)外部提供統(tǒng)一的接口方法攻礼,而代理類在接口中實(shí)現(xiàn)對(duì)真實(shí)類的附加操作行為业踢,從而可以在不影響外部調(diào)用情況下,進(jìn)行系統(tǒng)擴(kuò)展礁扮。也就是說(shuō)知举,我要修改真實(shí)角色的操作的時(shí)候瞬沦,盡量不要修改他,而是在外部在“包”一層進(jìn)行附加行為雇锡,即代理類逛钻。

    var factory_obj={//定義真實(shí)對(duì)象
        name:"test",
        address:"中國(guó)北京",
        setName:function(name){
            this.name=name;
        },
        showName:function(){
            return this.name
        },
        setAddress:function(addr){
            this.address=addr;
        },
        showAddress:function(){
            return this.address;
        }
    };
    var agent_obj={//定義代理對(duì)象
        setName:function(name){
            factory_obj.setName(name);
        },
        showName:function(){
            return factory_obj.name;
        },
        setAddress:function(addr){
            factory_obj.setAddress(addr);
        },
        showAddress:function(){
            return factory_obj.address;
        }
    }
    //定義使用者
    //通過(guò)調(diào)用代理對(duì)象agent_obj來(lái)執(zhí)行factory_obj對(duì)象
    agent_obj.setName("我是消費(fèi)者1");
    console.log(agent_obj.showName());
    agent_obj.setAddress("江西上饒");
    console.log(agent_obj.address);

總結(jié):在代理模式中一定要同時(shí)具備真實(shí)對(duì)象和代理對(duì)象,真實(shí)對(duì)象是實(shí)際需要操作的對(duì)象锰提,代理對(duì)象是一個(gè)能訪問(wèn)到真實(shí)對(duì)象的接口曙痘。他們相互依賴;

優(yōu)點(diǎn):可以在不影響真實(shí)對(duì)象的基礎(chǔ)上進(jìn)行其他功能擴(kuò)展立肘;保持真實(shí)對(duì)象的完整性边坤,符合開(kāi)放封閉原則;在以上代碼進(jìn)行功能擴(kuò)展:

    //擴(kuò)展age屬性谅年,并定義setAge和showAge方法
    agent_obj['age']="16";
    agent_obj['setAge']=function(age){
        this.age=age;
    }
    age_obj['showAge']=function(){
        return this.age;
    }

4.發(fā)布/訂閱者模式

發(fā)布/訂閱者模式主要是為了松散耦合茧痒,提高代碼質(zhì)量;它大致?lián)碛小鞍l(fā)布者”和“訂閱者”這兩個(gè)角色融蹂;訂閱者關(guān)注了某發(fā)布者后旺订,當(dāng)發(fā)布者發(fā)布最新?tīng)顟B(tài),則訂閱就會(huì)收到通知超燃,并作出相應(yīng)的動(dòng)作耸峭;

場(chǎng)景實(shí)例:現(xiàn)在文章類APP都有對(duì)文章作者進(jìn)行關(guān)注的功能,關(guān)注之后淋纲,當(dāng)文章作者發(fā)布新文章時(shí)劳闹,系統(tǒng)就會(huì)通知你文章更新了。

    (function(){
        var manageObj={}; //注冊(cè)管理中心
        var Publish=function(){//注冊(cè)發(fā)布者
            
        }
        var Subscribe=function(){//注冊(cè)訂閱者
            return this;
        }
        /**
        * 注冊(cè)訂閱事件
        * @param type:string 訂閱的標(biāo)識(shí)
        * @param funs:function 訂閱標(biāo)識(shí)的回調(diào)函數(shù)
        **/
        Subscribe.prototype.add=function(type,funs){
            if(typeof type == "string"){
                manageObj[type]=funs;
            }else{
                console.error("add(type:string,funs:function)參數(shù)類型Error");
            }
        }
        /**
        * 取消訂閱事件
        * @param type:string 訂閱的標(biāo)識(shí)
        **/
        Subscribe.prototype.remove=function(type){
            if(typeof type == "string"){
                var keys=Object.keys(manageObj);
                for(var i=0;i=keys.length;i++){
                    if(keys[i] == type){
                        delete manageObj[types];
                        break;
                    }
                }
            }else{
                console.error("remove(type:string)參數(shù)類型Error");
            }
        }
        /**
        * 觸發(fā)訂閱事件
        * @param type:string 訂閱的標(biāo)識(shí)
        **/
        Subscribe.prototype.trigger=function(type){
            if(typeof type == "string"){
                if(typeof manageObj[type] == "undefined"){
                    console.error(type+"沒(méi)有訂閱事件");
                }else{
                    manageObj[type]();
                }
            }else{
                console.error("trigger(type:string)參數(shù)類型Error");
            }
        }
        //實(shí)例化Subscribe
        var subObj=new Subscribe();
        subObj.add("definedEvent",function(){
            console.log("我是自定義事件");
        });
        subObj.trigger("definedEvent");
    })();
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末洽瞬,一起剝皮案震驚了整個(gè)濱河市本涕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伙窃,老刑警劉巖菩颖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異为障,居然都是意外死亡晦闰,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門鳍怨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)呻右,“玉大人,你說(shuō)我怎么就攤上這事鞋喇∩模” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵侦香,是天一觀的道長(zhǎng)落塑。 經(jīng)常有香客問(wèn)我纽疟,道長(zhǎng),這世上最難降的妖魔是什么憾赁? 我笑而不...
    開(kāi)封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任污朽,我火速辦了婚禮,結(jié)果婚禮上龙考,老公的妹妹穿的比我還像新娘蟆肆。我一直安慰自己,他們只是感情好洲愤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布颓芭。 她就那樣靜靜地躺著顷锰,像睡著了一般柬赐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上官紫,一...
    開(kāi)封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天肛宋,我揣著相機(jī)與錄音,去河邊找鬼束世。 笑死酝陈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的毁涉。 我是一名探鬼主播沉帮,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贫堰!你這毒婦竟也來(lái)了穆壕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤其屏,失蹤者是張志新(化名)和其女友劉穎喇勋,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體偎行,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡川背,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蛤袒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熄云。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖妙真,靈堂內(nèi)的尸體忽然破棺而出皱碘,到底是詐尸還是另有隱情,我是刑警寧澤隐孽,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布癌椿,位于F島的核電站健蕊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏踢俄。R本人自食惡果不足惜缩功,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望都办。 院中可真熱鬧嫡锌,春花似錦、人聲如沸琳钉。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)歌懒。三九已至啦桌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間及皂,已是汗流浹背甫男。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留验烧,地道東北人板驳。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像碍拆,于是被迫代替她去往敵國(guó)和親若治。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容