装饰设计模是对一个已存在的类进行增强,他的实现思路是:
1 明确被装饰类的继承体系,我们写的装饰类和被装饰类同在一个体系,即同一个级别;
2 定义一个被装饰类的一个成员变量,以构造函数的形式对他进行初始化操作;
3 明确哪些是我们要对被装饰类进行增强或者改写的功能;对无需增强的功能,直接调用被传进来的被装饰对象,调用原来的方法
对于要改下的功能进行自定义即可;
4 如果需要返回一个装饰类,最好以父类的形式返回;
自定义数据源的实现思路:
1 在类加载的时候就创建一批连接,并用一个集合(由于要多次进行增删操作,使用LinkedList)存储,取的时候从集合中remove,
2给用户提供获取连接的方法,当然对于用户获取的实际连接对象,这是我们包装后的连接对象,目的是为了不让用户直接关闭连接而损失
而是当用户调用关闭连接方法的时候,我们将连接从新放回原集合中(可以看做是一个数据库连接池);
3 实现java.sql.DataSource接口的其他方法;
我们自定义一个数据源主要是要改写用户获取的连接即Connection,改下close功能,防止用户之间关闭连接;从而损失连接;
不多说直接上代码;JDBC工具类,在此之前,数据库驱动包,配置文件什么的自己配吧,这个应该很简单:
package cn.itcast.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public final class JDBCUtils {
private JDBCUtils() {
}
private final static String url;
private final static String user;
private final static String password;
private final static String driverClassName;
static {
try {
InputStream inputStream = JDBCUtils.class.getClassLoader()
.getResourceAsStream("oracle_dbconfig.properties");
Properties props = new Properties();
props.load(inputStream);
url = props.getProperty("url");
user = props.getProperty("user");
password = props.getProperty("password");
driverClassName = props.getProperty("driverClassName");
} catch (Exception e) {
// 将异常转型为初始化错误抛出, 为数据库连接都没建好,没必要进行下去了;
throw new ExceptionInInitializerEr ror(e);
}
}
public static Connection getConnection() {
try {
Class.forName(driverClassName);
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static void free(ResultSet resultSet, Statement statement,
Connection connection) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
//当关闭结果集的时候,这 做通知gc对其进行回收;
resultSet = null;
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
statement = null;
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
connection = null;
}
}
}
下面这个是包装类MyConnection,只提供关键方法
public class UpgradeMyConnection extends MyConnection {
private Connection conn;
private LinkedList<Connection> pool;
public UpgradeMyConnection(Connection conn, LinkedList<Connection> pool) {
super(conn, pool);
}
@Override
public void close() throws SQLException {
pool.addFirst(conn);
}
}
大家也许发现了, 这里是UpgradeMyConnection,听我细细说来,这是对包装设计模式的一种该进,如果我们每次都只对被包装对象的某些方法进行增强或改写,而必须继承或者实现许多我们并不关心的方法,即直接调用被包装类对象上的方法即可.一次两次还可以接受,如果每次都得这 做,估计 得吐了, 此我们想到,可不可以这 ,我们定义一个空包装类,即对被包装类的所有方法进行空包装,直接调用被包装类的对象;
然后我们在继承这个空包装类,那么我们就爽多了,只要覆盖我们想增强或者改写的方法, 为其他方法父类已经实现了就不用在转给被包装类对象了,这省了不少事;只要空包装类估计大家肯定也能看懂的.
下面这个是我们写的数据源类,当然只覆盖了 心方法getConnection,
package cn.itcast.datasource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
import javax.sql.DataSource;
import cn.itcast.util.JDBCUtils;
import sun.jdbc.odbc.JdbcOdbc;
public class UpgradeDataSource implements DataSource {
private static LinkedList<Connection> pool=new LinkedList<Connection>();
static{
for(int i=0;i<10;i++){
pool.add(JDBCUtils.getConnection());
}
}
private UpgradeDataSource(){
}
private final static DataSource dataSource=new UpgradeDataSource();
public static DataSource getDataSource(){
return dataSource;
}
@Override
public synchronized Connection getConnection() throws SQLException {
if(pool.size()>0){
//这里返回的是包装好了的connection对象,但是我们的返回值还是写java.sql.Connection
//调用者完全可以将他当做connection对象来用,只是当他调用close方法的时候,被我们拦截并处理了,不是直接关闭
//而是从新返回数据库连接 中,从而做到了数据库连接的复用.
//同时必须得考虑到并发的问题是要同步代 块解决
UpgradeMyConnection myConnection=new UpgradeMyConnection(pool.removeFirst(), pool);
return myConnection;
}else
throw new RuntimeException("服务器正忙!!!");
}
}
总结:包装设计模式或者说装饰设计模式,核心是对被包装类的某些方法进行增强和改写,相比于直接集成被包装类有如下好处;
1 由于你是直接集成,那么原先的一些属性会丢失;
2 会使得继承体系变得非常的臃肿;