工廠方法的應用3

今天看java編程思想中的接口時,理解不了工廠方法設計模式,希望有人能來幫忙解答下。
      書上的代碼說的是在一個相同的棋盤上下國際象棋和西洋跳棋,
      interface   Game{...}
      interfacd   GameFactory{...}
         
      class   Checkers   implements   Game{...}
      class   CheckersFactory   implements   GameFactory
    {
      public   Game   getGmae()     {return   new   Checkers();}
      }
      class   Chess   implements   Game{...}  
      class   ChessFactory   implements   GameFactory
    {
    public   Game   getGmae()     {return   new   Chess();}
    }
    public   class   Games
    {                        
              public   static   void   playGame(GameFactory   factory)
              {       Game   s=factory.getGame();
                }  
            public   static   void   main(...)
          {playGame(new   CheckerFactory);     playGame(new   ChessFatory);}  
    }
這是書上的代碼,我省略了一些跟我問題無關的代碼。
我的問題是爲什麼要這麼麻煩,給Checkers和Chess都弄個工廠,然後從工廠裏返回類型,可以直接把public   static   void   playGame(GameFactory   factory)       改成
        public   static   void   playGame(Game   factory)不就可以了嗎?然後playGame(new   CheckerFactory);     playGame(new   ChessFatory);改成playGame(Checkers);
playGame(Chess);   利用向上轉型原理。這樣不是可以把上面的那些Factory代碼全刪掉麼?另外Factory模式到底有什麼用處。  
可能是我沒有理解工廠方法設計模式。希望有人能來回答下。 

---------------------

 看你的例子更像是Abstract   factory   pattern,而不像是工廠方法設計模式factory   method   pattern。
在你的例子裏,如你所說的改動,看似沒什麼問題,在這裏game的構造過程很簡單new   SomeGame()。

首先工廠模式在於其封裝了其產品(game)的構造過程。
考慮到複雜的構造過程,例如SomeGame構造需要配置多個參數,那麼getGame就要通過相應的途徑去取得這些參數,例如讀取配置文件。
在這種情況下,對於用戶main來說,就可以簡單的獲得Game而不需要清楚如何取構造它。

另一點,工廠模式在於其提供一個構造產品的方法。例如你做的是一個遊戲服務器,playGame會等待用戶連接,然後爲每一個用戶連接創建一個Game,那麼你可以簡單的gameFactory.getGame,而如果你把Game作爲參數傳遞就完全不同了。

---------------------------

這段程序據我的理解,並沒有深刻地表達工廠方法意義,可能讓你產生了誤解。按照你的方法來改也未嘗不可,但是它主要講的是工廠方法啊,所以就必須採用工廠來實現。

下面這些是原來幫別人回答類似問題時用到的代碼,你可以參考一下:
原文地址:http://community.csdn.net/Expert/TopicView3.asp?id=5658401

工廠方法指的是根據不同的情況產生不同的對象,比如:

public   static   Dao   getDao(String   dbmsName)   throws   UnsupportDatabaseException   {
  if(   dbmsName.equalsIgnoreCase( "SQL   Server ")   )   {
    return   new   SqlServerDao();
  }   else   if(   dbmsName.equalsIgnoreCase( "Oracle ")   )   {
    return   new   OracleDao();
  }   else   if(   dbmsName.equalsIgnoreCase( "MySQL ")   )   {
    return   new   MySQLDao();
  }   else   {
    throw   new   UnsupportDatabaseException(dbmsName);
  }
}
其中   Dao   是   SqlServerDao、OracleDao、MySQLDao   的接口。

上面這段代碼就是一個典型的工廠方法,通過傳入的數據庫名稱來確定,並獲得不同的數據庫處理實現。若使用的數據庫並沒有實現,則進行異常處理。

不過一般不會這樣寫,這裏僅作個示例。我基本上是把當前   Dao   的實現類寫在   XML   中,在進行動態加載類操作,使用工廠返回   Dao   對象的。

如果是一個寫得比較好的工廠方法,要符合“開-閉原則”,在新增實現類後,只需更改配置,而原來寫好的源代碼根本不需要去修改。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章