java設計模式:Factory 方法模式(Factory Method)

來源:互聯網
上載者:User

標籤:xtend   auto   角色   統一   abstract   runtime   問題   抽象   廠商   

Factory 方法模式

返回設計模式目錄

閱讀目錄:

  • 簡單原廠模式
    • 介紹
    • UML類圖
    • 參考代碼
    • 總結
  • Factory 方法模式
    • 介紹
    • UML類圖
    • 參考代碼
    • 總結
前言:

  《大話設計模式》裡有一小節叫‘活字印刷,物件導向‘的,講了一個小故事,大意如下:

  話說三國時期,曹操帶領大軍駐紮於赤壁。軍船相連,氣勢恢宏,眼看要滅掉東吳,統一天下,曹操甚悅,於是大宴群臣。席間曹操詩興大發,不覺吟道:"喝酒唱歌,人生真爽。……"。眾文武齊呼:"丞相好詩!"。於是一臣子速命印刷工匠刻板印刷,以便流傳天下。

  樣章出來曹操一看,感覺不妥,道:"喝與唱此話過俗,應該為‘對酒當歌‘較好!",於是此臣就命工匠重新來過,此工匠連夜之功就此白費,只得重刻之。

  樣章再次出來請曹操過目,曹操細細一品,覺得還是不好,說:"人生真爽太過直接,應改問語才夠意境,就改為‘對酒當歌人生幾何?……‘吧"。當臣子轉告工匠時,工匠暈倒。。。

  這裡的問題是三國時期活字印刷還未發明,所以改字的時候,就必須整塊板全部重刻!如果有了活字印刷,則只需更改四個字即可,其餘工作均未白做。

  第一,要改只需更改要改之字,此為可維護;第二,這些字並非這次用完就無用,完全可以在後來的印刷中重複使用,此乃可複用;第三此詩若要加字,只需另刻字加入即可,這是可擴充;第四字的排列其實可能豎排可能橫排,此時只需將活字移動即可滿足排列需求,此是靈活性好。編寫代碼時多考慮封裝,繼承,多態把程式的耦合度降低,使用物件導向思想使得程式更加的靈活,容易修改,並且易於複用。

  好了,說了這麼多,相信大家對設計模式多少有點感覺了。不錯,設計模式就是為了讓我們的代碼更靈活,易擴充,好維護和能複用。現在我們就先從原廠模式總結吧!

一、簡單原廠模式

1.介紹

  總結原廠模式之前先得說說簡單原廠模式。簡單原廠模式(又名靜態Factory 方法),不屬於GOF的23種設計模式之一。這種模式將建立對象的責任交由一個工廠對象,該工廠對象提供靜態公有方法向外提供產生對象的服務,所有產生對象的邏輯均包含在該靜態方法裡,對外不可見。簡單工廠是原廠模式裡最好理解的模式了,可以將其看作所有原廠模式的基礎。

2.UML類圖

  假裝這裡有類圖

3.參考代碼

//這是用戶端,public class Client {public static void main(String[] args) {// 用戶端只需要傳入需要的產品類型,就能得到對應的產品,使用者不需要知道建立產品的細節Product product = SimpleFactory.create("A");// Product product = SimpleFactory.create("B");// 調用產生產品的顯示價格方法product.showPrice();}}/** * 抽象產品角色 *  * @author ICE_melt * */interface Product {// 顯示產品價格public void showPrice();}// 具體產品Aclass ConcreateProductA implements Product {@Overridepublic void showPrice() {System.out.println("這是A產品,價格為10RMB,很便宜");}}// 具體產品Bclass ConcreateProductB implements Product {@Overridepublic void showPrice() {System.out.println("這是B產品,價格為600RMB,很貴的");}}/** * 工廠角色(即普通類提供了建立其他類的方法) *  * @author ICE_melt * */class SimpleFactory {/** * 簡單工廠一般為靜態方法,其內包含必要的邏輯判斷,能夠根據用戶端的條件建立具體的產品對象 * <br><b>剖析:</b> * <br>現在的產品都是基於<code>Product<code>介面的子類,如果增加產品,繼承體系沒有問題 * <br>但是工廠產生邏輯需要修改(增加if分支判斷邏輯),這一點違背了“開放封閉原則” */public static Product create(String type) {if ("A".equals(type)) {return new ConcreateProductA();} else if ("B".equals(type)) {return new ConcreateProductB();} else {new RuntimeException(type + "產品類型暫時不能生產,請聯絡生產廠商!");}return null;}}

4.總結

  簡單原廠模式的優點是分離了產品的建立者和使用者,有利於軟體系統結構的最佳化。局限是有需求變動時不修改代碼的話是不能夠擴充的。

返回頂部

 二、Factory 方法模式

1.介紹

  Factory 方法模式,又叫做多態性工廠。該模式定義一個用於建立對象的介面,讓子類決定執行個體化那一個產品對象。Factory 方法使一個類的執行個體化延遲到其子類。

2.UML類圖

  假裝有類圖

3.參考代碼

  首先是抽象產品類:

/** * 產品抽象 *  * @author ICE_melt * */public abstract class AbstractProduct {public AbstractProduct() {}// 所有產品都有對外展示的方法public abstract void display();}

 

  基礎抽象產品類的三種產品:

//產品--汽車public class CarProduct extends AbstractProduct {@Overridepublic void display() {System.out.println("我有四個輪子,在陸地上跑的飛快");}}
//產品--飛機public class AirplaneProduct extends AbstractProduct {@Overridepublic void display() {System.out.println("我有兩個機翼,能在天上飛");}}
//產品--輪船public class ShipProduct extends AbstractProduct {@Overridepublic void display() {System.out.println("我在海裡,速度很快");}}

  然後是工廠介面:

/** * 一個工廠介面,負責定義產品對象的生產 * (工廠介面也可以用抽象方法實現) * @author ICE_melt * */public interface IFactory {/* *  * 建立一個產品對象 */public AbstractProduct produceProduct();}

  工廠介面的三個具體工廠,每個工廠負責生產一種產品:

//汽車工廠,生產汽車public class CarFactory implements IFactory {@Overridepublic AbstractProduct produceProduct() {return new CarProduct();}}
//飛機工廠,生產飛機public class AirplaneFactory implements IFactory {@Overridepublic AbstractProduct produceProduct() {return new AirplaneProduct();}}
//輪船工廠,生產輪船public class ShipFactory implements IFactory {@Overridepublic AbstractProduct produceProduct() {return new ShipProduct();}}

  用戶端代碼:

/** * 用戶端代碼 * @author ICE_melt * */public class Client {public static void main(String[] args) {//這裡可以將工廠類的全路徑類名寫到項目的設定檔裡,並添加一個讀取該配置的方法String factoryConfig = readConfig();IFactory factory;try {//用戶端代碼只與抽象工廠 和 抽象產品 這兩個頂級介面耦合,//後台增加 一種新的產品的話,只需要同時增加 該產品的工廠類,//不需要修改任何已存在的代碼factory = (IFactory)Class.forName(factoryConfig).newInstance();AbstractProduct product = factory.produceProduct();product.display();} catch (Exception e) {//異常處理e.printStackTrace();}}public static String readConfig(){//可以將工廠類名全路徑寫到設定檔裡,這樣用戶端無需//更改代碼,只需配置即可完成不用產品的的展示需求return "com.icemelt.designpattern.factorymethod.AirplaneFactory";}}

4.總結

  Factory 方法首先需要屏蔽產品類的具體實現,產品類如何變化,調用者都不需要關心,只需關心產品類的介面,通常介面是相對穩定,只要此介面不發生變化,那麼系統上層就不會發生變化(這也是面向介面編程的好處)。其次需要屏蔽Factory 方法的具體實現,道理同前。然後我們就能享受Factory 方法給代碼帶來的靈活性的好處:此時所有用戶端代碼只與兩個抽象類別(或介面)有關,增加產品只需完成該產品和對應Factory 方法的編碼工作即可完成需求增加(不需要修改用戶端代碼和後台已存在的代碼,客戶需要新增功能只需修改配置即可)

  通常實際應用中商務邏輯會比較複雜,產品類可能並沒有統一的介面(也有可能是曆史遺留原因),這時候需要想辦法加上一層統一的間接關係後才能繼續應用本模式。

返回頂部

 

java設計模式:Factory 方法模式(Factory Method)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.