春風博客

          春天里,百花香...

          導航

          <2007年7月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          統(tǒng)計

          公告

          MAIL: junglesong@gmail.com
          MSN: junglesong_5@hotmail.com

          Locations of visitors to this page

          常用鏈接

          留言簿(11)

          隨筆分類(224)

          隨筆檔案(126)

          個人軟件下載

          我的其它博客

          我的鄰居們

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          更適合Swing程序的MVC方案

          MVC有MVC1和MVC2的區(qū)別,它們的區(qū)別在于MVC1中用Model來通知View進行改變,而MVC2中使用Controller來通知View.在桌面程序中一般采用MVC1,而Web程序多采用MVC2,這是因為web程序中,Model無法知道View的原因.

          在Swing程序中,我們通常采用讓View實現(xiàn)Observer接口,讓Model繼承Observable類來實現(xiàn)MVC1,而讓Controller把它們創(chuàng)建及連接起來,具體代碼如下:
          public class XXXControl {
              
          private XXXModel model = null;
              
          private XXXView view = null;

              
          public XXXControl() {
                  model 
          = new XXXModel();
                  view 
          = new XXXView();
                  model.addObserver(view);
               }


          .
          .
          .
          }

          而Model進過處理后得到了結果,它采用Observable的notifyObservers()方法來通知View進行改變,而View的public void update(Observable o, Object arg)方法將相應這一改變,它通過解析Observable類型的對象o得到處理結果,再進行具體的表現(xiàn)層改變.

          粗看起來MVC各司其職,很完美,但還有不和諧的隱患:
          1.View必須知道解析Model,造成了二者的耦合.
          2.View非得實現(xiàn)Observer接口,Model非得繼承Observable類,這個處理不是必要的.
          3.這種模式只適合即時處理,即相應很快的處理,對于耗時過程并不適合.
          4.由于Model中數(shù)據(jù)眾多,很多時候我們還需要建立一個常量類來區(qū)分各種情況和決定View更新的地方,進一步加重了類之間的耦合程度.

          綜上,我覺得對于稍大的Swing程序,MVC2+線程回調方式更適合,它的主要處理是:
          1.依然由Controller創(chuàng)建View和Model,它們擔負的職責也和原來一樣,但是View不實現(xiàn)Observer接口,Model不繼承Observable類,它們該怎么樣還是怎么樣,而讓Controller來充當它們之間的中介者.
          2.如果是即時處理,可以在Controller中添加事件處理時就直接寫來.如果是耗時處理,可以將View和Model的引用(或Model中元素的引用)傳遞給一個線程處理類,具體的運算和界面反應在線程處理類中完成.
          下面是一個調用例子:
          new FetchTablesThread(model.getDataSource(), view,schema).start();

          下面是線程類的例子:
          public class FetchTablesThread extends BaseThread {
              
          private static Logger logger = Logger.getLogger(FetchTablesThread.class);

              
          private String schema;

              
          public FetchTablesThread(DataSource dataSource, SqlWindowView view,
                      String schema) 
          {
                  
          super(dataSource, view);
                  
          this.schema = schema;
              }


              
          public void run() {
                  OutputPanel outputPanel 
          = view.getTabbedPanel().getInputOutputPanel().getOutputPanel();

                  
          try {
                      
          if (dataSource.getDbtype().equals("mysql")) {
                          
          // Specail Process for MySql
                          new FetchTables4MySqlThread(dataSource, view, schema).start();
                      }
           else {
                          
          // Ordinary Process for other DB
                          List tables = dataSource.getTablesInSchema(schema);

                          
          if (tables.size() > 0{
                              
          // Find tables under schema
                              view.getCatalogTablesPanel().getMultiTable().refreshTable(
                                      tables);

                              outputPanel.showText(
          true);
                              String text 
          = "Find " + tables.size()
                                      
          + " tables under schema:" + schema
                                      
          + " successfully!";
                              outputPanel.appendOutputText(text);
                              logger.info(text);
                          }
           else {
                              
          // Can't find tables under schema
                              outputPanel.showText(true);
                              String text 
          = "Can't find any table under schema:" + schema;
                              outputPanel.appendOutputText(text);
                              logger.info(text);
                          }

                      }

                  }
           catch (Exception ex) {
                      outputPanel.showText(
          true);
                      String text 
          = "Can't find any table under schema:" + schema+" and errorMsg="+ex.getMessage();
                      outputPanel.appendOutputText(text);
                      logger.info(text);            
                  }

              }

          }

          這樣做有兩個好處一是使程序結構松散化,適于修改,二是相對傳統(tǒng)的MVC2,Controller中事件處理的代碼也容易變得簡單而清晰,可維護性更佳.

          綜上,我認為MVC2+線程回調方式是一種值得推薦的Swing桌面程序寫法.

          關于線程回調方式,您可以參考:
          http://www.aygfsteel.com/sitinspring/archive/2007/06/28/126809.html

          關于MVC,您可以參考:
          http://junglesong.yculblog.com/post.2665424.html

          posted on 2007-07-19 14:47 sitinspring 閱讀(2315) 評論(5)  編輯  收藏 所屬分類: Object Orient Programming

          評論

          # re: 更適合Swing程序的MVC方案 2007-07-19 18:08 someone

          同意,線程就是用來處理需要長時間運行的任務,回調的設計也是線程通知中的最佳設計,只是在非Swing線程中刷新視圖是否存在問題,不知道你對這個方法SwingUtilities.invokeAndWait怎么看的?  回復  更多評論   

          # re: 更適合Swing程序的MVC方案 2007-07-19 19:48 sitinspring

          不好意思,SwingUtilities.invokeAndWait沒有嘗試過,不敢多言.

          關于刷新視圖,目前在使用中似乎有些問題,具體來說就是有滯后和突然進行刷新的情況發(fā)生,目前應用遠不如Eclispe多窗口那樣平滑自然,模擬新聞聯(lián)播的話說,還有待提高.

          我再做做看看,有了新結論我們再來討論一下.  回復  更多評論   

          # re: 更適合Swing程序的MVC方案 2007-07-19 22:22 go

          goodl  回復  更多評論   

          # re: 更適合Swing程序的MVC方案 2007-07-21 10:49 Sun

          不錯  回復  更多評論   

          # re: 更適合Swing程序的MVC方案 2009-07-26 18:09 wangmogang

          怎么個中介法呢,可以說下Controller協(xié)調其他兩者之間的流程嗎  回復  更多評論   

          sitinspring(http://www.aygfsteel.com)原創(chuàng),轉載請注明出處.
          主站蜘蛛池模板: 福清市| 永和县| 陕西省| 崇义县| 清苑县| 利川市| 治多县| 商水县| 陇川县| 同仁县| 墨玉县| 水富县| 理塘县| 鹤山市| 津市市| 灯塔市| 根河市| 富蕴县| 张家界市| 武宣县| 肃宁县| 堆龙德庆县| 苍梧县| 沈阳市| 松潘县| 宝清县| 古蔺县| 北票市| 曲阜市| 萨嘎县| 永新县| 孟津县| 高台县| 太谷县| 长治县| 新绛县| 台南市| 潼关县| 肇庆市| 应城市| 周口市|