在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ Mixin 模式
中介者模式
MVVM
亨元模式
設(shè)計(jì)模式分類(lèi)概覽表
ES Harmony
組合模式
CommonJS
jQuery 插件的設(shè)計(jì)模式
外觀模式
觀察者模式
建造者模式
構(gòu)造器模式
外觀模式
簡(jiǎn)介
AMD
原型模式
設(shè)計(jì)模式的分類(lèi)
觀察者模式
命名空間模式
代理模式
編寫(xiě)設(shè)計(jì)模式
適配器模式
反模式
什么是設(shè)計(jì)模式
模塊化模式
MVC
Mixin 模式
裝飾模式
設(shè)計(jì)模式的結(jié)構(gòu)
單例模式
迭代器模式
命令模式
工廠模式
MVP
暴露模塊模式
惰性初始模式

Mixin 模式

在諸如C++或者List著這樣的傳統(tǒng)語(yǔ)言中,織入模式就是一些提供能夠被一個(gè)或者一組子類(lèi)簡(jiǎn)單繼承功能的類(lèi),意在重用其功能。

子類(lèi)劃分

對(duì)于不熟悉子類(lèi)劃分的開(kāi)發(fā)者,在深入織入模式和裝飾器模式之前,我們將對(duì)他們進(jìn)行一個(gè)簡(jiǎn)短的初學(xué)者入門(mén)指引。

子類(lèi)劃分是一個(gè)參考了為一個(gè)新對(duì)象繼承來(lái)自一個(gè)基類(lèi)或者超類(lèi)對(duì)象的屬性的術(shù)語(yǔ).在傳統(tǒng)的面向?qū)ο缶幊讨?類(lèi)B能夠從另外一個(gè)類(lèi)A處擴(kuò)展.這里我們將A看做是超類(lèi),而將B看做是A的子類(lèi).如此,所有B的實(shí)體都從A處繼承了其A的方法.然而B(niǎo)仍然能夠定義它自己的方法,包括那些重載的原本在A中的定義的方法。

B是否應(yīng)該調(diào)用已經(jīng)被重載的A中的方法,我們將這個(gè)引述為方法鏈.B是否應(yīng)該調(diào)用A(超類(lèi))的構(gòu)造器,我們將這稱(chēng)為構(gòu)造器鏈。

為了演示子類(lèi)劃分,首先我們需要一個(gè)能夠創(chuàng)建自身新實(shí)體的基對(duì)象。

var Person =  function( firstName , lastName ){

  this.firstName = firstName;
  this.lastName =  lastName;
  this.gender = "male";

};

接下來(lái),我們將制定一個(gè)新的類(lèi)(對(duì)象),它是一個(gè)現(xiàn)有的Person對(duì)象的子類(lèi).讓我們想象我們想要加入一個(gè)不同屬性用來(lái)分辨一個(gè)Person和一個(gè)繼承了Person"超類(lèi)"屬性的Superhero.由于超級(jí)英雄分享了一般人類(lèi)許多共有的特征(例如:name,gender),因此這應(yīng)該很有希望充分展示出子類(lèi)劃分是如何工作的。

// a new instance of Person can then easily be created as follows:
var clark = new Person( "Clark" , "Kent" );

// Define a subclass constructor for for "Superhero":
var Superhero = function( firstName, lastName , powers ){

    // Invoke the superclass constructor on the new object
    // then use .call() to invoke the constructor as a method of
    // the object to be initialized.

    Person.call( this, firstName, lastName );

    // Finally, store their powers, a new array of traits not found in a normal "Person"
    this.powers = powers;
};

SuperHero.prototype = Object.create( Person.prototype );
var superman = new Superhero( "Clark" ,"Kent" , ["flight","heat-vision"] );
console.log( superman );

// Outputs Person attributes as well as powers

Superhero構(gòu)造器創(chuàng)建了一個(gè)自Peroson下降的對(duì)象。這種類(lèi)型的對(duì)象擁有鏈中位于它之上的對(duì)象的屬性,而且如果我們?cè)赑erson對(duì)象中設(shè)置了默認(rèn)的值,Superhero能夠使用特定于它的對(duì)象的值覆蓋任何繼承的值。

Mixin(織入目標(biāo)類(lèi))

在Javascript中,我們會(huì)將從Mixin繼承看作是通過(guò)擴(kuò)展收集功能的一種途徑.我們定義的每一個(gè)新的對(duì)象都有一個(gè)原型,從其中它可以繼承更多的屬性.原型可以從其他對(duì)象繼承而來(lái),但是更重要的是,能夠?yàn)槿我鈹?shù)量的對(duì)象定義屬性.我們可以利用這一事實(shí)來(lái)促進(jìn)功能重用。

Mix允許對(duì)象以最小量的復(fù)雜性從它們那里借用(或者說(shuō)繼承)功能.作為一種利用Javascript對(duì)象原型工作得很好的模式,它為我們提供了從不止一個(gè)Mix處分享功能的相當(dāng)靈活,但比多繼承有效得多得多的方式。

它們可以被看做是其屬性和方法可以很容易的在其它大量對(duì)象原型共享的對(duì)象.想象一下我們定義了一個(gè)在一個(gè)標(biāo)準(zhǔn)對(duì)象字面量中含有實(shí)用功能的Mixin,如下所示:

var myMixins = {

  moveUp: function(){
    console.log( "move up" );
  },

  moveDown: function(){
    console.log( "move down" );
  },

  stop: function(){
    console.log( "stop! in the name of love!" );
  }

};

然后我們可以方便的擴(kuò)展現(xiàn)有構(gòu)造器功能的原型,使其包含這種使用一個(gè) 如下面的score.js_.extends()方法輔助器的行為:

// A skeleton carAnimator constructor
function carAnimator(){
  this.moveLeft = function(){
    console.log( "move left" );
  };
}

// A skeleton personAnimator constructor
function personAnimator(){
  this.moveRandomly = function(){ /*..*/ };
}

// Extend both constructors with our Mixin
_.extend( carAnimator.prototype, myMixins );
_.extend( personAnimator.prototype, myMixins );

// Create a new instance of carAnimator
var myAnimator = new carAnimator();
myAnimator.moveLeft();
myAnimator.moveDown();
myAnimator.stop();

// Outputs:
// move left
// move down
// stop! in the name of love!

如我們所見(jiàn),這允許我們將通用的行為輕易的"混"入相當(dāng)普通對(duì)象構(gòu)造器中。

在接下來(lái)的示例中,我們有兩個(gè)構(gòu)造器:一個(gè)Car和一個(gè)Mixin.我們將要做的是靜Car參數(shù)化(另外一種說(shuō)法是擴(kuò)展),以便它能夠繼承Mixin中的特定方法,名叫driveForwar()和driveBackward().這一次我們不會(huì)使用Underscore.js。

取而代之,這個(gè)示例將演示如何將一個(gè)構(gòu)造器參數(shù)化,以便在無(wú)需重復(fù)每一個(gè)構(gòu)造器函數(shù)過(guò)程的前提下包含其功能。

// Define a simple Car constructor
var Car = function ( settings ) {

        this.model = settings.model || "no model provided";
        this.color = settings.color || "no colour provided";

    };

// Mixin
var Mixin = function () {};

Mixin.prototype = {

    driveForward: function () {
        console.log( "drive forward" );
    },

    driveBackward: function () {
        console.log( "drive backward" );
    },

    driveSideways: function () {
        console.log( "drive sideways" );
    }

};

// Extend an existing object with a method from another
function augment( receivingClass, givingClass ) {

    // only provide certain methods
    if ( arguments[2] ) {
        for ( var i = 2, len = arguments.length; i < len; i++ ) {
            receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
        }
    }
    // provide all methods
    else {
        for ( var methodName in givingClass.prototype ) {

            // check to make sure the receiving class doesn't
            // have a method of the same name as the one currently
            // being processed
            if ( !Object.hasOwnProperty(receivingClass.prototype, methodName) ) {
                receivingClass.prototype[methodName] = givingClass.prototype[methodName];
            }

            // Alternatively:
            // if ( !receivingClass.prototype[methodName] ) {
            //  receivingClass.prototype[methodName] = givingClass.prototype[methodName];
            // }
        }
    }
}

// Augment the Car constructor to include "driveForward" and "driveBackward"
augment( Car, Mixin, "driveForward", "driveBackward" );

// Create a new Car
var myCar = new Car({
    model: "Ford Escort",
    color: "blue"
});

// Test to make sure we now have access to the methods
myCar.driveForward();
myCar.driveBackward();

// Outputs:
// drive forward
// drive backward

// We can also augment Car to include all functions from our mixin
// by not explicitly listing a selection of them
augment( Car, Mixin );

var mySportsCar = new Car({
    model: "Porsche",
    color: "red"
});

mySportsCar.driveSideways();

// Outputs:
// drive sideways

優(yōu)點(diǎn)&缺點(diǎn)

Mixin支持在一個(gè)系統(tǒng)中降解功能的重復(fù)性,增加功能的重用性.在一些應(yīng)用程序也許需要在所有的對(duì)象實(shí)體共享行為的地方,我們能夠通過(guò)在一個(gè)Mixin中維護(hù)這個(gè)共享的功能,來(lái)很容易的避免任何重復(fù),而因此專(zhuān)注于只實(shí)現(xiàn)我們系統(tǒng)中真正彼此不同的功能。

也就是說(shuō),對(duì)Mixin的副作用是值得商榷的.一些開(kāi)發(fā)者感覺(jué)將功能注入到對(duì)象的原型中是一個(gè)壞點(diǎn)子,因?yàn)樗鼤?huì)同時(shí)導(dǎo)致原型污染和一定程度上的對(duì)我們?cè)泄δ艿牟淮_定性.在大型的系統(tǒng)中,很可能是有這種情況的。

我認(rèn)為,強(qiáng)大的文檔對(duì)最大限度的減少對(duì)待功能中的混入源的迷惑是有幫助的,而且對(duì)于每一種模式而言,如果在實(shí)現(xiàn)過(guò)程中小心行事,我們應(yīng)該是沒(méi)多大問(wèn)題的。

上一篇:單例模式下一篇:代理模式