首頁 >Java >java教程 >Java設計模式簡單工廠模式

Java設計模式簡單工廠模式

高洛峰
高洛峰原創
2016-12-15 14:16:521741瀏覽

1.1 簡單工廠(Simple Factory)模式


簡單工廠模式是類別的創建,又稱為靜態工廠方法(Static Factory Methord)模式。簡單工廠模式是由一個工廠物件決定要創造哪一種產品類別的實例。

 

1.1.1 工廠模式的幾種形態


工廠模式專門負責將大量有共同介面的類別實例化。工廠模式可以動態的決定將哪一個類別實例化,工廠模式有以下幾種形態:
 簡單工廠(Simple Factory)模式:又稱靜態工廠方法(Static Factory Methord)模式。
 工廠方法(Factory Method)模式:又稱為多態性工廠(Polymorphic Factory)模式或虛擬建構子(Virtual Constructor)模式。
 抽象工廠(Abstract Factory)模式:又稱工具箱(Kit或Toolkit)模式。
下圖所示的就是簡單工廠模式的簡略類別圖。

Java設計模式簡單工廠模式

簡單工廠模式,或稱為靜態工廠方法模式,是不同工廠方法模式的一個特殊實現。在Java語言中,通常的工廠方法模式不能透過設計功能的退化給出靜態工廠方法模式。

 

1.1.2 簡單工廠模式的引進(一般模式)
例如有農場,生產各種水果,有蘋果(Apple)、草莓(Strawberry)、葡萄(Grape);農場的園丁(FruitGardener)要根據客戶的需求,提供相應的水果。以下來看看是如何用簡單工廠模式實現這個過程的,如下圖:

Java設計模式簡單工廠模式

此模式的實作源碼如下:

 

1.1.2.1 產品介面.patterns.simplefactory.ybgc;

/**

 * Created by IntelliJ IDEA.
 * FileName:Fruit.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Date:    2006-12-100 著)讀書筆記
 * 工廠模式模式--簡單工廠模式--一般模式
 * ReadMe:  抽象產品角色:工廠的水果產品介面--水果
 */
public interface Fruit {
    /**
     * 植牙
    */
    void plant(); ();

    /**

     * 生長

    */
    void harvest();
}

 


1.1.2.2 產物
/**
     * 收穫
    */

public class Apple implements Fruit {

    private int treeAge;

    /**
 * Created by IntelliJ IDEA.

 * FileName:Apple.java

 * User:    LavaSoft
 * Date:   著)讀書筆記
 * 工廠模式模式--簡單工廠模式--一般模式
 * ReadMe:  水果工廠的產品:蘋果
 */ ted .");
    }

    /**
     * 植牙
    */
    public void grow() {
        System.out.println("Apple

        System.out.println("Apple); & */

    public void harvest() {
        System.out.println("Apple has been harvested.");
    }       return treeAge;
    }

    /**

     * 生長

    */
    public void setTreeAge(int treeAge) {
        this.treeAge = treeAge        this.treeAge = treeAge
;

1.1.2.3 產品草莓類:Strawberry.java
package com.lavasoft.patterns.simplefactory.ybgc;

/**
 * Created by IntelliJ IDEA.
 * FileName:Strawberry.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * 對博士著)讀書筆記
 * 工廠模式模式--簡單工廠模式--一般模式
 * ReadMe:  水果工廠的產品:草莓
 */
public class Strawberry Implements Fruit {/**
     * 生長
    */public class Strawberry Implements Fruit { "草莓已收成。");
    }

    /**

     * 收穫
    */
    public void plant() {
     *
     * 植牙
    */

    public static void log(String msg) {

        System.out.println(msg);
    }
}
softosofthp . patterns.simplefactory.ybgc;

/**

     * 輔助方法

    */
public class Grape 實作Fruit {
    private boolean 無籽;   // 是否有種子
🠎) v. – {
        System.out.println("葡萄種下。");
    }

    /**

 * Created by IntelliJ IDEA.

 * FileName:Grape.java

 * User:    LavaSoft
 * Date:    2006-12-100 著)閱讀筆記

 * 工廠模式模式--簡單工廠模式--一般模式

 * ReadMe:  水果工廠的產品:葡萄
 */ ? "葡萄/
    public boolean getSeedless() {
        return Seedless;
    }

   less />
     * 植牙
    o/  }

   less />
     * 生長

    o//🠎)//

    this.seedless = 無種子;
    }

    /**
     * 收穫
    */

    public static void log(String msg) {

        System.out.println(msg);
    }
}
園林類:55 .lavasoft.patterns .simplefactory.ybgc;

/**
 * Created by IntelliJ IDEA.
 * FileName:FruitGardener.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * 20博士著)讀書筆記
 * 工廠模式模式--簡單工廠模式--一般模式
 * ReadMe:  工廠類角色: 水果園丁,生產水果產品
 */
public class FruitGardener {
    /**
     * 靜態工廠方法
     * @param which :特定的產品名稱
     * @return 水果物件
     */
    public static Fruit factory(String which) 
            return new Apple();
        } else if (which.equalsIgnoreCase("strawberry")) {
         Case("grape")) {
            return new Grape();
} else {
            throw new BadFruitException("Bad fruit request");
       FruitException.java
package com.lavasoft.patterns.simplefactory.ybgc;

/**

 * Created by IntelliJ IDEA.

 * FileName:BadFruitException.java

 * User:    LavaSoft
 * Date:    閻宏博士著)讀書筆記

 * 工廠模式模式--簡單工廠模式--一般模式

 * ReadMe:  工廠的異常處理類
 */
public class BadFruitException extends Exception {
    public BadFruitException(String msg) {
       
1.1.2.7 一般工廠模式的測試類別
package com.lavasoft.patterns.simplefactory.ybgc;

/**
 * Created by IntelliJ IDEA.
 * FileName:TestApp.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1

 * Date:    2006-12-1

 * @著)讀書筆記

 * 工廠模式模式--簡單工廠模式--一般模式

 * ReadMe:  一般工廠模式的測試類別
 */

public class TestApp {

    /**
     * 測試方法
    */
   testvate void try {
            Fruit f = FruitGardener.factory(fruitName);
          adFruitException e) {
            System.out.println("對不起!工廠目前不能生產你所要的產品:" + fruitName);
            System.out.println(e.getMessage());                    //輸出異常堆疊資訊
        }
    }

    /**
     * 應用入口方法
    */
    public static void main(String args[]) {
             t.test("grape ");
        t.test("strawberry");

        t.test("car");  //此處投擲異常,水果工廠能生產car(轎車)! }

 

1.1.2.8 測試運行結果
恭喜!生產了一個水果對象:apple
恭喜!生產了一個水果對象:grape
恭喜!生產了一個水果對象:strawberry
對不起!工廠目前不能生產你所要的產品:car
Bad fruit request
com.lavasoft.patterns.simplefactory.ybgc.BadFruitException: Bad fruit request
 at com.lavasoft.patterns.simplefactory.ybgc.FruitGardener。 simplefactory.ybgc.TestApp.test(TestApp.java:19)
 at com.lavasoft.patterns.simplefactory.ybgc.TestApp.main(TestApp.java:37) at sun.reflect.Native at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at javalang. at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)

Process finished with exit code 0

從結果看來,有異常,是因為輸入了工廠不能生產的類型car (小汽車),哈哈哈哈,果園能生產汽車嗎?讓幼稚園的小朋友告訴你吧!


 

1.1.3 簡單工廠模式的一般性結構

 

總結一下,從上面的簡單工廠模式的實現可以看到,簡單工廠模式需要實作

 工廠角色:園藝生水果介面
 特定產品:蘋果、葡萄、草莓

另外還一般還需要實現

 工廠異常類
 客戶類
簡單工廠模式的一般性結構圖如下:




1.1.4簡單工廠模式的實作

 Java設計模式簡單工廠模式

1.1.4.1 使用介面或抽象類別實作多層次的產品結構

工廠類別可以有多個靜態的工廠方法,分別用來生產不同的產品物件。

 

1.1.4.2 多個工廠方法

分別負責創建不同的產品對象,例如java.text.DateFormat類別是其子類別的工廠類,而DateFormat類別就是提供了多個靜態工廠方法。

 

1.1.4.3 抽象產品角色的省略
如果系統只有一個具體產品角色產品角色的話,那麼就可以省略掉抽象產品角色。省略掉抽象產品角色後的簡略類別圖如下:


下面是一個例子,工廠角色創建特定產品,原始碼如下:

 Java設計模式簡單工廠模式

1.1.4.3.1 產品角色:ConcreteProductage .lavasoft.patterns.simplefactory.gchb;

/**

 * Created by IntelliJ IDEA.

 * FileName:ConcreteProduct.java

 * User:    LavaSoft
 * Date:    2006-12-1

 * Date:    2006-12-1

 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
, 2: 8: 宏博士著)讀書筆記
 * 工廠模式--簡單工廠模式--工抽合併(工廠角色與抽象產品角色合併)
 * ReadMe:  具體產品類,表示單一的一類產品.
 */
public class ConcreteProduct {
    public ConcreteProduct() {
 age com. lavasoft.patterns.simplefactory.gchb;

/**
 * Created by IntelliJ IDEA.
 * FileName:Creator.java

 * User:    LavaSoft

 * Date:    2006-12-1

 * Date:    2006-12-1

 * Date:    2006-12-1
 * Date:    2006-12-1

 * Date:    2006-12-1

 *:  著)讀書筆記
 * 工廠模式--簡單工廠模式--工抽合併(工廠角色與抽象產品角色合併)
 * ReadMe:  特定產品類,與抽象產品角色合併,只生產單一種類產品.
 */
public class Creator {
    /**
     * 靜態工廠方法
     * @return 一個產品
    */
   
}

 

1.1.4.3.3 測試類別
package com.lavasoft.patterns.simplefactory.gchb;

/**
 * Created by IntelliJ IDEA.
 * FileName:TestApp.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * 對博士  著)閱讀筆記
 * 工廠模式--簡單工廠模式--工抽合併(工廠角色與抽象產品角色合併)
 * ReadMe:  工抽合併測試類別
 */
public class TestApp {
    private void test() {
        Creator t = Creator.factory();

public static void main(String args[]) {

        new TestApp().test();
    }
}

 

 


1.1.4.4 工廠角色與抽象角色合併

在某些情況下,工廠角色可以由抽象產品角色扮演。典型的應用就是java.text.DateFormat類,一個抽象產品類同時是子類的工廠,如下圖所示:

下面是我自己寫的一個實現,源代碼如下:

 

Java設計模式簡單工廠模式1.1 .4.4.1 抽象產品類別(同時又是工廠類別)

package com.lavasoft.patterns.simplefactory.cxsl;

/**

 * Created by IntelliJ IDEA.

 * FileName:AbsProduct.java

 * User:    LavaSoft
 * Date:    2006-12-3

 * Date:    2006-12-3

 * Date:    2006-12-3
 * Date:    2006-12-3
 * Date:  博士著)讀書筆記
 * 工廠模式--簡單工廠模式--工廠角色與抽象產品角色合併
 * ReadMe:  抽象產品類,同時又是工廠類.
 */
public abstract class AbsProduct {) return new Product();
    }
}

 

1.1.4.4.2 特定產品類別
package com.lavasoft.patterns.simplefactory.cxslct; Product(){
    }

}

 


1.1.4.4.3 測試類

package com.lavasoft.patterns.simplefactory.cxsl;


/**
 * Created by IntelliJ IDEA.
 * FileName:Product.java
 * User:    LavaSoft
 * Date:    2006-12-3
 * Date:    2006-12-3
 * Date:    2006-12-3
 * Date:    2006-12-3
 *:  著)閱讀筆記
 * 工廠模式--簡單工廠模式--工廠角色與抽象產品角色合併
 * ReadMe:  特定產品類
 */
public class TestApp {

    private void test () {

        Product a = AbsProduct.factory();

        System.out.println("成功建立一個產品物件!");       TestApp test = new TestApp();

        test.test();
    }

}


 

 

1.1.4.4.

 

1.1.4.4.

Process finished with exit code 0


 

這個實作很簡單,程式碼就不做詳細解釋了!

 

1.1.4.5 三個角色全部合併

如果在上面例子的基礎上,連抽象產品角色都省略了,而工廠角色就可以與具體產品角色合併。換言之,一個產品類為自身的工廠。如下圖所示:

下面給出一個簡單的實作範例如下:

 

1.1.4.5.1 特定產品類別

package com.lavasoft.patterns.simplefactory.shshb;

/**
 * Created by IntelliJ IDEA.
 * FileName:ConcreteProduct.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:   / 宏博士著)讀書筆記
 * 工廠模式--簡單工廠模式--三色合一模式
 * ReadMe:  抽象產品,產品,工廠類三和一後的具體產品類
 */
public class ConcreteProduct

{

 public ConcreteProduct(){}

    /**
     * 靜態工廠方法
     * @return 特定的產品ConcreteProduct實例
    */🠎  return new ConcreteProduct();
    }
}

 

1.1.4.5.2 測試類別

package com.lavasoft.patterns.simplefactory.sshb;

/**

 * Created by IntelliJ IDEA.
 * FileName:TestApp.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * Date:    2006-12-1
 * 對博士  著)讀書筆記
 * 工廠模式--簡單工廠模式--三色合一模式
 * ReadMe:  測試方法

 */public🠎 test (){

        ConcreteProduct t=ConcreteProduct.factory();
        System.out.println("產品成功生產! ){
        new TestApp() .test();
    }
}

 

1.1.4.5.3 測試運算

 

1.1.4.6 產品物件的循環使用和登記式的工廠方法

這裡在單例模式和多例模式中在討論。

簡單工廠模式的優點和缺點

 


1.1.4.6.1 簡單工廠模式的優點

核心式工廠類,工廠類別決定在什麼情況下創建哪種產品類的實例。而客戶端則可以免除直接創建產品物件的責任,而僅僅是「消費」產品。簡單工廠模式透過這種做法實現了責任的分割。

 

1.1.4.6.2 簡單工廠模式的缺點

當產品類別具有複雜的多層等級結構時,工廠類別只有它自己。以不變應萬變,是其缺點。
這個工廠類集中了所有產品創建邏輯,形成了一個無所不知的全能類(也稱上帝類),如果此類出問題了,整個應用都受大影響。
當產品有多個介面時,判斷在什麼條件下創建什麼產品類實例會很困難。

對於工廠來說,增加新的產品時一個痛苦的過程。工廠角色必須知道每種產品,如何創建它們,以及何時向客戶提供它們。換言之,接納新的產品意味著修改這個工廠角色的原始碼。簡單工廠只在有限的程度上支持「開-閉」原則。

由於簡單工廠模式使用靜態方法作為工廠方法,而靜態方法無法由子類別繼承,因此工廠角色無法形成基於繼承的等級結構。這項缺點會在工廠方法模式中克服。

 

1.1.4.7 簡單工廠模式在Java中的應用

DateFormat與簡單工廠模式

SAX2庫中的XMLReaderFactory與簡單工廠模式


 出一個個的人,這就是簡單工廠模式的應用,類別圖如下:



女媧是工廠角色,人是抽象產品角色,張三李四是產品。具體實現就不在給了,參考園丁生產水果的例子。



更多Java設計模式簡單工廠模式相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn