簡體   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