Kira-2006
          -僅僅是一陣風也罷了,偏偏是這樣永恒, 僅僅是一場夢也罷了,偏偏是如此的真實,
          posts - 4,comments - 7,trackbacks - 0
          解耦合的設計目標:
              1. 應用層解耦合--應用邏輯與數據邏輯相分離。
              2. 資源層解耦合--邏輯結構與物理結構相分離。

          DAO模式:即Data Accessor模式和Active Domain Object模式。
              Data Accessor模式:實現數據訪問和業務邏輯的分離。
              Active Domain Object:實現了業務數據的對象化封裝。
              Domain Object:簡單來講就是對領域內涉及的各個數據對象,反映到代碼,就是一個擁有相關屬性的getter,setter方法的java Bean。

              DAO模式通過對業務邏輯蹭提供數據抽象層接口,實現了以下目標:
                  
          1. 數據存儲邏輯的分離:通過對數據訪問邏輯進行抽象,為上層結構提供抽象化的數據訪問接口。
                  2. 數據訪問底層實現的分離:數據訪問劃分為抽象層和實現層,從而分離了數據使用和數據訪問的底層實現細節。
                  3. 資源管理和調用的分離。
                  4.數據抽象:DAO模式通過對底層數據的封裝,為業務層提供了一個面向對象的接口,使得業務邏輯開發人員可以面向業務中的實體進行編程。
                  DAO = Data+Accessor+Domain Object

          DAO模式的進一步改良
              Factory模式的引入:
                  由于需要針對不同的數據庫訪問機制分別提供各個版本的Data Accessor實現,自然我們會想到通過java interface定義一個調用接口,然后針對這個調用接口實現不同數據庫的Data Accessor。通過接口作為調用界面和實現規范,可以避免對具體實現的依賴。
                  
          public interface CustomerDAO{
              
          public Customer getCustomer(String custID);
              
          public void save(Customer customer);
          }

          作為最常見的創建模式,Factory模式在這里起到連接接口和實現的橋梁作用,通過Factory模式,我們可以根據具體的需要加載相應的實現,并將此實現作為所對應接口的一個實例提供給業務層使用。
          CustomerDAO custDAO = (CustomerDAO)DAOFactory.getDAO(CustomerDAO.class);
          Customer customer 
          = custDAO.getCustomer(custoemrID);
          業務邏輯層通過接口調用底層實現,具體的DAO實現類不會出現在我們的業務代碼中。而具體實現類在配置文件中加以配置,之后DAOFactory.getDAO方法通過讀取配置文件獲得當前我們期望使用的實現類的類名,再通過java Class動態加載機制加載返回。
          從而我們的代碼不依賴于某個特定的實現類,只需要在部署的時候在配置文件中指定當前采用的實現類即可。
          public class DAOFactory{
              
          private static HashMap daoMap = null;

              
          //根據指定的Class來獲取DAO實例
              public static Object getDAO(Class daoInterface){
                  initial();
                  Object dao
          =daoMap.get(daoInterface);
                  
          if(null==dao){
                      
          throw new DAOException("No implementation found of DAO interface => "+daoInterface.getName());
                  }

                  
          return dao;
              }


              
          //初始化DAOFactory,加載DAO interface和 
              
          //implementation到daoMap中
              public static sychronized void initial(){
                  
          if(null==daoMap){
                      
          //根據配置文件中加載DAO實現配置
                      daoMap = DAOConfig.load();
                  }

              }

          }


          //DAOConfig類實現了配置文件的讀取功能,并根據配文
          //件中的內容加載指定的接口和實現
          public class DAOConfig{
              
          private static Logger logger = LogManager.getLogger(DAOConfig.class);
              
          private static final String DAO_CONFIG_FILE="dao.xml";
              
          private static final String DAO_CONFIG_SECTION="DAO";

              
          public static synchronized HashMap load(){
                  HashMap map 
          = new HashMap();
                  JFigLocator jfigLocator 
          = JFig.getInstance(jfigLocator);
                  Properties prop
          =daoConfig.getSectionAsProperties(DAO_CONFIG_SECTION);
                  Enumeration enumSection
          =prop.Keys();
                  
          while(enumSection.hasMoreElements()){
                      String daoIface
          =(String)enumSectioni.nextElement();
                      String daoImpl
          =(String)prop.getProperty(daoIface);
                      
          try{
                          Class iface
          =ClassToolKit.loadClass(daoIface);
                          Class impl
          =ClassToolKit.loadClass(daoImpl);
                          
          //將接口作為索引,實現作為值。
                          map.put(iface,impl);
                      }
          catch(ClassNotFoundException e){
                          logger.debug(
          "No Class Found => "+e);
                       }

                  }

                  
          return map;
              }

          }

          ClassToolKit.loadClass方法實現了類文件的動態加載:
          public class ClassToolKit{
              
          public static Class loadClass(String className)throws ClassNotFoundException{
                  Class cls
          =null;
                  
          try{
                      
          //首先嘗試用當前ClassLoader加載
                      cls=Thread.currentThread().getContextClassLoader().loadClass(className);
                  }
          catch(Exception e){
                      e.printStackTrace();
                  }

                  
          if(cls==null){
                      
          //如果通過當前ClassLoader加載失敗,使
                        
          //用系統ClassLoader加載
                      cls=Class.forName(className);
                  }

                  
          return cls;
              }

          }
          這樣,通過接口與實現的分離,并結合DAOFactory動態加載實現類,我們就實現了底層訪問實現的參數化配置功能。從而為增強產品的部署能力提供了強有力的支持。
              經過Factory模式的改造,業務層代碼進行相應的修改:
          public BigDecimal calcAmount(String customerID,BigDecimal amount){
              
          //根據客戶ID獲得客戶記錄
              CustomerDAO customerDAO=(CustomerDAO)DAOFactory.getDAO(CustomerDAO.class);
              Customercustomer
          =customerDAO.getCustomer(customerID);

              
          //根據客戶等級獲得打折比率
              PromotionDAO promoDAO=(PromotionDAO)DAOFactory.getDAO(PromotionDAO.class);
              Promotion promotion
          =promoDAO.getPromotion(customer.getLevel());

              
          //累計客戶總消費額,并更新數據庫
              customer.setSumAmount(customer.getSumAmount().add(amount));
              customerDAO.save(customer);

              
          //返回打折后金額
              return amount.multiply(promotion.getRatio());

          }
          這段代碼中混雜了數據訪問層的內容,如DAOFactory.getDAO方法的調用。

          Proxy模式的引入
              為了保持業務邏輯代碼的簡潔,將Factory模式帶來的Bad Smell排除在系統外,引入Proxy模式。
              Proxy模式的作用:通過提供一個中間層(Proxy),將上層調用接口與下層實現相銜接。
              經過Proxy模式改進后的業務層代碼:
          public BigDecimal calcAmount(String customerID,BigDecimal amount){
              Customer customer
          =CustomerProxy.getCustomer(customerID);

              Promotion promotion
          =PromotionProxy.getPromotion(customer.getLevel());

              customer.setSumAmount(customer.getSumAmount.add(amount));

              CustomerProxy.save(customer);

              
          return amount.multiply(promotion.getRatio());

          }

          public class CustomerProxy{
              
          //get Customer Object by CustomerID
              public static Customer getCustomer(String customerID){
                  customerDAO custDAO
          =(CustomerDAO)DAOFactory.getDAO(CustomerDAO.class);
                  
          return custDAO.getCustomer(customerID);
              }


              
          //Save Customer Object to DataBase
              public static void save(Customer customer){
                  CustomerDAO custDAO
          =(CUstomerDAO)DAOFactory.getDAO(CustomerDAO.class);
                  custDAO.save(customer);
              }

          }

          posted on 2008-05-02 19:33 Kira-2006 閱讀(403) 評論(0)  編輯  收藏 所屬分類: hibernate
          主站蜘蛛池模板: 都江堰市| 嘉禾县| 安丘市| 宣威市| 耒阳市| 宿迁市| 屏山县| 灵台县| 甘肃省| 湖北省| 霍邱县| 九龙城区| 锡林浩特市| 灵武市| 淳化县| 定安县| 靖江市| 秀山| 乌什县| 扬中市| 论坛| 盱眙县| 科技| 三门县| 桐梓县| 井冈山市| 板桥市| 逊克县| 林芝县| 呼和浩特市| 青浦区| 大余县| 宁陵县| 增城市| 师宗县| 团风县| 邳州市| 襄汾县| 承德县| 山阳县| 九寨沟县|