MVC與三層架構的研討

一、MVC架構
Struts是一個不錯的MVC架構,我一直以來都用它,通過簡單的配置即可將view,controler,和Model結合起來。View主要以JSP來實現,因爲它是面向標籤的,所以對於網頁設計人員提供了很好的接口。FormBean是介於JSP和Action之間的中間數據載體,它肩負着數據從JSP到ACTION的傳遞過程。Action是流程的中轉站,不同的業務在不同的Action中以不同的Model調用來實現。Model就是實現具體業務的操作過程,不過這種過程是一種在較高水平上的實現。
總之,MVC架構實現了三層結構中的兩層,即表現層和業務層,另外還有一層被稱之爲持久化層。
二、三層架構
正如以上所說的,三層架構即“表現層”,“業務層”,“持久化層”。表現層實現的代表作品是Struts框架,業務層實現的代表作品是Spring,持久層實現的代表作品是Hibernate。不過在我的開發中Spring被省掉了,因爲我認爲業務過於簡單,還不至於用Spring來實現。下面我將具體的來說說我的三層實現。
1、三種Bean
在我的實現中,總共有三種Bean,它們都是爲保存對象狀態而存在的。持久層中,這種Bean就是POJO對象。它是面向數據庫的,或者說多少得照顧到數據庫的實現,因爲我習慣於用PowerDesigner來設計數據庫,做出來的結構也是比較中規中矩的,而如果直接用Hibernate來實數據庫的話,就不那麼幹淨了。所以POJO對象的設計就不能完全面向對象。業務層中的Bean我把它稱之爲Entity,這是一個完全面向程序邏輯的Bean。它可能是好幾個POJO的集合。對於業務邏輯來,這種被稱之爲Entity的Bean做到了“拿來就用”,很便於業務的進行。在顯示層中的Bean就是FormBean了,主要用於傳入數據所用。
POJO僅生存於持久化層,到了業務層就將數據交給Entity了。而Entity不僅生存於業務層,它還被傳到了JSP中,用於顯示。
2、Pojo與Dao
我認爲這是數據與操作的關係,Dao只在呼操作,而Pojo僅用於保存數據。下面是我Dao接口的實個現。
public interface Dao {

  //********** operattion method *********
  void resetPO(Pojo pojo);//重新設置POJO實體
  String save();//保存或更新POJO實體
  Pojo load();//通過ID值獲取確切的POJO
  List find(short by);//通過某一屬性值來獲取POJO
  void close();//顯示調用,以關閉session,至此該DAO將不再可用。
}
所有的涉及具體操作的Dao類均實現它。三個方法把Hibernate的查詢語句封裝起來。在業務層中只關心save(),load(),或find()。下面是一個具體UserDao的實現。
public class UserDao implements Dao {

  public final short _ALL = 0;
  public final short _BY_NAME = 1;
  public final short _BY_ACCOUNT = 2;
  public final short _BY_PASSWORD = 3;
  public final short _BY_ACCOUNT_PASSWORD = 4;

  private UserPo userPo;
  private static Log log = LogFactory.getLog(DocumentDAO.class);
  private Session session;

  //************ initial method *************** 
  public UserDao() {
    userPo = new UserPo();
    session = HibernateUtil.currentSession();
  }

  public UserDao(UserPo user){
    this.userPo = user;
    session = HibernateUtil.currentSession();
  }

  //************ method begin ***************

   /**
    * resetPO()
    *重新加載POJO對象
    * @param pojo Pojo
    */
   public void resetPO(Pojo pojo) {
     this.userPo = (UserPo)pojo;
   }


   /**
    * save()
    * 保存UserPo對象於數據庫,如果是一個已持久的對象,則進行update操作
    * @return String
    */
   public String save() {
    String oid = null;
    try{
      //Session session = HibernateUtil.currentSession() 已經被提至構造函數中初始化了
      Transaction tx = session.beginTransaction();
      if (userPo.getId() == null) {
        oid = (String)session.save(userPo);//如果這是一個新的pojo則進行insert操作。
        session.flush();
        tx.commit();
      }else{
        session.update(userPo,userPo.getId());//如果該pojo已被初始化過則進行update操作
        session.flush();
        tx.commit();
      }
    }catch(HibernateException ex){
      System.out.println("//********* error **********///n UserDao.save()出現異常!");
      log.error("UserDao.save()出現異常!",ex);
    }
    return oid;
  }

  /**
   * get()
   * 通過id值,從數據庫中獲得指定的UserPo對象
   * @return Pojo
   */
  public Pojo load() {
    UserPo tmp = new UserPo();
    try{
      //Session session = HibernateUtil.currentSession() 已經被提至構造函數中初始化了
      tmp = (UserPo) session.get(UserPo.class, userPo.getId()); //用確切存在的ID值獲得對象
    }catch(HibernateException hbe){
      hbe.printStackTrace();
    }
    if (tmp != null) {
      userPo = tmp;
      return userPo;
    }
    else
      return null;
  }

  /**
   * find()
   * 從數據庫中查找一個User對象
   * @return Pojo
   */
  public List find(short by) {
    //Session session = HibernateUtil.currentSession() 已經被提至構造函數中初始化了
    Query query = null;
    String where=null;
    switch(by){
      case 0 :
        where = "";
        break;
      case 1 :
        where = " where us.name='"+userPo.getName()+"'";
        break;
      case 2 :
        where = " where us.account='"+userPo.getAccount()+"'";
        break;
      case 3 :
        where = " where us.password='"+userPo.getPassword()+"'";
        break;
      case 4 :
        where = " where us.account='"+userPo.getAccount()+"' and us.password='"+userPo.getPassword()+"'";
    }
    query = session.createQuery("from UserPo us"+where);
    return query.list();
  }

  public void close(){
    HibernateUtil.closeSession();
  }

}
其中HibernateUtil是一個Hibernate方法類,它提供線程安全的Session。和關閉這個Session的方法(雖然關閉Session過於簡單)。每個Dao是由DaoFactory來產生的。DaoFactory也有一個公共的接口。如下:
public interface DaoFactory {
  /**
   * DAO對象工廠,獲取各個數據實體的DAO對象,返回一個統一的接口 Dao
   * @return Dao
   */
  Dao getDocumentDAO();
  Dao getDocHeadDAO();
  Dao getDocAccessoryDAO();
  Dao getUserDao(User u);

}
下面是一個基於Hibernate的Dao的實現。
public class HbDaoFactory implements DaoFactory {

  public HbDaoFactory() {
  }

  /**
   * getDocumentDao
   *
   * @return Dao
   */
  public Dao getDocumentDAO() {
    /**@todo Implement this com.cecs.dao.DaoFactory method*/
    return new com.cecs.dao.DocumentDAO();
  }

  /**
   * getDocHeadDao
   *
   * @return Dao
   */
  public Dao getDocHeadDAO() {
    /**@todo Implement this com.cecs.dao.DaoFactory method*/
    throw new java.lang.UnsupportedOperationException("Method getDocHeadDAO() not yet implemented.");
  }

  /**
   * getDocAccessoryDao
   *
   * @return Dao
   */
  public Dao getDocAccessoryDAO() {
    /**@todo Implement this com.cecs.dao.DaoFactory method*/
    throw new java.lang.UnsupportedOperationException("Method getDocAccessoryDAO() not yet implemented.");
  }

  /**
   * getUserDao
   *獲取UserDao對象
   * @return Dao
   */
  public Dao getUserDao(User u) {
    return new UserDao(u);
  }

}
這樣一但不用Hibernate來實現持久層,也可以很方便改爲其它的Dao而不用修改業務層。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章