一.简述及实现原则
装饰模式:在不改变 原有类 和 不使用继承的情况下, 动态地扩展一个对象的功能。
因会创建一个包装对象,来包裹真实对象而得名。
- 作用:增强对象的功能
例子1:
墙: 功能---遮风挡雨
包了墙纸的墙(本质还是墙):
功能---遮风挡雨
新增功能---陶冶情操
例子2:
钢笔: 功能---写字
包了礼盒的钢笔(本质还是钢笔):
功能---写字
功能---礼品
- 没有改变原有类
- 进行动态地增强
装饰类:增强功能的类(包了墙纸的墙)
被装饰类:待增强功能的类(墙)
实现原则:
- 装饰类 必须 实现 被装饰类的所有接口
- 装饰类 中 必须获取 被装饰类对象
二.入门案例
分析:
- 定义一个装饰类 实现 Phone接口
- 装饰类中 获取到 被装饰类对象(成员变量)
代码实现:
HWPhoneDecorator:
public class HWPhoneDecorator implements Phone {
//被装饰类的对象
private HWPhone old;
public HWPhoneDecorator(HWPhone old) {
this.old = old;
}
/*
* 打电话方法不需要增强,不需要改变
* */
public void call(String number) {
old.call(number);
}
/**
* 发短信方法需要被增强
*/
public void sendMsg() {
//1、先运行原来的功能
old.sendMsg();
//2、再执行新的增强代码
System.out.println("(o゜▽゜)o☆[BINGO!]");
}
}
测试类:
public static void main(String[] args) {
Phone hw = new HWPhoneDecorator(new HWPhone());
hw.call("12345");
hw.sendMsg();
}
小结:
装饰者设计模式,可以在不改变原有类的情况,动态增强类中某个方法。
实现:
- 装饰类实现 被装饰类实现的所有接口
- 装饰类中 获取 被装饰类对象
三.装饰者设计模式向静态代理转变
HWPhoneDecorator
public class HWPhoneDecorator implements Phone {
//被装饰类的对象
private Phone old; //接口下的实现类都能增强
public HWPhoneDecorator(Phone old) {
this.old = old;
}
/*
* 打电话方法不需要增强,不需要改变
* */
public void call(String number) {
old.call(number);
}
/**
* 发短信方法需要被增强
*/
public void sendMsg() {
//1、先运行原来的功能
old.sendMsg();
//2、再执行新的增强代码
System.out.println("(o゜▽゜)o☆[BINGO!]");
}
}
四..使用装饰者设计模式修改连接池
- 增强Connection 对象close方法,不是关闭资源,而是归还连接池
分析:
- 编写一个装饰类MyConnection,增强Connection对象
- 需要重写close方法
- 把连接池创建的Connection对象,装饰为MyConnection对象
MyConnection
public class MyConnection implements Connection {
//被装饰的Connection对象
private Connection old;
//因为close方法需要把连接归还连接池,所以这里也要获取连接池
private LinkedList<Connection> pool;
public MyConnection(Connection old, LinkedList<Connection> pool) {
this.old = old;
this.pool = pool;
}
/**
* 要增强的close方法
* @throws SQLException
*/
public void close() throws SQLException {
//old.close();//会关闭资源
//把当前装饰类对象 归还到连接池
pool.addLast(this);
}
/**
* 其他方法 用原对象进行调用即可,底下代码无需手写
*/
public Statement createStatement() throws SQLException {
return old.createStatement();
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
return old.prepareStatement(sql);
}
public CallableStatement prepareCall(String sql) throws SQLException {
return old.prepareCall(sql);
}
public String nativeSQL(String sql) throws SQLException {
return old.nativeSQL(sql);
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
old.setAutoCommit(autoCommit);
}
public boolean getAutoCommit() throws SQLException {
return old.getAutoCommit();
}
public void commit() throws SQLException {
old.commit();
}
public void rollback() throws SQLException {
old.rollback();
}
public boolean isClosed() throws SQLException {
return old.isClosed();
}
public DatabaseMetaData getMetaData() throws SQLException {
return old.getMetaData();
}
public void setReadOnly(boolean readOnly) throws SQLException {
old.setReadOnly(readOnly);
}
public boolean isReadOnly() throws SQLException {
return old.isReadOnly();
}
public void setCatalog(String catalog) throws SQLException {
old.setCatalog(catalog);
}
public String getCatalog() throws SQLException {
return old.getCatalog();
}
public void setTransactionIsolation(int level) throws SQLException {
old.setTransactionIsolation(level);
}
public int getTransactionIsolation() throws SQLException {
return old.getTransactionIsolation();
}
public SQLWarning getWarnings() throws SQLException {
return old.getWarnings();
}
public void clearWarnings() throws SQLException {
old.clearWarnings();
}
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
return old.createStatement(resultSetType,resultSetConcurrency);
}
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return old.prepareStatement(sql,resultSetType,resultSetConcurrency);
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return old.prepareCall(sql,resultSetType,resultSetConcurrency);
}
public Map<String, Class<?>> getTypeMap() throws SQLException {
return old.getTypeMap();
}
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
old.setTypeMap(map);
}
public void setHoldability(int holdability) throws SQLException {
old.setHoldability(holdability);
}
public int getHoldability() throws SQLException {
return old.getHoldability();
}
public Savepoint setSavepoint() throws SQLException {
return old.setSavepoint();
}
public Savepoint setSavepoint(String name) throws SQLException {
return old.setSavepoint(name);
}
public void rollback(Savepoint savepoint) throws SQLException {
old.rollback(savepoint);
}
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
old.releaseSavepoint(savepoint);
}
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return old.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability);
}
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return old.prepareStatement(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
}
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return old.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
}
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return old.prepareStatement(sql,autoGeneratedKeys);
}
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return old.prepareStatement(sql,columnIndexes);
}
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return old.prepareStatement(sql,columnNames);
}
public Clob createClob() throws SQLException {
return old.createClob();
}
public Blob createBlob() throws SQLException {
return old.createBlob();
}
public NClob createNClob() throws SQLException {
return old.createNClob();
}
public SQLXML createSQLXML() throws SQLException {
return old.createSQLXML();
}
public boolean isValid(int timeout) throws SQLException {
return old.isValid(timeout);
}
public void setClientInfo(String name, String value) throws SQLClientInfoException {
old.setClientInfo(name,value);
}
public void setClientInfo(Properties properties) throws SQLClientInfoException {
old.setClientInfo(properties);
}
public String getClientInfo(String name) throws SQLException {
return old.getClientInfo(name);
}
public Properties getClientInfo() throws SQLException {
return old.getClientInfo();
}
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return old.createArrayOf(typeName,elements);
}
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return old.createStruct(typeName,attributes);
}
public void setSchema(String schema) throws SQLException {
old.setSchema(schema);
}
public String getSchema() throws SQLException {
return old.getSchema();
}
public void abort(Executor executor) throws SQLException {
old.abort(executor);
}
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
old.setNetworkTimeout(executor,milliseconds);
}
public int getNetworkTimeout() throws SQLException {
return old.getNetworkTimeout();
}
public <T> T unwrap(Class<T> iface) throws SQLException {
return old.unwrap(iface);
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return old.isWrapperFor(iface);
}
}
MyDataSource
public class MyDataSource implements DataSource {
private static final String DRIVERCLASS="com.mysql.jdbc.Driver";
private static final String URL="jdbc:mysql://127.0.0.1:3306/day01_db";
private static final String USERNAME="root";
private static final String PASSWORD="1234";
//连接池
private static final LinkedList<Connection> pool = new LinkedList<Connection>();
static{
//1、注册驱动
try {
Class.forName(DRIVERCLASS);
//2、初始化连接池,默认连接池有5个连接
initPool();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 初始化连接池
*/
private static void initPool() throws SQLException {
for (int i = 0; i <5 ; i++) {
pool.addLast(getCon());
}
}
/**
* 类内部进行获取连接的方法
* @return
*/
private static Connection getCon() throws SQLException {
return new MyConnection(DriverManager.getConnection(URL,USERNAME,PASSWORD),pool);
}
/**
* 获取连接
* @return
* @throws SQLException
*/
public Connection getConnection() throws SQLException {
//判断:连接池是否有连接
if(pool.size()==0){
//连接池没有连接,再创建5个
initPool();
}
//连接池有连接,从池中取出一个连接
return pool.removeLast();
}
/**
* 关闭所有资源 (con对象 归还到 连接池中)
* @param con
* @param ps
* @param rs
* @throws SQLException
*/
public static void closeAll(Connection con, PreparedStatement ps,ResultSet rs) throws SQLException {
if(rs!=null)
rs.close();
if(ps!=null)
ps.close();
if(con!=null)
con.close();
}
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
public PrintWriter getLogWriter() throws SQLException {
return null;
}
public void setLogWriter(PrintWriter out) throws SQLException {
}
public void setLoginTimeout(int seconds) throws SQLException {
}
public int getLoginTimeout() throws SQLException {
return 0;
}
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
看完恭喜你,又知道了一点点!!!
你知道的越多,不知道的越多!
~感谢志同道合的你阅读, 你的支持是我学习的最大动力 ! 加油 ,陌生人一起努力,共勉!!
注: 如果本篇有需要改进的地方或错误,欢迎大神们指定一二~~