青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Javen-Studio 咖啡小屋

http://javenstudio.org - C++ Java 分布式 搜索引擎
Naven's Research Laboratory - Thinking of Life, Imagination of Future

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  24 隨筆 :: 57 文章 :: 170 評論 :: 4 Trackbacks

學習筆記之ORM設計中用到的模式
by Naven at 2005-09-19


DAO 模式

DAO 模式即 Data Access Object 模式,實際是兩個模式的組合,即 Data Accessor 模式和 Active Domain Object 模式,其中 Data Accessor 模式實現了數據訪問和業務邏輯的分離,而 Active Domain Object 模式實現了業務數據的對象化封裝,一般都是將這兩個模式組合使用。

DAO 模式通過對業務層提供數據抽象層接口,實現了以下目標:
1、數據存儲邏輯的分離:通過對數據訪問邏輯進行抽象,為上層結構提供抽象化的數據訪問接口。
2、數據訪問底層實現的分離:通過將數據訪問劃分為抽象層和實現層,從而分離了數據使用和數據訪問的底層實現細節。
3、資源和調度的分離:將數據訪問邏輯從業務邏輯中脫離開來,使得在數據訪問層實現統一的資源調度,通過數據庫連接池以及各種緩存機制(Statement Cache,Data Cache等)的配合使用,大幅度提升系統性能。
4、數據抽象:通過對底層數據的封裝,為業務層提供一個面向對象的接口,使得業務邏輯開發人員可以面向業務中的實體進行編碼。即對業務層屏蔽了數據庫訪問的底層實現,業務層僅包含于本領域相關的邏輯對象和算法。

總結來說,DAO 模式可以這么理解:
Data Accessor Object (DAO)= Data + Accessor + Domain Object

舉例來說,如下(引自《深入淺出Hibernate》):
public Double calcAmount(String customerid, double amount)
{
    // 根據客戶ID獲得客戶記錄
    Customer customer = CustomerDAO.getCustomer(custmerid);
    // 根據客戶等級獲得打折規則
    Promotion promotion = PromotionDAO.getPromotion(customer.getLevel());
    // 累積客戶總消費額,并保存累計結果
    customer.setSumAmount(customer.getSumAmount().add(amount);
    CustomerManager.save(customer);
    // 返回打折后的金額
    return amount.multiply(protomtion.getRatio());
}
從這段代碼看出,通過 DAO 模式對各個數據對象進行封裝,對業務層屏蔽了數據庫訪問的底層實現,業務層僅包含于本領域相關的邏輯對象和算法。


Abstract Factory 模式

Abstract Factory 模式即 抽象工廠創建型模式,它提供一個創建一系列相關或相互依賴對象的接口,而無需制定它們具體的類。換句話說,就是向調用者提供一個接口,使得在不必指定產品的具體類型情況下,創建多個產品族中的產品對象,這就是抽象工廠模式的用意。
作為最常用的創建模式,抽象工廠模式在這里起到連接接口和實現的橋梁作用。通過該模式,可以根據具體需要加載相應的實現,并將此實現作為所對應接口的一個實例提供給業務層使用。

如抽象如下接口(引自《深入淺出Hibernate》):
public interface CustomerDAO {
    public Customer getCustomer(String custid);
    public void save(Customer customer);
}
業務層這樣使用:
CustomerDAO custDAO = (CustomerDAO) DAOFactory.getDAO(CustomerDAO.class);
Customer customer = custDAO.getCustomer(customerID);

也就是說,業務層通過接口調用底層實現,具體的DAO實現類不會出現在業務代碼中。
不過卻帶來了另一個缺憾,即混雜了一些數據訪問層的內容,如 DAOFactory.getDAO() 方法的調用,所以還需引入 Proxy 模式加以改良。


Proxy 模式

Proxy 模式即 代理結構型模式,它為其他對象提供一種代理以控制對這個對象的訪問。比如說 Windows 的快捷方式和 Unix 的文件/目錄的Link文件就是一種代理的例子。
引入 Proxy 模式的作用是通過提供一個中間層(Proxy),將上層調用接口與下層的實現相銜接,以做到保持業務代碼的簡潔,消除 Factory 模式帶來的缺憾。

改進后的業務代碼如下(引自《深入淺出Hibernate》):
public Double calcAmount(String customerid, double amount)
{
    // 根據客戶ID獲得客戶記錄
    Customer customer = CustomerProxy.getCustomer(custmerid);
    // 根據客戶等級獲得打折規則
    Promotion promotion = PromotionProxy.getPromotion(customer.getLevel());
    // 累積客戶總消費額,并保存累計結果
    customer.setSumAmount(customer.getSumAmount().add(amount);
    CustomerManager.save(customer);
    // 返回打折后的金額
    return amount.multiply(protomtion.getRatio());
}
而在 CustomerProxy類和 PromotionProxy類中實現調用 CustomerDAO類和 PromotionDAO類的方法。


Decorator 模式

Decorator 模式即 裝飾結構型模式,又名包裝(Wrapper)模式。目的是利用一個對象,透明地為另一個對象添加新的功能,是繼承關系的一個替代方案。就增加功能來說,Decorator 模式相比生成子類更為靈活。簡單來說,就是通過一個 Decorator 對原有對象進行封裝,同時實現與原有對象相同的接口,從而得到一個基于原有對象的,對即有接口的增強性的實現。

在以下情況下應當使用 Decorator 模式:
1、需要擴展一個類的功能,或給一個類增加附加責任。
2、需要動態地給一個對象增加功能,這些功能可以再動態地撤銷。
3、需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關系變得不現實。

Decorator 模式有如下缺點:
使用裝飾模式會產生比使用繼承關系更多的對象,更多的對象會使得查錯變得困難,特別是這些對象看上去都很相像。

舉例來說(引自《深入淺出Hibernate》):
如果要實現連接池,并且在 Connection 對象使用后調用 close() 時不關閉連接,而是釋放到連接池中,則可以考慮實現一個 ConnectionDecorator 類來做,它實現 Connection 類所有方法,并且所有方法都轉調 Connection 類的相同方法。

public class ConnectionDecorator
    implements Connection {

    private Connection dbconn;
   
    public ConnectionDecorator(Connection conn) {
        this.dbconn = conn; // 實際從數據庫獲得的 Connection 引用
    }

    /**
     * 次方法將被子類覆蓋,以實現數據庫連接池的連接返回操作
     */
    public void close() throws SQLException {
        this.dbconn.close();
    }

    // 其他方法類似,均調用 dbconn.xxx方法

}

然后就可以實現一個類繼承 ConnectionDecorator,而覆蓋其 close() 方法即可,如下:

public class PooledConnection
    extends ConnectionDecorator
    implements Connection {
   
    private ConnectionPool connPool;
   
    public PooledConnection(ConnectionPool pool, Connection conn) {
        super(conn);
        connPool = pool;
    }
   
    /**
     * 覆蓋close方法,將數據庫連接返回連接池,而不是直接關閉連接
     */
    public void close() throws SQLException {
        connPool.releaseConnection(this.dbconn);
    }
   
}

同樣的道理,還可以利用 Decorator 模式對 DriverManager類進行同樣的改造,從而最小化數據庫連接池對傳統 JDBC 編碼方式的影響.
但是由于 Decorator 模式的缺點,會導致大量類似的小類,并且由于此模式要求實現與目標對象一致的接口,Connection 接口中定義的方法眾多,也必須在 ConnectionDecorator 類中逐一實現,雖然只是簡單的委托實現。隨意接下來引入 Dynamic Proxy 模式很好地解決了這一問題。


Dynamic Proxy 模式

Dynamic Proxy 模式是 JDK1.3 版本中引入的一種新的動態代理機制(Dynamic Proxy),它為 Java 帶來了極佳的運行期擴展能力。嚴格來說,Dynamic Proxy 本身并非一種模式,只能算是 Proxy 模式的一種動態實現方式。感覺有點像 Win32 里 hook 機制。

下面通過上面連接池的例子來解釋 Dynamic Proxy 機制(引自《深入淺出Hibernate》):
Dynamic Proxy 模式可以解決 Decorator 模式帶來的弊端。通過實現一個綁定到 Connection 對象的 InvocationHandler 接口來實現,使得可以在 Connection.close() 方法被調用時將其截獲,并以新的 close() 方法替代,實現連接調用關閉方法時返回到數據庫連接池中的目的。
下面是 ConnectionHandler 類,它實現了 InvocationHandler 接口,按照 Dynamic Proxy 機制的定義,invoke() 方法將截獲所有代理對象的方法調用操作,這里通過 invoke() 方法截獲 close() 方法來處理。

public class ConnectionHandler
    implements Invocationhandler {
   
    Connection dbconn;
    ConnectionPool pool;
   
    public ConnectionHandler(ConnectionPool connPool) {
        this.pool = connPool;
    }
   
    /**
     * 將動態代理綁定到指定 Connection 對象
     */
    public Connection bind(Connection conn) {
        this.dbconn = conn;
       
        Connection proxyConn =
            (Connection) Proxy.newProxyInstance(
                conn.getClass().getClassLoader(),
                conn.getClass().getInterfaces(),
                this);
               
        return proxyConn;
    }
   
    /**
     * 方法調用攔截器
     * 判斷當前調用的方法是否 "close" 方法
     * 如是,調用 pool.releaseConnection() 方法替代
     */
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
       
        Object obj = null;
       
        // 如果調用的方法是 "close" 方法
        if( "close".equals(method.getName()) ) {
            pool.releaseConnection(dbconn);
        }else {
            obj = method.invoke(dbconn, args);
        }
       
        return obj;
    }
}

另外 DbConnectionPool.getConnection() 方法也需要做修改以使用 ConnectionHandler 類:

pubic synchronised Connection getConnection()
    throws DBException {
   
    Connection conn;
   
    // 這里代碼從連接池中獲取一個空閑的連接,如無空閑連接,則創建一個新的連接
    ...
   
    // 這里調用 ConnectionHandler 類來綁定獲得的連接,使之變為一個連接代理返回給用戶
    ConnectionHanler connHanler = new ConnectionHanler(this);
    return connHanler.bind(conn);
}

到這里可以看到,基于 Dynamic Proxy 模式的實現相對 Decorator 更加簡潔明了。

參考文獻:1、《深入淺出Hibernate》

posted on 2005-10-03 12:24 Javen-Studio 閱讀(1395) 評論(0)  編輯 收藏 引用
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲成色精品| 亚洲一区二区三区精品动漫| 免费影视亚洲| 久久综合狠狠综合久久综合88| 欧美一区二区三区播放老司机| 午夜精彩视频在线观看不卡 | 欧美本精品男人aⅴ天堂| 久久婷婷麻豆| 亚洲国产电影| 亚洲毛片一区| 午夜久久一区| 农夫在线精品视频免费观看| 欧美精品免费看| 国产精品久久毛片a| 国产婷婷97碰碰久久人人蜜臀| 黑人一区二区三区四区五区| 亚洲人体1000| 欧美在线观看网址综合| 欧美va亚洲va国产综合| 99re66热这里只有精品3直播 | 国产精品国产馆在线真实露脸| 国产精品视频| 亚洲激情影视| 欧美亚洲在线观看| 亚洲第一精品电影| 亚洲欧美日韩久久精品| 美女在线一区二区| 国产精品高潮呻吟久久av无限| 狠狠入ady亚洲精品| 亚洲最新合集| 米奇777超碰欧美日韩亚洲| 亚洲视频一区二区免费在线观看| 亚洲午夜一二三区视频| 亚洲视频一区在线| 欧美在线观看视频一区二区三区| 麻豆成人在线观看| 亚洲精品一区二区三区av| 欧美在线黄色| 欧美亚男人的天堂| 亚洲国产精品一区二区第四页av | 亚洲欧美在线网| 欧美日韩mv| 亚洲成人中文| 久久久欧美一区二区| 一区二区三区蜜桃网| 欧美成人第一页| 狠狠色噜噜狠狠色综合久| 亚洲欧美一区在线| 日韩一区二区免费看| 欧美国产一区二区在线观看| 狠狠久久亚洲欧美| 久久久精品动漫| 亚洲欧美精品在线观看| 国产精品成人观看视频免费| 亚洲精品乱码久久久久| 欧美成人黄色小视频| 久久精品国产99| 国产综合婷婷| 久久这里有精品15一区二区三区| 亚洲一区视频| 国产精品一级久久久| 香蕉久久夜色| 亚洲免费视频在线观看| 国产精品久久久久久久久免费桃花| 这里只有精品丝袜| 99成人精品| 国产精品九九久久久久久久| 亚洲一区二区三区精品在线| 亚洲精品午夜精品| 欧美午夜精品电影| 欧美一区2区三区4区公司二百| 亚洲中字在线| 国语精品中文字幕| 美女网站久久| 欧美暴力喷水在线| 亚洲视频一区二区免费在线观看| 99re8这里有精品热视频免费| 国产精品成人aaaaa网站| 亚洲欧美三级伦理| 欧美尤物一区| 91久久极品少妇xxxxⅹ软件| 亚洲第一成人在线| 欧美日韩三级一区二区| 久久成人精品视频| 欧美freesex交免费视频| 亚洲网站啪啪| 欧美一区二区高清| 久久这里只精品最新地址| 日韩午夜电影| 国产精品久久久久久久久免费| 欧美一区二区免费| 老司机免费视频一区二区| 亚洲精品一区二区三区av| 一本一道久久综合狠狠老精东影业 | 久久久精品一品道一区| 麻豆精品视频在线观看| 一本大道久久a久久精品综合| 亚洲午夜激情免费视频| 在线国产亚洲欧美| 宅男噜噜噜66一区二区66| 激情久久久久久久久久久久久久久久| 亚洲第一色在线| 国产精品久久毛片a| 欧美黄色一级视频| 国产精品午夜视频| 亚洲欧洲一二三| 国产自产在线视频一区| 日韩视频免费| 在线观看欧美亚洲| 亚洲欧美日韩天堂| 亚洲图片欧洲图片av| 久久伊人一区二区| 欧美有码在线观看视频| 欧美精品精品一区| 欧美国产日韩a欧美在线观看| 国产精品尤物福利片在线观看| 亚洲国产激情| 在线欧美一区| 欧美在线播放一区| 欧美一二三视频| 欧美日一区二区三区在线观看国产免| 久久手机免费观看| 国产偷国产偷精品高清尤物| 9久re热视频在线精品| 亚洲欧洲综合另类在线| 久久精品夜色噜噜亚洲a∨| 午夜天堂精品久久久久| 欧美亚日韩国产aⅴ精品中极品| 最新国产の精品合集bt伙计| 亚洲国产日韩一区| 另类春色校园亚洲| 欧美激情1区2区3区| 亚洲欧洲日本一区二区三区| 老色鬼精品视频在线观看播放| 久久天天狠狠| 国产自产精品| 久久一区二区三区四区五区| 女人香蕉久久**毛片精品| 在线观看成人一级片| 久久免费高清| 欧美激情视频在线免费观看 欧美视频免费一 | 欧美一级视频| 狠狠色2019综合网| 欧美制服丝袜| 裸体素人女欧美日韩| 国产一区二区中文字幕免费看| 亚洲午夜成aⅴ人片| 亚洲欧美不卡| 国产美女高潮久久白浆| 欧美一区二区啪啪| 免费成人av在线看| 亚洲精品免费一二三区| 欧美日韩精品在线观看| 一区二区三区 在线观看视| 香港久久久电影| 国产综合av| 欧美激情2020午夜免费观看| 日韩视频在线一区二区| 亚洲免费人成在线视频观看| 国产精品无码永久免费888| 欧美一区二区三区视频| 欧美激情成人在线| 亚洲特级片在线| 国产一区二区三区的电影| 久久一日本道色综合久久| 亚洲裸体俱乐部裸体舞表演av| 亚洲欧美日韩爽爽影院| 黄色成人在线网址| 欧美日韩天天操| 欧美一区成人| 亚洲三级电影全部在线观看高清| 亚洲一本视频| 一区二区三区在线视频免费观看| 欧美mv日韩mv国产网站| 亚洲视频综合在线| 欧美第一黄色网| 欧美一区二区三区男人的天堂 | 午夜精品视频一区| 在线观看视频一区二区| 欧美日韩亚洲综合一区| 久久aⅴ国产欧美74aaa| 亚洲精品欧美日韩专区| 欧美在线在线| 中日韩在线视频| 亚洲国产中文字幕在线观看| 国产精品久久久久久久一区探花| 久久亚洲综合| 亚洲欧美日韩国产精品| 最近中文字幕mv在线一区二区三区四区| 亚洲免费中文| 亚洲精品偷拍| 黄色成人av网站| 国产精品一区免费在线观看| 免费不卡在线视频| 久久精品国产亚洲一区二区| 亚洲视频免费看| 日韩视频二区| 亚洲精品偷拍| 亚洲国产天堂久久综合网| 老妇喷水一区二区三区|