原廠模式(Factory Pattern)和java反射機制最佳化思考

來源:互聯網
上載者:User

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">GOF的原廠模式是最基礎的一種建立型設計模式,其適用於建立同一介面的不同實現子類,</span>

其優點是:將使使用者更加方便使用,而不關心具體的建立邏輯

缺點是:每增加一個介面的子類,必須修改工程類的相關邏輯(後面我們用java的反射機制進行最佳化)


從上面UML圖看到,我們設定了一個Shape介面,並且實現了三個子類,我們通過ShapeFactory來根據不同的名稱返回不同的子類執行個體,通過FactoryPatternDemo進行的測試。邏輯很簡單,不再詳述。

public class ShapeFactory {   //使用 getShape 方法擷取形狀類型的對象   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("SQUARE")){         return new Square();      }      return null;   }}

基於以上面ShapeFactory的實現,我們思考到,如果我們再增加一個子類實現,那麼ShapeFactory必須進行相應的修改源碼,並重新進行編譯,這不是我們想要的結果。如果能不改變ShapeFactory的內容,而是將需要調用的子類寫在設定檔中多好,這樣ShapeFactory從設定檔中接收到需要返回的子類名稱,返回相應的子類執行個體。說到這裡,大家也許有點耳熟,這和spring中的依賴注入不很相似嗎,能想到這裡說明你很厲害了。不錯,這個就需要java的反射機制來實現(spring依賴注入的內部原理就是依賴java的反射機制),java.lang.Class類閃亮登場。

利於java.lang.Class類,我們可以通過Class.forName方法用類的詳細名稱(含包名)得到一個這個類的Class,之後就可以通過這個Class類進行一系列的操作了,執行個體化一個這個類的類對象newInstance()(調用不含參數的建構函式執行個體化),查看他的構造方法Constructor,方法Method,成員變數Field,執行Method(可能需要java.lang.reflect中的類)。

回到上面,我們如何最佳化上面的原廠模式,思路是這樣的,首先將將要調用的子類名放到設定檔中(好處是在改變調用的時候並不需要改變其他的代碼),然後在Factory中用Class解析這個類,並執行個體化返回。最後在Demo中進行調用。思路很簡單

properties檔案如下:

shape.className=factoryPattern.Rectangle
Factory代碼如下
public class ShapeFactory {public Shape getShape(String shapeClassName){Shape targetShape=null;Class oneClass=null;try {oneClass=Class.forName(shapeClassName);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("不能正確擷取類");}try {targetShape=(Shape) oneClass.newInstance();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("不能正確建立執行個體");}return targetShape;}
調用:

public static void main(String[] args) {String targetClassName=ClassNameConfig.getProperty("shape.className");System.out.println("targetClassName:"+targetClassName);ShapeFactory shapeFactory=new ShapeFactory();Shape targetShape=shapeFactory.getShape(targetClassName);targetShape.draw();}
這樣,當修改調用子類時,只需要修改設定檔即可。當然,對於簡單的原廠模式應用沒必要如此繁瑣
理解了這個,也就不難理解Spring的Ioc技術,Spring的設定檔換成了xml檔案,而且設計比較複雜,調用程式變成了所謂的spring容器,當然這隻是spring設計的基石,上層建築還是很複雜的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.