學習JavaScript設計模式——工廠模式(二)

工廠方法模式——給我一張名片

工廠方法模式:

  • 通過對產品類抽象使其創建業務,主要負責用于創建多類產品的實例。
  • 本意是說將實際創建對象工作推遲到子類當中.(在子類當中寫具體邏輯代碼,Java abstract 抽象類)
  • Java?Script中將工廠方法看做一個實例化對象的工廠類
  • 最好使用安全模式類,即給個類型的判斷(this instanceof 類)

安全模式

  var Demo = function(){
    if(!this instanceof Demo){
      return new Demo()
    }
  }
  
  Demo.prototype = {
    show: function(){
      console.log('獲取成功')
    }
  }
  
  var d = Demo()
  
  d.show()
  

安全的工廠方法

  // 安全模式創建的工廠類
  var Factory = fucntion(type, content) {
     if(this instanceof Factory) {
        var s = new this[type](content)
        return s
     } else {
        return new Factory(type, content)
     }
  }
  
  // 工廠原型中設置 創建所有類型數據對象 的基類
  Factory.prototype = {
   Java: function(content) {
     // ......
   },
   JavaScript: function(content) {
    // ......
   },
   UI: function(content) {
     this.content = content;
     (function(content){
        var div = document.createElement('div');
        div.innerHTML = content
        div.style.border = '1px solid red'
        document.getElementById('container').applendChild(div)
     })(content)
   },
   php: function(content) {
     // ......
   }
  }

工廠方法模式的好處

  1. 如果想添加其他類,不需要修改工廠類,而只需要在工廠類的原型里進行添加所需要的基類即可
  2. 好比你在Facroty類的原型里面注冊了一張名片,以后需要哪類直接拿著這張名片,查找這上面的信息就能找到這個類了(可以根據參數查找工廠的所需要的類),不用擔心使用時找不到基類
  3. 可以輕松創建多個類的實例對象,避免使用者與對象類之間的耦合,用戶不必關心創建該對象的具體類,只需要調用工廠方法即可

抽象工廠模式——出現的都是幻覺

  • 通過對類的工廠抽象使其業務用于對產品類簇的創建,而不負責創建某一類產品的實例
  • 一般用抽象工廠模式作為父類來創建一些子類

示例代碼

 var VehicleFactory = function(subType, superType){
   if(typeof VehicleFactory[superType] === 'function'){
      // 緩存類
      function F(){}
      // 繼承父類的屬性和方法
      F.prototype = new VehicleFactory[superType]()
      // 將子類的constructor指向子類
      subType.constuctor = subType
      // 子類原型繼承"父類"(父類的一個實例)
      subType.prototype = new F()
   } else {
      // 拋出未創建抽象類的錯誤
      throw new Error('為創建該抽象類')
   }
 }
 
 // 小汽車抽象類
 VehicleFactory.Car = function(){
   this.type = 'car' 
 }
 
 VehicleFactory.Car.prototype = {
   getPrice: function(){
     return new Error('抽象方法不能調用')
   },
   getSpeed: function(){
     return new Error('抽象方法不能調用')
   }
 }
 
 // 公共汽車抽象類
 VehicleFactory.Bus = function(){
   this.type = 'bus'
 }
 
 VehicleFactory.Bus.prototype = {
   getPrice: function(){
     return new Error('抽象方法不能調用,只能重寫')
   },
   getPassengerNum: function(){
     return new Error('抽象方法不能調用,只能重寫')
   }
 }
 
 // 卡車抽象類
 VehicleFactory.Truck = function(){
   this.type = 'truck'
 }
 
 VehicleFactory.Truck.prototype = {
   getPrice: function(){
     return new Error('抽象方法不能調用,只能重寫')
   },
   getTrainload: function(){
     return new Error('抽象方法不能調用,只能重寫')
   }
 }
  

從上面代碼可以看出

  • 抽象工廠其實是一個實現子類繼承父類的方法
  • 在這個方法中我們需要通過傳遞子類以及要繼承父類(抽象類)的名稱
  • 并且在抽象工廠方法中又增加了一次對抽象類存在性的一次判斷,如果存在,則將子類繼承父類的方法
  • 然后子類通過寄生式繼承,不過不是繼承父類的原型,而是通過new關鍵字復制父類的一個實例(這么做的原因是因為過渡類不應僅僅繼承父類的原型方法,還要繼承父類的對象屬性,所以要通過new關鍵字將父類的構造函數執行一遍來復制構造函數中的屬性和方法)
  • 對抽象工廠添加抽象類也很特殊,因為抽象工廠是個方法不需要實例化對象,所以只需要一份,因此直接為抽象工廠添加類的屬性即可

使用方法

 // 寶馬汽車類
 let BMW = function(price, speed){
   this.price = price;
   this.speed = speed;
 }
 
 // 使用抽象工廠方法繼承抽象類‘Car’
 VehicleFactory(BMW,'Car')
 // 重寫抽象類的方法
 BMW.prototype.getPrice = function(){
    return this.price
 }
 
 BMW.prototype.getSpeed = function(){
    return this.speed
 }
 
 // 宇通汽車類
 let YUTONG = function(price, passenger) {
   this.price = price;
   this.speed = passenger;
 }
 // 抽象工廠實現對Bus抽象類的繼承
 VehicleFactory(YUTONG, 'Bus')
 // 重寫抽象類的方法
 YUTONG.prototype.getPrice = function(){
   return this.price
 }
 
 YUTONG.prototype.getPassengerNum = function(){
   return this.passenger
 }
 
 // 奔馳卡車類
 let BenzTruck = function(price, trainload){
   this.price = price;
   this.trainload = trainload;
 }
 
 // 抽象工廠實現對Truck抽象類的繼承
 VehicleFactory(BenzTruck, 'Truck')
 // 重寫抽象類的方法
 BenzTruck.prototype.getSpeed = function(){
   return this.speed
 }
 
 BenzTruck.prototype.getTrainload = function(){
   return this.trainload
 }
 
 // 實例化
 let car = new BMW(200000, 100)
 console.log(car.getPrice())    // 200000
 console.log(car.type)          // car

自己這些代碼的過程中

  • 抽象工廠方法的意義在于,實現子類對父類(抽象類)的繼承,從而繼承抽象類的屬性和方法,對抽象類的方法進行重寫,達到復用的目的
  • 可以對多個抽象類進行封裝,能夠方便管理
  • 和Java的抽象類達到比較相似的程度

由于更熟悉這個抽象工廠模式,從而自己寫了幾次,所以更新的比較慢,見諒,主要是想要徹底熟悉了解這個抽象工廠方法

收獲:

  • 抽象工廠模式是設計模式中最抽象的一種,也是創建模式中唯一一種抽象化創建模式。
  • 該模式創建出的結果不是一個真實的對象實例,而是一個類簇(管理多個抽象類),它制定了類的結構
  • 區別于 簡單工廠模式 創建單一對象, 工廠方式模式創建多累對象
  • 由于JavaScript中不支持抽象化創建與虛擬方法,所以導致這種模式不能像其他面向對象語言中應用得那么廣泛

工廠模式主要是為了創建對象實例或者類簇(抽象工廠),關心的是最終產出(創建)的是什么。不關心創建的整個過程,僅僅需要知道最終創建的結果。得到的都是對象實例或者類簇。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容