没有if-else块的JavaScript Factory模式

Min*_*ser 1 javascript design-patterns factory factory-pattern

我想知道是否有更好的方法来实现createEmployee(),它使用字典或其他方式快速查找所请求的类型而不是if-else块.

function Clerk( options ) {
            this.hourRate = options.hourRate || 20;
            this.firstName = options.firstName || "no first name";
            this.lastName = options.lastName || "no last name";
            this.id = options.id || "-9999999999";
        }

        function Manager( options) {
            this.hourRate = options.hourRate || 200;
            this.firstName = options.firstName || "no first name";
            this.lastName = options.lastName || "no last name";
            this.id = options.id || "-9999999999";
            this.yearBonus = options.yearBonus || "200000";
        }

        function Teacher( options) {
            this.hourRate = options.hourRate || 100;
            this.firstName = options.firstName || "no first name";
            this.lastName = options.lastName || "no last name";
            this.id = options.id || "-9999999999";
            this.subject = options.subject || "history";
        }

        var EmployeesFactory = function() {};

        EmployeesFactory.prototype.createEmployee = function (options) {
            if(options.employeeType == "Clerk")
                employeeConstructor = Clerk;
            else if(options.employeeType == "Manager")
                employeeConstructor = Manager;
            else if(options.employeeType == "Teacher")
                employeeConstructor = Teacher;
            return new employeeConstructor(options);
        }

        var factory = new EmployeesFactory();
        var person = factory.createEmployee( {
            employeeType: "Manager",
            firstName: "Haim",
            lastName: "Michael",
            id: 234234234 } );

        document.write(person instanceof Manager);
Run Code Online (Sandbox Code Playgroud)

pid*_*pid 6

试试这个:

var constructors;

constructors = {
    "Clerk" : function (options) {
        // your constructor code here for clerks
    },
    "Manager" : function (options) {
        // your constructor code here for managers
    },
    "Teacher" : function (options) {
        // your constructor code here for teachers
    }
};

EmployeesFactory.prototype.createEmployee = function (options) {
    return constructors[options.employeeType](options);
};
Run Code Online (Sandbox Code Playgroud)

我建议保持constructors对象隐藏在里面EmployeesFactory.这样,你也摆脱了不需要的功能名称(Clerk,ManagerTeacher).

此外,您应该constructors只创建一次对象并在create中重用它.不要在创建中实例化它.您可以通过以下方式执行此操作:

var EmployeesFactory = function () {
    var constructors;

    constructors = {
        "Clerk" : function (options) {
            // your constructor code here for clerks
        },
        "Manager" : function (options) {
            // your constructor code here for managers
        },
        "Teacher" : function (options) {
            // your constructor code here for teachers
        }
    };

    return {
        "create" : function (options) {
            return constructors[options.employeeType](options);
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

你这样得到工厂:

factory = EmployeesFactory();
Run Code Online (Sandbox Code Playgroud)

并且可以这样创建东西:

factory.create(options);
Run Code Online (Sandbox Code Playgroud)

所有这些都将舒适,隐藏在外部封闭的封闭内部,没有外面的内脏.

工厂模式的目的是隐藏对象构造的复杂性和细节,因此在模式的一个方面(我承认,次要/最小)缺少保持方法供消费.通过使用闭包,您也可以获得隐藏的好处.