熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

爪哇語言工廠方法創立性模式介紹(上)

2022-06-13   來源: Java高級技術 

  正如同筆者在<簡單工廠模式>一節裡介紹的工廠模式有簡單工廠模式工廠方法模式和抽象工廠模式幾種形態簡單工廠模式已經在前面作過介紹在簡單工廠模式中一個工廠類處於對產品類實例化調用的中心位置上它決定那一個產品類應當被實例化 如同一個交通警察站在來往的車輛流中決定放行那一個方向的車輛向那一個方向流動一樣
  而本節要討論的工廠方法模式是簡單工廠模式的進一步抽象化和推廣它比簡單工廠模式聰明的地方在於 它不再作為一個具體的交通警察的面貌出現而是以交通警察局的面貌出現它把具體的車輛交通交給下面去管理換言之工廠方法模式裡不再只由一個工廠類決定那一個產品類應當被實例化這個決定被交給子類去作處於工廠方法模式的中心位置上的類甚至都不去接觸那一個產品類應當被實例化這種細節這種進一步抽象化的結果是這種新的模式可以用來處理更加復雜的情形
  為什麼需要工廠方法模式
  現在讓我們繼續考察我們的小花果園在<簡單工廠模式>一節裡我們在後花園裡引進了水果類植物 構造了簡單工廠模式來處理 使用一個FruitGardener類來負責創立水果類的實例見下圖
   
  圖 簡單工廠模式FruitGardener掌握所有水果類的生殺大權 
  在這一節裡我們准備再次引進蔬菜類植物比如
  西紅柿 (Tomato)
  土豆 (Potato)
  西芥蘭花 (Broccoli)
  蔬菜與花和水果當然有共同點可又有不同之處蔬菜需要噴灑(dust)殺蟲劑(pesticide)除蟲 不同的蔬菜需要噴灑不同的殺蟲劑等等怎麼辦呢?
  那麼再借用一下簡單工廠模式不就行了? 再設計一個專管蔬菜類植物的工廠類比如
   
  圖 簡單工廠模式VeggieGardener掌握所有蔬菜類的生殺大權 
  這樣做一個明顯的不足點就是不夠一般化和抽象化在FruitGardener和VeggieGardener類之間明顯存在很多共同點 這些共同點應當抽出來一般化和框架化這樣一來如果後花園的主人決定再在園子裡引進些樹木類植物時 我們有框架化的處理方法本節所要引入的工廠方法模式就符合這樣的要求
  簡單工廠模式的回顧
  有必要首先回顧一下簡單工廠模式的定義以便於比較
   
  圖 簡單工廠模式的類圖定義 
  從上圖可以看出簡單工廠模式涉及到以下的角色
  工廠類 (Creator)
  擔任這個角色的是工廠方法模式的核心是與應用程序緊密相關的直接在應用程序調用下創立產品實例的那個類工廠類只有一個而且是實的見下面的位圖
   
  產品 (Product)
  擔任這個角色的類是工廠方法模式所創立的對象的父類或它們共同擁有的接口
  實產品 (Concrete Product)
  擔任這個角色的類是工廠方法模式所創立的任何對象所屬的類
  實產品類可以是分布在一維數軸上的分立點 中的任何一個見下面的位圖
   
  工廠方法模式的定義
  我們給出工廠方法模式的類圖定義如下
   
  圖 工廠方法模式的類圖定義 
  從上圖可以看出工廠方法模式涉及到以下的角色
  抽象工廠接口(Creator)
  擔任這個角色的是工廠方法模式的核心它是與應用程序無關的任何在模式中創立對象的工廠類必須實現這個接口
  實工廠類 (Conrete Creator)
  擔任這個角色的是與應用程序緊密相關的直接在應用程序調用下創立產品實例的那樣一些類
  實工廠類可以是分布在一維數軸上的分立點 中的任何一個見下面的位圖
   
  產品 (Product)
  擔任這個角色的類是工廠方法模式所創立的對象的父類或它們共同擁有的接口
  實產品 (Concrete Product)
  擔任這個角色的類是工廠方法模式所創立的任何對象所屬的類
  實產品類可以是分布在二維平面上的分立點 () () ()中的任何一個見下面的位圖
   
  由實工廠(橫數軸上第一點)創立的對象來自實產品類() () ()由實工廠(橫數軸上第二點)創立的對象來自實產品類() () ()依此類推 
  工廠方法模式和簡單工廠模式在定義上的不同是很明顯的工廠方法模式的核心是一個抽象工廠類而不像簡單工廠模式 把核心放在一個實類上工廠方法模式可以允許很多實的工廠類從抽象工廠類繼承下來 從而可以在實際上成為多個簡單工廠模式的綜合從而推廣了簡單工廠模式
  反過來講簡單工廠模式是由工廠方法模式退化而來設想如果我們非常確定一個系統只需要一個實的工廠類 那麼就不妨把抽象工廠類合並到實的工廠類中去而這樣一來我們就退化到簡單工廠模式了
  與簡單工廠模式中的情形一樣的是ConcreteCreator 的factory() 方法返還的數據類型是一個接口 PlantIF而不是哪一個具體的產品類這種設計使得工廠類創立哪一個產品類的實例細節完全封裝在工廠類內部
  工廠方法模式又叫多形性工廠模式顯然是因為實工廠類都有共同的接口或者都有共同的抽象父類
  工廠方法模式在小花果園系統中的實現
  好了現在讓我們回到小花果園的系統裡看一看怎樣發揮工廠方法模式的威力解決需要接連不斷向小花果園引進不同類別的植物所帶來的問題
  首先我們需要一個抽象工廠類比如叫做 Gardener作為兩個實工廠類 FruitGardener 及 VeggieGardener 的父類 Gardener 的 factory() 方法可以是抽象的留給子類去實現也可以是實的在父類實現一部分功能再在子類實現剩余的功能我們選擇將 factory() 做成抽象的主要是因為我們的系統是一個示范系統內容十分簡單沒有要在父類實現的任何功能
  
  圖 工廠方法模式在小花果園系統中的實現 
  抽象工廠類 Gardener 是工廠方法模式的核心但是它並不掌握水果類或蔬菜類的生殺大權相反地這項權力被交給子類即 VeggieGardener 及 FruitGardener
  package comjavapatternsfactorymethod;
  abstract public class Gardener
  {
   public abstract PlantIF factory(String which) throws BadFruitException;
  }
  代碼清單 父類 Gardener
  package comjavapatternsfactorymethod;
  
  public class VeggieGardener extends Gardener
  {
   public PlantIF factory(String which) throws BadPlantException
   {
  if (whichequalsIgnoreCase(tomato))
  {
   return new Tomato();
  }
  else if (whichequalsIgnoreCase(potato))
  {
   return new Potato();
  }
  else if (whichequalsIgnoreCase(broccoli))
  {
   return new Broccoli();
  }
  else
  {
   throw new BadPlantException(Bad veggie request);
  }
   }
  
  }
  代碼清單 子類 VeggieGardener
  
  package comjavapatternsfactorymethod;
  
  public class FruitGardener extends Gardener
  {
   public PlantIF factory(String which)
   {
  if (whichequalsIgnoreCase(apple))
  {
   return new Apple();
  }
  else if (whichequalsIgnoreCase(strawberry))
  {
   return new Strawberry();
  }
  else if (whichequalsIgnoreCase(grape))
  {
   return new Grape();
  }
  else
  {
   throw new BadPlantException(Bad fruit request);
  }
   }
  }
  代碼清單 子類 FruitGardener
  package comjavapatternsfactorymethod;
  
  public class Broccoli implements VeggieIF PlantIF
  {
   public void grow()
   {
  log(Broccoli is growing);
   }
  
   public void harvest()
   {
  log(Broccoli has been harvested);
   }
   public void plant()
   {
  log(Broccoli has been planted);
   }
   private static void log(String msg)
   {
  Systemoutprintln(msg);
   }
   public void pesticideDust(){ }
  }
  代碼清單 蔬菜類 Broccoli其它的蔬菜類與 Broccoli 相似因此不再贅述
  package comjavapatternsfactorymethod;
  public class Apple implements FruitIF PlantIF
  {
   public void grow()
   {
  log(Apple is growing);
   }
   public void harvest()
   {
  log(Apple has been harvested);
   }
   public void plant()
   {
  log(Apple has been planted);
   }

From:http://tw.wingwit.com/Article/program/Java/gj/201311/27652.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.