zoukankan      html  css  js  c++  java
  • 设计模式(九):混入模式

    第一次完整看一遍(JavaScript设计模式)该模式的介绍,感觉这不就是继承而已吗,只不过可能是部分继承。

    混入(Mixin)模式

    定义:

    Mixin是可以轻松被一个子类或一组子类继承功能的类,目的是函数复用。继承Mixin是扩展功能的方式,另外也可能从多个Mixin类进行继承。

    继承方式:

    这个模式关键点在于继承,JavaScript上有几种实现继承的方式:

    1. 原型继承

    function A(){
         this.name = "A";
    }
    function B(){
    }
    B.prototype= new A();
    var b = new B();
    console.log(b instanceof A);     //true
    console.log(b instanceof B);     //true

    PS:无法实现多继承。

    2. 拷贝继承

    function extend(receiveClass, givingClass){
         for(var key in givingClass.prototype){
               receiveClass.prototype[key] = givingClass.prototype[key];
          }
    }
    function A(){
    }
    A.prototype.hello = function(){
         console.log("hello");
    }
    function B(){
    }
    extend(B, A);
    var b = new B();
    console.log(b instanceof A);     //false
    console.log(b instanceof B);     //true

    PS:支持多继承,但效率低。

    3. 构造继承

    function A1(){
         this.name = "A";
    }
    function A2(){
         this.age = 18;
    }
    function B(){
         A1.call(this);
         A2.call(this);
         this.desc =  "Test";
    }
    var b = new B();
    console.log(b instanceof A);     //false
    console.log(b instanceof B);     //true

    PS:支持多继承

    4. 实例继承

    function A(){
         this.name = "A";
    }
    function B(){
         var instance = new A();
         instance.desc = "Test";
         return instance;
    }
    var b = new B();
    console.log(b instanceof A);     //true
    console.log(b instanceof B);     //false

    PS:这种方式我觉得很糟糕,生成的对象本质是父类的实例,不是子类的对象,当然也不支持多继承。

    例子:

    // 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]];
            }
        }
        else {
            for ( var methodName in givingClass.prototype ) {
                if ( !Object.hasOwnProperty.call(receivingClass.prototype, methodName) ) {
                    receivingClass.prototype[methodName] = givingClass.prototype[methodName];
                }
            }
        }
    }
     
    augment( Car, Mixin, "driveForward", "driveBackward" );
    var myCar = new Car({
        model: "Ford Escort",
        color: "blue"
    });
    myCar.driveForward();
    myCar.driveBackward();
     
    augment( Car, Mixin );
    var mySportsCar = new Car({
        model: "Porsche",
        color: "red"
    });
    mySportsCar.driveSideways();

    这个例子里面Car类所扩展的功能,是通过拷贝继承的继承方式继承的。

    优点:

    1. 减少系统中的重复功能及增加函数复用。

    缺点:

    1. 将功能注入对象原型中,会导致原型污染和函数起源方面的不确定性。

    PS:简单说就是找不到扩展的方法的来源。

    结论:

    混入模式是一种简单的结构型模式,目的是扩展子类功能,子类可从多个Mixin类收集功能。

    参考文献

    1. http://raychase.iteye.com/blog/1337415 (JavaScript实现继承的几种方式)

    2. 《JavaScript设计模式》by 徐涛【译】

    本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。

    本文地址 :http://www.cnblogs.com/lovesong/p/5617570.html

  • 相关阅读:
    Python解析Yahoo的XML格式的天气预报数据
    如何卸载wineQQ?
    纪念我的第一篇
    hihocoder1062 最近公共祖先·一
    hihocoder1055 刷油漆(树形DP)
    hihocoder1050 树中的最长路径
    hihocoder1049 根据二叉树的先序序列和中序序列求后序序列
    hihocoder1044 状态压缩
    hihocoder1043 完全背包
    hihocoder1038 01背包
  • 原文地址:https://www.cnblogs.com/lovesong/p/5617570.html
Copyright © 2011-2022 走看看