我想知道是否有更好的方法来实现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);
答案 0 :(得分: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);
};
我建议将constructors
对象隐藏在EmployeesFactory
内。
这样你也可以摆脱不受欢迎的函数名称(Clerk
,Manager
和Teacher
)。
此外,您应该只创建一次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);
}
};
};
你这样得到工厂:
factory = EmployeesFactory();
并且可以通过这种方式创建:
factory.create(options);
所有这些都将是舒适的,隐藏在外部封闭的封闭内部,没有任何胆量悬挂在外面。
工厂模式的目的是隐藏对象构造的复杂性和细节,因此在某个方面缺少用于消费的方法 (我承认,小/最小的模式。通过使用闭包,你也可以获得隐藏的好处。
答案 1 :(得分:2)
是的,如你所说,使用字典:
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";
}
答案 2 :(得分:0)
是的,下面的代码更清晰。
// Create this one time
var constructors = {};
constructors["Manager"] = Manager
constructors["Teacher"] = Teacher
...
// Each object
return new constructors[options.employeeType](options);