更适合Swing程序的MVC方案

更适合Swing程序的MVC方案

MVC有MVC1和MVC2的区别,它们的区别在于MVC1中用Model来通知View进行改变,而MVC2中使用Controller来通知View.在桌面程序中一般采用MVC1,而Web程序多采用MVC2,这是因为web程序中,Model无法知道View的原因.

在Swing程序中,我们通常采用让View实现Observer接口,让Model继承Observable类来实现MVC1,而让Controller把它们创建及连接起来,具体代码如下:
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得到处理结果,再进行具体的表现层改变.

粗看起来MVC各司其职,很完美,但还有不和谐的隐患:
1.View必须知道解析Model,造成了二者的耦合.
2.View非得实现Observer接口,Model非得继承Observable类,这个处理不是必要的.
3.这种模式只适合即时处理,即相应很快的处理,对于耗时过程并不适合.
4.由于Model中数据众多,很多时候我们还需要建立一个常量类来区分各种情况和决定View更新的地方,进一步加重了类之间的耦合程度.

综上,我觉得对于稍大的Swing程序,MVC2+线程回调方式更适合,它的主要处理是:
1.依然由Controller创建View和Model,它们担负的职责也和原来一样,但是View不实现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);            
        }

    }

}

这样做有两个好处一是使程序结构松散化,适于修改,二是相对传统的MVC2,Controller中事件处理的代码也容易变得简单而清晰,可维护性更佳.

综上,我认为MVC2+线程回调方式是一种值得推荐的Swing桌面程序写法.

关于线程回调方式,您可以参考:
http://www.blogjava.net/sitinspring/archive/2007/06/28/126809.html

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

你可能感兴趣的:(更适合Swing程序的MVC方案)