【JS设计模式】之2 工厂模式

293 阅读2分钟

  • 本文内容:
    1. 介绍什么是工厂模式
    2. 代码实现
    3. 举例其他实际工程中的应用
    4. 多个类如何在工厂中创建?
    5. 总结
  • 目标: 解决对象创建的问题, 用户可以不用new , 解耦要new的类与调用者, 避比如一个类在若干个文件都有引用且实例化。用工厂函数封装一层, 下次要替换新的类,直接在工厂函数中修改一处即可

一个例子:实现一个lazyMan, lazyMan.eat().sleep()

//相关代码
class LazyMan{

}

//工厂函数
fuction lazyMan(){
    return new LazyMan()
}

在工程上的应用:

  1. jQ :
jQuery = function( selector, context ) {
  return new jQuery.fn.init( selector, context );
};
  1. react: createElement

function createElement(type, config, children) {
    // var propName; // Reserved names are extracted

    // var props = {};
    // var key = null;
    // var ref = null;
    // var self = null;
    // var source = null;

    // if (config != null) {
    //   if (hasValidRef(config)) {
    //     ref = config.ref;

    //     {
    //       warnIfStringRefCannotBeAutoConverted(config);
    //     }
    //   }

    //   if (hasValidKey(config)) {
    //     key = '' + config.key;
    //   }

    //   self = config.__self === undefined ? null : config.__self;
    //   source = config.__source === undefined ? null : config.__source; // Remaining properties are added to a new props object

    //   for (propName in config) {
    //     if (hasOwnProperty$1.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
    //       props[propName] = config[propName];
    //     }
    //   }
    // } // Children can be more than one argument, and those are transferred onto
    // // the newly allocated props object.


    // var childrenLength = arguments.length - 2;

    // if (childrenLength === 1) {
    //   props.children = children;
    // } else if (childrenLength > 1) {
    //   var childArray = Array(childrenLength);

    //   for (var i = 0; i < childrenLength; i++) {
    //     childArray[i] = arguments[i + 2];
    //   }

    //   {
    //     if (Object.freeze) {
    //       Object.freeze(childArray);
    //     }
    //   }

    //   props.children = childArray;
    // } // Resolve default props


    // if (type && type.defaultProps) {
    //   var defaultProps = type.defaultProps;

    //   for (propName in defaultProps) {
    //     if (props[propName] === undefined) {
    //       props[propName] = defaultProps[propName];
    //     }
    //   }
    // }

    // {
    //   if (key || ref) {
    //     var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;

    //     if (key) {
    //       defineKeyPropWarningGetter(props, displayName);
    //     }

    //     if (ref) {
    //       defineRefPropWarningGetter(props, displayName);
    //     }
    //   }
    // }

    return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
  }

多个产品怎么办?

class Car {
    constructor(name) {
        this.name = name
    }
    logName() {
        console.log(this.name)
    }
}

class Benz extends Car {}

class BMW extends Car {}


let carFactory = (name) => {
    switch (name) {
        case 'Benz':
            return new Benz('Benz')
        case 'Bmw':
            return new BMW('bmw')
    }
}
console.log(carFactory('Benz')) //Benz { name: 'Benz' }
carFactory('Bmw').logName() //bmw

总结

工厂模式解决了对象或者类的创建问题。不用自己new class 得到对应的实例。构造函数和创建者分离, 符合开放封闭原则(我当前的理解是:老代码不要改动 新的代码可以加)。

本文使用 mdnice 排版