繁体   English   中英

没有if-else块的JavaScript Factory模式

[英]JavaScript Factory pattern without if-else block

我想知道是否有更好的方法来实现使用字典的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);

尝试这个:

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);
};

我建议将constructors对象很好地隐藏在EmployeesFactory 这样,您还可以摆脱不需要的函数名称( ClerkManagerTeacher )。

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

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);
        }
    };
};

您可以通过以下方式获得工厂:

factory = EmployeesFactory();

并可以通过以下方式创建东西:

factory.create(options);

一切都将舒适且隐藏在外部的封口内,没有胆量挂在外面。

工厂模式的目的是隐藏的复杂性和对象结构的细节,因此保持方法各地的消费是错过了一个方面(我承认,未成年人/最小)的格局。 通过使用闭包,您还将获得隐藏的好处。

是的,正如您所说,请使用字典:

function createEmployee(options) {
    return new {
        "Clerk": Clerk,
        "Manager": Manager,
        "Teacher": Teacher
    }[options.employeeType](options);
}

也许使对象文字成为静态变量constructors ,然后重新引入中间的employeeConstructor变量,以获得更多的详细信息和更少的混乱语法:-)


顺便说一句,您的构造函数中有很多代码重复。 您可以使它更干燥:

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

function Clerk(options) {
    Employee.call(this, options, 20);
}
function Manager(options) {
    Employee.call(this, options, 200);
    this.yearBonus = options.yearBonus || "200000";
}
function Teacher(options) {
    Employee.call(this, options, 100);
    this.subject = options.subject || "history";
}

是的,下面将是更干净的代码。

// Create this one time
var constructors = {};

constructors["Manager"] = Manager
constructors["Teacher"] = Teacher
...

// Each object
return new constructors[options.employeeType](options);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM