摘要:假設有一個生產交通工具的工廠類,它包含生成多種交通工具實例的方法。在使用這個類生產對象的時候,傳入參數,在參數中的屬性規定我們需要的類型,構造函數就能夠返回我們需要的對象類型了。
一般來說,創建對象的時候我們都習慣使用new關鍵字來調用constructor構造函數,但使用這種方式會有一些缺點,首先構造器函數的創建本身就是為了模仿其他一些面向對象語言的特性,有些人覺得這是non-sense;另一方面,在一個類中用new關鍵字調用其他類的構造函數,會造成兩個類之間的耦合,設計模式應該要盡量避免這些影響代碼可重用性的問題。
簡單工廠模式一個工廠可以生產同一類的多種物品,具體生產哪種就看客戶下什么訂單了。工廠模式也是一樣,我們創建一個工廠類,它可以創建多種實例,由開發者指定。
假設有一個生產交通工具的工廠類Vehicle,它包含生成多種交通工具實例的方法。
function Vehicle() {} Vehicle.prototype = { createVihicle: function(options) { var vehicle; switch(options.type) { case "car": vehicle = new Car(); break; case "truck": vehicle = new Truck(); break; default: vehicle = new Bike(); } return vehicle; } };
在使用這個類生產對象的時候,傳入option參數,在參數中的type屬性規定我們需要的類型,構造函數就能夠返回我們需要的對象類型了。使用這種方法,如果我們要添加新的交通工具類型也是很方便的,在工廠的switch中直接添加一個case就可以了。
switch(options.type) { case "car": vehicle = new Car(); break; case "truck": vehicle = new Truck(); break; case "plane": vehicle = new Plane(); break; default: vehicle = new Bike(); }
通過這種方式,將成員對象的創建工作轉交給外部對象,可以像上述代碼一樣轉交給獨立的命名空間,像Car,Truck,Plane等,如果外部對象屬于同一類的話,將它們組織為一個大類中的子類比較合理。
工廠模式以上介紹的是簡單工廠模式,簡單工廠模式會把創建工作交給外部的類來做,這實際上會增加類的數量,并不利于代碼的組織。真正的工廠模式會把創建工作交給子類來完成,父類只對創建過程中的一般性問題進行處理,這些處理會影響到每個子類,而子類之間相互獨立,可以對創建過程進行一些定制化操作。
還是以生產交通工具為例,將交通工具父類改寫為一個抽象類,它不負責直接生產交通工具,而是通過它派生出一些子類,這些子類代表不同的國家,不同的國家可以生產自己的交通工具。
將父類抽象化:
function Vehicle() {} Vehicle.prototype = { createVihicle: function(options) { // 這里不直接生產,如果直接調用會拋出錯誤 throw new Error("Unsupported operation on an abstract class.") } };
不同的國家作為子類,子類首先對父類進行繼承,然后實現自己的createVehicle方法。
function China() {} // 繼承方法 extend(China, Vehicle); // 實現自己的createVehicle方法 China.prototype.createVehicle = function(options) { var vehicle; switch(options.type) { case "car": vehicle = new Car(); break; case "truck": vehicle = new Truck(); break; default: vehicle = new Bike(); } return vehicle; }
以后要生產交通工具的時候就調用China子類的createVehicle方法就可以了。
var chinaVehicle = new China(); var myCar = chinaVehicle.createVehicle({ type: "Car" });
一般性的代碼集中在父類中,個性化的代碼在子類中多帶帶定制。
工廠模式適用場合子類的共同點是它們都實現了同一批接口,盡管內部細節并不盡相同。生產對象的方法有一個選擇性的過程,這種選擇可以是開發者自定的,比如需要生產何種交通工具,也可以是自動選擇的,比如根據瀏覽器環境生產合適的XHR對象。對于相似性很高,實現了同一類接口的對象,工廠模式是比較合適的。
另外的一大好處就是子類的一些設置代碼可以全部放在父類的構造器函數中,不需要在每個子類的構造函數中重復運行同樣的代碼,只需要在父類的代碼中實現一次就好。子類只需要專注于實現自己的方法,不用考慮別的問題。
最后一點則是如果一個類中包含了很多更小的子類作為自己的組成部分,那么替換這些子類的工作會很簡單,因為工廠模式降低了模塊之間的耦合度,一個模塊并不會依賴于其某一組成部分。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/87528.html
摘要:三種使用構造函數創建對象的方法和的作用都是在某個特殊對象的作用域中調用函數。這種方式還支持向構造函數傳遞參數。叫法上把函數叫做構造函數,其他無區別適用情境可以在特殊的情況下用來為對象創建構造函數。 一、工廠模式 工廠模式:使用字面量和object構造函數會有很多重復代碼,在此基礎上改進showImg(https://segmentfault.com/img/bVbmKxb?w=456&...
摘要:使用構造器有個嚴重的危害,如果在調用構造器函數的時候忘記使用前綴,不僅不會綁定到新對象,還會污染全局變量原型模式原型模式中,我們采用對象來繼承。 構造器調用模式 當一個函數對象被創建時,Function構造器會運行類似這樣的代碼: this.prototype = {constructor: this} new一個函數事會發生: Function.method(new, functio...
命名空間 var MYNAMESPACE = MYNAMESPACE || {}; //構造函數 MYNAMESPACE.Child = function () {} // 變量 MYNAMESPACE.mystr= 6-ara forerer MYNAMESPACE.Person = function(name) { this.name = name; }; //原型 MYNAMES...
摘要:繼承的是超類型中構造函數中的屬性,如上繼承了屬性,但沒有繼承原型中的方法。上述造成的結果是子類型實例中有兩組超類型的構造函數中定義的屬性,一組在子類型的實例中,一組在子類型實例的原型中。 ECMAScript只支持實現繼承,主要依靠原型鏈來實現。與實現繼承對應的是接口繼承,由于script中函數沒有簽名,所以無法實現接口繼承。 一、原型鏈 基本思想:利用原型讓一個引用類型繼承另一個引用...
摘要:具體檢查方式則是檢查對象是否實現了接口所聲明的所有方法。組合模式將對象群體與組成對象同等對待。裝飾者模式透明地為另一對象提供包裝,實現相同的接口。 Javascript 中模仿接口的三種方法 1. 注釋描述 /* interface Composite { function add(child); function remove(child); function ge...
閱讀 3222·2021-11-23 09:51
閱讀 3566·2021-11-09 09:46
閱讀 3673·2021-11-09 09:45
閱讀 2949·2019-08-29 17:31
閱讀 1867·2019-08-26 13:39
閱讀 2726·2019-08-26 12:12
閱讀 3624·2019-08-26 12:08
閱讀 2243·2019-08-26 11:31