裝飾模式

二、裝飾模式

2.1 裝飾模式原理Connection close

目的:改寫已存在的類的某個方法或某些方法,裝飾設(shè)計模式(包裝模式)

口訣:

1、編寫一個類,實現(xiàn)與被包裝類相同的接口。(具備相同的行為)

2、定義一個被包裝類類型的成員變量。

3、定義構(gòu)造方法,把被包裝類的對象注入,給被包裝類變量賦值。

4、對于不需要改寫的方法,調(diào)用原有的方法。

5、對于需要改寫的方法,寫自己的代碼。

1.包裝Connection的實現(xiàn)類

 //mysql的Connection類實現(xiàn)了sun公司的Connection的接口規(guī)范
 //我們要包裝的是mysql的Connection 
 //所以:我們寫的這個包裝類也要實現(xiàn)sun公司的Connection的接口規(guī)范--我們的類與mysql的Connection要具有相同的約束動作
  //1.編寫一個類,使之與被包裝類實現(xiàn)相同的接口(具有相同的行為)
 public class DecoratorConnection implements Connection{ 

private Connection oldConnection;   //2.添加一個被包裝類的對象(依賴的關(guān)系)--實際上運行的時候傳過來的是實現(xiàn)類的對象:com.mysql.jdbc.Connection的實例
private LinkedList<Connection> pool;

//3.定義構(gòu)造方法,通過構(gòu)造方法的參數(shù),將被包裝類注入,給被包裝類賦值 
//實際上運行的時候傳過來的是實現(xiàn)類的對象:com.mysql.jdbc.Connection的實例
public DecoratorConnection(Connection conn,LinkedList<Connection> pool){
    this.oldConnection = conn;
    this.pool = pool;
}

 //5.需要改寫的方法:自己寫代碼
 @Override
public void close() throws SQLException {
    //因為這里關(guān)閉連接也需要連接池的引用,所以,也必須把連接池注入到本類中
  pool.addLast(oldConnection);
}
//下面的方法不需要改變原有的功能,只以prepareStatement(String sql)為例,以下其它方法相同: 
 //4.對于不需要改寫的方法,調(diào)用原有的方法 
 @Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
    return oldConnection.prepareStatement(sql);
}
 //其它方法略……
}

2.連接池產(chǎn)生的Connection是被包裝之后的類

//sun公司開發(fā)一套連接池的接口規(guī)范DataSource,自定義的連接池,要實現(xiàn)這個規(guī)范
//這回實現(xiàn)連接池,使用的是實現(xiàn)sun公司的接口
public class MyDataSource implements DataSource{
// 創(chuàng)建一個連接的池子--集合,線程安全的問題
private static LinkedList<Connection> pool = (LinkedList<Connection>) Collections
        .synchronizedList(new LinkedList<Connection>());

// 在連接池中初始化10個連接
static {
    try {
        for (int i = 0; i < 10; i++) {
            Connection conn = DBUtil.getConnection();
            pool.add(conn);
        }
    } catch (Exception e) {
        // 將異常向上拋
        throw new ExceptionInInitializerError("初始化連接池失??!");
    }
}

// 重寫getConnection()方法
@Override
public Connection getConnection() throws SQLException {
    Connection conn = null;
    if(pool.size()>0){ //說明池子里還有連接
      conn =  pool.removeFirst();  //移除并返回對象
      Connection myConn = new DecoratorConnection(conn,pool); //得到一個包裝后的Connection對象
      return myConn;  //返回的是包裝之后的Connection
}else{  
      throw new RuntimeException("服務(wù)器正忙.......");
      //服務(wù)器正忙的解決思路:
      //1.等待
      //2.等待超時新創(chuàng)建一個連接用DBUtil產(chǎn)生,用完之后,不用交回池,真的close()
    }
}
  // 其余方法實現(xiàn)……
@Override
public PrintWriter getLogWriter() throws SQLException {
    // TODO Auto-generated method stub
    return null;
}

3.編寫測試類

public static void main(String[] args) {
    Connection conn = null;
    PreparedStatement ps = null;
    
    try {
        DataSource ds = new MyDataSource();
        conn = ds.getConnection();  //從池中取出一個連接,這個連接已經(jīng)被包裝了DecoratorConnection類型的
        ps = conn.prepareStatement(".........");
        ps.executeQuery();
        
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        try {
            conn.close();  //調(diào)用了包裝Connection之后的DecoratorConnection的close()方法了
                           //即:被連接池回收了
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容