学习笔记(8):第2章 架构师内功心法之设计模式 -Abstract Factory Pattern抽象工厂模式...

立即学习:https://edu.csdn.net/course/play/28941/403597?utm_source=blogtoedu

抽象工厂模式(Abastract Factory Pattern)是指提供一个创建一些列相关获相互依赖对象的接口,无须指定他们具体的类。——属于创建型设计模式。


public interface IVideo{
    void record();
}
public interface INote{
    void edit();
}

public abstract class CourseFactory{
    public void init(){
        System.out,println("初始化基础数据");
    }

    protected abstract INote creatNote();
    
     protected abstract IVideo creatVideo();
}

public class JavaVideo implements IVideo{
    public void record(){
}

}
public class PythonVideo implements IVideo{
    public void record(){
}

}

public class JavaNote implements INote{
    public void edit(){
}

}
public class PythonNote implements INote{
    public void edit(){
}

}

public class JavaCourseFactory extends CourseFactory{
    protected INote createNote(){
    super.init();
    return new JavaNote();
}
    protected IVideo createVideo(){
    super.init();
    return new JavaVideo();
}
}

public class PythonCourseFactory extends CourseFactory{
    protected INote createNote(){
    super.init();
    return new PythonNote();
}
    protected IVideo createVideo(){
    super.init();
    return new PythonVideo();
}
}

public class Test{
   public static void main(String[] args){
       CourseFactory factory = new JavaCourseFactory();
       factory.createNote().edit();
       factory.createVideo().record();
}
}

抽象工厂模式的适用场景

客户端(应用层)不依赖于产品类实例如何创建、实现细节。

强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。

提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

产品族:一系类的相关的产品,整合到一起有关联。

产品等级:同一个继承体系。

优点:

具体产品在应用层代码隔离,无须关心创建细节。

将一系类的产品族统一到一起创建。

缺点:

规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。

增加了系统的抽象性和理解难度。

利用工厂模式重构的实践案例

JDBC操作案例,每次操作都需要重新创建数据库连接,每次创建其实都非常耗费性能,消耗业务调度时间。利用工厂模式,将数据库连接预先创建好放到容器中缓存着,在业务调用时就只需现取现用。

package jdbcfactory;
//Pool抽象类
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
import java.util.concurrent.locks.Condition;

/**
 自定义连接池getInstance()返回Pool唯一实例,第一次调用时执行构造函数
 构造函数Pool()调用驱动装载loadDrivers()函数;
 连接池创建creatPool()函数loadDrivers()装载驱动;
 createPool()建连接池getConnection()
 返回一个连接实例getConnection(Long time)添加时间限制;
 freeConne(connection con)将con连接实例返回当前使用的连接数
*/

public abstract class Pool {
    public String propertiesName = "connection-INF.properties";
    private static Pool instance = null; // 定义唯一实例
    /**最大连接数*/
    protected int maxConnect = 100;

    /**保持连接数*/
    protected int normalConnect = 10;

    /**驱动字符串*/
    protected String driverName = null;

    /**驱动类*/
    protected Driver driver = null;

    /**私有构造函数,不允许外界访问*/
    protected  Pool(){
        try{
            init ();
            loadDrivers(driverName);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**初始化所有从配置文件中读取的成员变量*/
    private void init() throws IOException {
        InputStream is = Pool.class.getResourceAsStream(propertiesName);
        Properties p = new Properties();
        p.load(is);
        this.driverName = p.getProperty("driverName");
        this.maxConnect = Integer.parseInt(p.getProperty("maxConnect"));
        this.normalConnect = Integer.parseInt(p.getProperty("normalConnect"));
    }
    /**装载和注册所有JDBC驱动程序
     * @Param dri 接受驱动字符串*/
    protected void loadDrivers(String dri) {
        String driverClassName = dri;
        try {
            driver = (Driver) Class.forName(driverClassName).newInstance();
            DriverManager.registerDriver(driver);
            System.out.println("成功注册JDBC驱动程序" + driverClassName);
        } catch (Exception e) {
            System.out.println("无法注册JDBC驱动程序" + driverClassName + ",错误:" + e);
        }

    }

    /**创建连接池*/
    public abstract void createPool();
    /**
     * (单例模式)返回数据库连接池Pool实例
     * @return
     * @throws IOException
     * @throws ClassCastException
     * @throws IllegalAccessException
     * @throws InterruptedException
     * */
    public static synchronized Pool getInstance() throws IOException,
            ClassNotFoundException, IllegalAccessException, InstantiationException {
        if (instance == null) {
            instance.init();
            instance = (Pool) Class.forName("org.e_book.sqlhelp.Pool").newInstance();
        }
        return instance;
    }
    /**获得一个可用连接,如果没有则创建一个连接,且小于最大连接限制
     * @return*/
    public abstract Connection getConnection();

     /**获得一个连接,有时间限制
      * @Param time 设置该链接持续时间(以毫秒为单位)*/
     public abstract Connection getConnection(long time);

     /**将连接对象返回给连接池
      * @param con 获得连接对象*/
     public abstract void freeConnection(Connection con);

    /**返回当前空闲连接数*
     * @return
     */
    public abstract int getnum();

    /**返回当前工作的连接数
     * @return*/
    public abstract int getnumActive();

     /**关闭所有连接,撤销驱动注册(此方法为单例方法)*/
     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());;
         }
     }
}
package jdbcfactory;
import java.io.*;
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;
import java.util.concurrent.locks.Condition;
import java.util.zip.CheckedOutputStream;

/**管理数据库连接池*/
public class DBConnectionPool extends Pool{
    private int checkedOut; // 正在使用的连接数

    /**存放产生的连接对象容器*/
    private Vector<Connection> freeConnections = new Vector<>();

    private String passWord = null; // 密码

    private String url = null; // 连接字符串

    private String userName = null; //用户名

    private static int num = 0; //空闲连接数

    private static int numActive = 0; // 当前可用的连接数

    private static DBConnectionPool pool = null; // 连接池实例变量

    /**产生数据连接池
     * @return*/
    public static synchronized DBConnectionPool getInstance(){
         if (pool == null){
             pool = new DBConnectionPool();
         }
         return pool;
    }
    /**
     * 获得一个连接池实例*/
    private DBConnectionPool(){
        try {
            init();
            for (int i = 0; i < normalConnect; i++){
                //初始化normalConn个连接
                Connection c = newConnection();
                if (c != null){
                    freeConnections.addElement(c);
                    num++;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**建立连接池*/
    @Override
    public void createPool() {
        pool = new DBConnectionPool();
        if (pool != null){
            System.out.println("创建连接池成功");
        }else {
            System.out.println("创建连接池失败");
        }

    }
    /**初始化
     * @throws IOException*/
    private void init() throws IOException {
        InputStream is = DBConnectionPool.class.getResourceAsStream(propertiesName);
        Properties p = new Properties();
        p.load(is);
        this.userName = p.getProperty("userName");
        this.passWord = p.getProperty("passWord");
        this.driverName = p.getProperty("driverName");
        this.url = p.getProperty("url");
        this.driverName = p.getProperty("driverName");
        this.maxConnect = Integer.parseInt(p.getProperty("maxConnect"));
        this.normalConnect = Integer.parseInt(p.getProperty("normalConnect"));
    }
    /**如果不再使用某个连接对象时,可调用此方法将该对象释放到连接池
     * @param con*/


    /**创建一个连接池
     * @return*/
    private Connection newConnection(){
         Connection con = null;
             try {
                 if (userName == null) {// 用户,密码都为空
                     con = DriverManager.getConnection(url);
                 } else {
                     con = DriverManager.getConnection(url, userName, passWord);
                 }
                 System.out.println("连接池创建一个新连接");
             }catch (SQLException e) {
                 System.out.println("无法创建这个URL的连接"+url);
                 return null;
             }
             return con;
    }


    //(单利模式)获取一个可用连接
    @Override
    public synchronized Connection getConnection() {
         Connection con = null;
         if (freeConnections.size() > 0){ // 还有空的连接
             num--;
             con = (Connection) freeConnections.firstElement();
             freeConnections.removeElementAt(0);
             try{
                 if(con.isClosed()){
                     System.out.println("从连接池删除一个无效连接");
                     con = getConnection();
                 }
             }catch (SQLException e){
                 System.out.println("从连接池删除一个无效连接");
                 con = getConnection();
             }
         }else if (maxConnect == 0 || checkedOut < maxConnect){ // 没有空闲连接且当前连接小于最大允许值,最大值为0则不限制
             con = newConnection();
         }
        if (con != null){// 当前连接数+1
            checkedOut++;
        }
        numActive++;
       return con;
    }
    /**获取一个连接,并加上等待时间限制,时间为毫秒
     * @param  timeout 接受等待时间(以毫秒为单位)
     * @return*/
    @Override
    public synchronized Connection getConnection(long timeout) {
         long startTime = new Date().getTime();
         Connection con;
         while ((con = getConnection()) == null){
             try {
                 wait(timeout); // 线程等待
             }catch (InterruptedException e){

             }
             if ((new Date().getTime() - startTime) >= timeout){
                 return null;
             }
         }
        return con;
    }


    /**关闭所有连接*/
    public synchronized void release(){
        try {
            //将当前连接赋值到枚举中
            Enumeration allConnections = freeConnections.elements();
            //使用循环关闭所有连接
            while (allConnections.hasMoreElements()){
                //如果枚举对象至少还有一个可提供的元素,则返回次枚举的元素
                Connection conn = (Connection) allConnections.nextElement();
                try{
                    conn.close();
                    num--;
                }catch (SQLException e){
                    System.out.println("无法关闭连接池中的连接");
                }
            }
            freeConnections.removeAllElements();
            numActive = 0;
        }finally {
            super.release();
        }
    }
    /***/

    @Override
    public synchronized void freeConnection(Connection con) {
        freeConnections.addElement(con);
        num++;
        checkedOut--;
        numActive--;
        notifyAll();//解锁
    }

    @Override
    public int getnum() {
        return num;
    }

    @Override
    public int getnumActive() {
        return numActive;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43222122/article/details/107520627