設(shè)計(jì)模式之簡(jiǎn)單工廠、工廠方法遵馆、抽象工廠

設(shè)計(jì)模式之簡(jiǎn)單工廠鲸郊、工廠方法、抽象工廠

什么是設(shè)計(jì)模式团搞?

設(shè)計(jì)模式(Design pattern)代表了最佳的實(shí)踐严望,通常被有經(jīng)驗(yàn)的面向?qū)ο蟮能浖_(kāi)發(fā)人員所采用。設(shè)計(jì)模式是軟件開(kāi)發(fā)人員在軟件開(kāi)發(fā)過(guò)程中面臨的一般問(wèn)題的解決方案逻恐。這些解決方案是眾多軟件開(kāi)發(fā)人員經(jīng)過(guò)相當(dāng)長(zhǎng)的一段時(shí)間的試驗(yàn)和錯(cuò)誤總結(jié)出來(lái)的像吻。

簡(jiǎn)單工廠模式

簡(jiǎn)單工廠模式(Simple Factory Pattern)是 Java 中最常用的設(shè)計(jì)模式之一。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式复隆,它提供了一種創(chuàng)建對(duì)象的方式拨匆。

在簡(jiǎn)單工廠模式中,包含必要的判斷邏輯挽拂,簡(jiǎn)單工廠實(shí)現(xiàn)了對(duì)象的創(chuàng)建和分離惭每。

在不修改任何客戶(hù)端代碼的情況下更換和增加新的具體產(chǎn)品類(lèi),在一定程度上提高了系統(tǒng)的靈活性亏栈。

何時(shí)使用:

我們明確地計(jì)劃不同條件下創(chuàng)建不同實(shí)例時(shí)台腥。

缺點(diǎn):

(1)工廠類(lèi)的職責(zé)過(guò)重,從類(lèi)圖中可以看出簡(jiǎn)單工廠中包含加減乘除的邏輯判斷語(yǔ)句绒北,它一旦有問(wèn)題打毛,整個(gè)系統(tǒng)都要出問(wèn)題
(2)在添加新的類(lèi)的時(shí)候沿后,例如我添加了開(kāi)根號(hào)運(yùn)算是尔,那么系統(tǒng)中的簡(jiǎn)單工廠類(lèi)就要修改烙样,違反了開(kāi)放——封閉原則贴汪!這樣及其不利于系統(tǒng)的擴(kuò)展和維護(hù)!
(3)簡(jiǎn)單工廠的靜態(tài)方法休吠,使得工廠角色無(wú)法形成基于繼承的等級(jí)結(jié)構(gòu)扳埂!

實(shí)例:

畫(huà)圓形

Shape shape= ShapeFactory.getShape("circle");
shape.draw();

畫(huà)正方形

Shape shape= ShapeFactory.getShape("rect");
shape.draw();

畫(huà)三角形

Shape shape= ShapeFactory.getShape("triangle");
shape.draw();

其中,Shape為interface或者抽象類(lèi)瘤礁,包括了draw()方法阳懂。ShapeFactory(工廠)肯定是一個(gè)類(lèi),getShape是其靜態(tài)方法蔚携,所以可以直接調(diào)用希太。圓形、正方形酝蜒、三角形,都是實(shí)現(xiàn)了Shape接口/抽象類(lèi)的對(duì)應(yīng)子類(lèi)矾湃。

工廠

public class ShapeFactory {
          public static final String TAG = "ShapeFactory";
          public static Shape getShape(String type) {
              Shape shape = null;
              if (type.equalsIgnoreCase("circle")) {
                  shape = new CircleShape();
              } else if (type.equalsIgnoreCase("rect")) {
                  shape = new RectShape();
              } else if (type.equalsIgnoreCase("triangle")) {
                  shape = new TriangleShape();
              }
              return shape;
          }
   }

工廠方法模式

工廠模式(Factory Pattern)是 Java 中最常用的設(shè)計(jì)模式之一亡脑。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式邀跃。

在工廠模式中霉咨,我們?cè)趧?chuàng)建對(duì)象時(shí)不會(huì)對(duì)客戶(hù)端暴露創(chuàng)建邏輯,并且是通過(guò)使用一個(gè)共同的接口來(lái)指向新創(chuàng)建的對(duì)象拍屑。

在增加修改新的運(yùn)算類(lèi)的時(shí)候不用修改代碼途戒,只需要增加對(duì)應(yīng)的工廠就好,完全符合開(kāi)放——封閉性原則僵驰。

并且創(chuàng)建對(duì)象的細(xì)節(jié)完全封裝在具體的工廠內(nèi)部喷斋,而且有了抽象的工廠類(lèi),所有的具體工廠都繼承了自己的父類(lèi)蒜茴,體現(xiàn)了多態(tài)性星爪。

何時(shí)使用:

我們明確地計(jì)劃不同條件下創(chuàng)建不同實(shí)例時(shí)。

缺點(diǎn):

(1)在增加新的產(chǎn)品時(shí)粉私,也必須增加新的工廠類(lèi)顽腾,會(huì)帶來(lái)額外的開(kāi)銷(xiāo)
(2)抽象層的加入使得理解程度加大

實(shí)例:

工廠:

public interface ShapeFactory{
    void draw();
}

具體工廠(圓形)

public class CircleFactory implements ShapeFactory{
    void draw(){
        /*具體實(shí)現(xiàn)*/
    }
}

具體工廠(正方形)

public class RectFactory implements ShapeFactory{
    void draw(){
        /*具體實(shí)現(xiàn)*/
    }
}

具體工廠(三角形)

public class TriangleFactory implements ShapeFactory{
    void draw(){
        /*具體實(shí)現(xiàn)*/
    }
}

畫(huà)圓形

ShapeFactory factory= new CircleFactory();
Shape shape = factory.getShape();
shape.draw();

畫(huà)正方形

ShapeFactory factory= new RectFactory();
Shape shape = factory.getShape();
shape.draw();

畫(huà)三角形

ShapeFactory factory= new TriangleFactory();
Shape shape = factory.getShape();
shape.draw();

“工廠方法模式讓一個(gè)類(lèi)的實(shí)例化延遲到其子類(lèi)”其實(shí)指的是,工廠方法模式先需要實(shí)例化工廠诺核,然后才能用該工廠實(shí)例造對(duì)應(yīng)的實(shí)例抄肖。而不是直接通過(guò)工廠類(lèi)+靜態(tài)方法來(lái)造實(shí)例。

抽象工廠模式

抽象工廠模式(Abstract Factory Pattern)是圍繞一個(gè)超級(jí)工廠創(chuàng)建其他工廠窖杀。該超級(jí)工廠又稱(chēng)為其他工廠的工廠漓摩。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式陈瘦。

在抽象工廠模式中幌甘,接口是負(fù)責(zé)創(chuàng)建一個(gè)相關(guān)對(duì)象的工廠潮售,不需要顯式指定它們的類(lèi)。每個(gè)生成的工廠都能按照工廠模式提供對(duì)象锅风。

抽象工廠模式除了具有工廠方法模式的優(yōu)點(diǎn)外酥诽,最主要的優(yōu)點(diǎn)就是可以在類(lèi)的內(nèi)部對(duì)產(chǎn)品族進(jìn)行約束。所謂的產(chǎn)品族皱埠,一般或多或少的都存在一定的關(guān)聯(lián)肮帐,抽象工廠模式就可以在類(lèi)內(nèi)部對(duì)產(chǎn)品族的關(guān)聯(lián)關(guān)系進(jìn)行定義和描述,而不必專(zhuān)門(mén)引入一個(gè)新的類(lèi)來(lái)進(jìn)行管理边器。

何時(shí)使用:

系統(tǒng)的產(chǎn)品有多于一個(gè)的產(chǎn)品族训枢,而系統(tǒng)只消費(fèi)其中某一族的產(chǎn)品。

缺點(diǎn):

產(chǎn)品族的擴(kuò)展將是一件十分費(fèi)力的事情忘巧,假如產(chǎn)品族中需要增加一個(gè)新的產(chǎn)品恒界,則幾乎所有的工廠類(lèi)都需要進(jìn)行修改。所以使用抽象工廠模式時(shí)砚嘴,對(duì)產(chǎn)品等級(jí)結(jié)構(gòu)的劃分是非常重要的十酣。

實(shí)例:

圖形接口:

public interface Shape{
    void draw();
}

畫(huà)圓形

public class Circle implements Shape{
    @Override
    void draw(){
        /*具體實(shí)現(xiàn)*/
    }
}

畫(huà)正方形

public class Rectanglet implements Shape{
    @Override
    void draw(){
        /*具體實(shí)現(xiàn)*/
    }
}

畫(huà)三角形

public class Triangle implements Shape{
    @Override
    void draw(){
        /*具體實(shí)現(xiàn)*/
    }
}

顏色接口

public interface Color {
   void fill();
}

紅色

public class Red implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Red::fill() method.");
   }
}

綠色

public class Green implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Green::fill() method.");
   }
}

藍(lán)色

public class Blue implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}

抽象工廠

public abstract class AbstractFactory {
   public abstract Color getColor(String color);
   public abstract Shape getShape(String shape) ;
}

圖形工廠

public class ShapeFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("circle")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("rectangle")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("triangle")){
         return new Triangle();
      }
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      return null;
   }
}

顏色工廠

public class ColorFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      if(color == null){
         return null;
      }        
      if(color.equalsIgnoreCase("red")){
         return new Red();
      } else if(color.equalsIgnoreCase("green")){
         return new Green();
      } else if(color.equalsIgnoreCase("blue")){
         return new Blue();
      }
      return null;
   }
}

工廠創(chuàng)造器

public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if(choice.equalsIgnoreCase("shape")){
         return new ShapeFactory();
      } else if(choice.equalsIgnoreCase("color")){
         return new ColorFactory();
      }
      return null;
   }
}

Test

public class Test {
   public static void main(String[] args) {
 
      //獲取形狀工廠
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
 
      //獲取形狀為 Circle 的對(duì)象
      Shape shape1 = shapeFactory.getShape("circle");
      //調(diào)用 Circle 的 draw 方法
      shape1.draw();
 
      //獲取形狀為 Rectangle 的對(duì)象
      Shape shape2 = shapeFactory.getShape("rectangle");
      //調(diào)用 Rectangle 的 draw 方法
      shape2.draw();
      
      //獲取形狀為 Triangle 的對(duì)象
      Shape shape3 = shapeFactory.getShape("triangle"); 
      //調(diào)用 Triangle 的 draw 方法
      shape3.draw();
 
      //獲取顏色工廠
      AbstractFactory colorFactory = FactoryProducer.getFactory("color");
       
      //獲取顏色為 Red 的對(duì)象
      Color color1 = colorFactory.getColor("red"); 
      //調(diào)用 Red 的 fill 方法
      color1.fill();
      
       //獲取顏色為 Green 的對(duì)象
      Color color2 = colorFactory.getColor("green") 
      //調(diào)用 Green 的 fill 方法
      color2.fill();
 
      //獲取顏色為 Blue 的對(duì)象
      Color color3 = colorFactory.getColor("blue"); 
      //調(diào)用 Blue 的 fill 方法
      color3.fill();
   }
}

抽象工廠中,一個(gè)產(chǎn)品族中的多個(gè)對(duì)象被設(shè)計(jì)成一起工作時(shí)际长,它能保證客戶(hù)端始終只使用同一個(gè)產(chǎn)品族中的對(duì)象耸采。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市工育,隨后出現(xiàn)的幾起案子虾宇,更是在濱河造成了極大的恐慌,老刑警劉巖如绸,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘱朽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡竭沫,警方通過(guò)查閱死者的電腦和手機(jī)燥翅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蜕提,“玉大人森书,你說(shuō)我怎么就攤上這事』咽疲” “怎么了凛膏?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)脏榆。 經(jīng)常有香客問(wèn)我猖毫,道長(zhǎng),這世上最難降的妖魔是什么须喂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任吁断,我火速辦了婚禮趁蕊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仔役。我一直安慰自己掷伙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布又兵。 她就那樣靜靜地躺著任柜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沛厨。 梳的紋絲不亂的頭發(fā)上宙地,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音逆皮,去河邊找鬼宅粥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛电谣,可吹牛的內(nèi)容都是我干的粹胯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辰企,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了况鸣?” 一聲冷哼從身側(cè)響起牢贸,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎镐捧,沒(méi)想到半個(gè)月后潜索,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡懂酱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年竹习,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片列牺。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡整陌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瞎领,到底是詐尸還是另有隱情泌辫,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布九默,位于F島的核電站震放,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏驼修。R本人自食惡果不足惜殿遂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一诈铛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧墨礁,春花似錦幢竹、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蜕企,卻和暖如春咬荷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背轻掩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工幸乒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唇牧。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓罕扎,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親丐重。 傳聞我的和親對(duì)象是個(gè)殘疾皇子腔召,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 總結(jié)一下23中設(shè)計(jì)模式各自的優(yōu)缺點(diǎn),及實(shí)際情況中如何使用扮惦。 詳細(xì)解析如下臀蛛,使用實(shí)例代碼地址:https://git...
    chanyi閱讀 800評(píng)論 0 0
  • 1. 如何判斷你已經(jīng)掌握了某種設(shè)計(jì)模式?(非常重要) ① 這個(gè)模式的意圖是什么崖蜜?它解決了什么問(wèn)題浊仆、什么時(shí)候可以使用...
    望穿秋水小作坊閱讀 235評(píng)論 0 0
  • 設(shè)計(jì)模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計(jì)原則時(shí)需要注意以下幾點(diǎn):a) 高內(nèi)聚、低耦合和單一職能的“沖突”實(shí)際上豫领,這兩者...
    彥幀閱讀 3,752評(píng)論 0 14
  • 設(shè)計(jì)模式匯總 一抡柿、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,948評(píng)論 1 15
  • 夜鶯2517閱讀 127,724評(píng)論 1 9