工厂方法的应用3

来源:互联网 发布:linux解压缩 编辑:程序博客网 时间:2024/06/01 09:46

今天看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   对象的。

如果是一个写得比较好的工厂方法,要符合“开-闭原则”,在新增实现类后,只需更改配置,而原来写好的源代码根本不需要去修改。

原创粉丝点击