创建型设计模式
一.简单工厂模式(Simple Factory Pattern)别名静态工厂方法模式
定义:抽象封装了对象创建的逻辑。适合在对象创建逻辑复杂的情况下使用
产品类有公用父接口
简单工厂方法中集中对象创建逻辑,采用静态方法的方式
这样在对产品类进行扩展时,不会影响客户端代码,工厂方法中的对象创建方式可以采用反射的方式来避免频繁修改,靠近于开闭原则
简单工厂方法在JDK中的应用:
Calender.getInstance()方法
优点:结构简单方便调用,工厂和产品的职责区分明确
缺点:工厂类单一,当产品基数增多时,工厂类会特别臃肿,违背高聚合原则
二.工厂方法模式(Factory Method Pattern)别名多态性工厂模式
定义:定义一个创建对象的接口,由实现这个接口的类决定实例化哪个类,工厂方法模式把类的实例化推迟到子类中进行 多态 的使用
对象:抽象工厂,具体工厂,抽象产品,具体产品
分解掉简单工厂模式下,所有产品的创建均由一个工厂类来控制所造成的代码臃肿,使产品与工厂一一对应
优点:灵活性增强,在新产品添加时,只需多写一个对应的工厂类,解耦合
缺点:类的个数增多
三.抽象工厂模式
定义:提供一个创建一系列相关或相互依赖对象的接口,无需指定他们具体的类,适用于需要生产产品族的情景,区分产品族和产品等级,同一产品族下的各各等级的产品由同一个抽象工厂的实现类去创建(抽象出产品族和产品等级这两层关系,清晰化业务层次关系,更具有逻辑性)
角色:抽象工厂,具体工厂,抽象产品,具体产品
实际应用:
- 抽象工厂模式重构数据库连接池
package com.designMode;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
/**
* @author yangxiaozhen
* @date 2022/5/4-14:16
* 自定义连接池
* getInstance()返回POOL唯一实例,第一次调用时执行构造函数
* 构造函数Pool()调用驱动装载LoadDrivers()函数
* 连接池创建CreatePool()函数,loadDrivers()函数装载驱动
* getConnection()返回一个连接实例 getConnection(Long time)添加时间限制
* freeConnection(Connection con) 将con连接实例返回连接池
* getNum()返回空闲连接数
* getActiveNum()返回当前使用的连接数
*/
public abstract class Pool {
public static String propertiesName = "connection-INF.properties";
private static Pool instance = null;
protected int MaxConnect = 0;//最大连接数量
protected int normalConnect = 0;//保存连接数量
protected String driverName = null;
protected Driver driver = null;
//私有的无参构造方法
protected Pool() {
try {
init();
loadDriver(driverName);
} catch (IOException e) {
e.printStackTrace();
}
}
//从配置文件读取,初始化成员变量
private void init() throws IOException {
InputStream is = Pool.class.getClassLoader().getResourceAsStream(propertiesName);
Properties p = new Properties();
p.load(is);
driverName = p.getProperty("driverName");
normalConnect = Integer.parseInt(p.getProperty("normalConnect"));
MaxConnect = Integer.parseInt(p.getProperty("MaxConnect"));
driverName = p.getProperty("driverName");
}
//根据drivername加载驱动,并给drivermanager注册驱动
private void loadDriver(String driverName) {
try {
driver = (Driver) Class.forName(driverName).newInstance();
DriverManager.registerDriver(driver);
System.out.println("加载驱动" + driverName + "成功");
} catch (Exception e) {
System.out.println("加载驱动" + driverName + "失败,错误信息" + e);
}
}
//单例模式,返回数据库连接池实例
static synchronized Pool getInstance() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
if (instance == null) {
instance = (Pool) Class.forName("com.designMode.Pool").newInstance();
}
return instance;
}
//创建连接池抽象方法
public abstract void createPool();
public abstract Connection getConnection();
public abstract Connection getConnection(Long timeout);
public abstract void freeConnection(Connection connection);
public abstract int getNum();
public abstract int getActiveNum();
//注销驱动
protected synchronized void release() {
try {
DriverManager.deregisterDriver(driver);
System.out.println("撤销JDBC驱动" + driver.getClass().getName());
} catch (SQLException e) {
System.out.println("撤销JDBC驱动" + driver.getClass().getName() + "失败:" + e);
}
}
}
package com.designMode;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
/**
* @author yangxiaozhen
* @date 2022/5/4-15:08
* 数据库连接池管理类
*/
public class DBConnectionPool extends Pool {
private int checkedOut;//正在使用的连接
private Vector connections = new Vector();//存放创建的连接
private String password = null;
private String username = null;
private String url = null;
private static int num = 0;
private static int numActive = 0;
private static DBConnectionPool pool = null;
public static synchronized DBConnectionPool getInstance() {
if (pool == null) {
pool = new DBConnectionPool();
}
return pool;
}
private DBConnectionPool() {
try {
init();
for (int i = 0; i < normalConnect; i++) {
Connection c = newConnection();
if (c != null) {
connections.addElement(c);
num++;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
//初始化配置资源
private void init() throws IOException {
InputStream inputStream = DBConnectionPool.class.getClassLoader().getResourceAsStream(propertiesName);
Properties properties = new Properties();
properties.load(inputStream);
this.username = properties.getProperty("username");
this.password = properties.getProperty("password");
this.driverName = properties.getProperty("driverName");
this.url = properties.getProperty("url");
this.MaxConnect = Integer.parseInt(properties.getProperty("maxConnection"));
this.normalConnect = Integer.parseInt(properties.getProperty("normalConnect"));
}
private Connection newConnection() {
Connection connection = null;
try {
if (username == null) {
connection = DriverManager.getConnection(url);
} else {
connection = DriverManager.getConnection(url, username, password);
}
System.out.println("创建新连接成功");
} catch (SQLException e) {
System.out.println("创建URL:" + url + "连接失败:" + e);
return null;
}
return connection;
}
@Override
public void createPool() {
pool = new DBConnectionPool();
if (pool != null) {
System.out.println("创建连接池成功");
}
System.out.println("创建连接池失败");
}
@Override
public synchronized Connection getConnection() {
Connection connection = null;
if (connections.size() > 0) {
num--;
connection = (connections.firstElement());
connections.removeElementAt(0);
try {
if (connection.isClosed()) {
connection = getConnection();
System.out.println("从连接池中删除一个失效连接");
}
} catch (SQLException e) {
connection = getConnection();
System.out.println("从连接池中删除一个失效连接");
}
} else if (MaxConnect == 0 || checkedOut < MaxConnect) {
connection = newConnection();
}
if (connection != null) {
checkedOut++;
}
numActive++;
return connection;
}
@Override
public synchronized Connection getConnection(Long timeout) {
long time = new Date().getTime();
Connection connection;
while ((connection = newConnection()) == null) {
try {
wait(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
if ((new Date().getTime() - time) >= timeout) {
return null;
}
}
return connection;
}
@Override
public synchronized void freeConnection(Connection connection) {
connections.addElement(connection);
num++;
checkedOut--;
numActive--;
notifyAll();
}
public synchronized void release() {
try {
Enumeration elements = connections.elements();
while (elements.hasMoreElements()) {
Connection connection = elements.nextElement();
try {
connection.close();
num--;
} catch (SQLException e) {
System.out.println("无法关闭连接池中的连接" + e);
}
}
connections.removeAllElements();
numActive = 0;
} finally {
super.release();
}
}
@Override
public int getNum() {
return num;
}
@Override
public int getActiveNum() {
return numActive;
}
}
优点:增加了程序的可扩展性,在需求新增时能不修改已有代码,只需实现新的具体工厂即可
缺点:在产品族中扩展的新的产品比较乏力,增加了系统的抽象理解难度
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)