结合JDK,Spring,Mybatis,Netty,Tomcat,Dubbo等经典框架的源码对设计模式展开分析(一)

结合JDK,Spring,Mybatis,Netty,Tomcat,Dubbo等经典框架的源码对设计模式展开分析(一),第1张

创建型设计模式

一.简单工厂模式(Simple Factory Pattern)别名静态工厂方法模式

定义:抽象封装了对象创建的逻辑。适合在对象创建逻辑复杂的情况下使用

产品类有公用父接口

简单工厂方法中集中对象创建逻辑,采用静态方法的方式

这样在对产品类进行扩展时,不会影响客户端代码,工厂方法中的对象创建方式可以采用反射的方式来避免频繁修改,靠近于开闭原则

简单工厂方法在JDK中的应用:

Calender.getInstance()方法

优点:结构简单方便调用,工厂和产品的职责区分明确

缺点:工厂类单一,当产品基数增多时,工厂类会特别臃肿,违背高聚合原则

二.工厂方法模式(Factory Method Pattern)别名多态性工厂模式

定义:定义一个创建对象的接口,由实现这个接口的类决定实例化哪个类,工厂方法模式把类的实例化推迟到子类中进行 多态 的使用

对象:抽象工厂,具体工厂,抽象产品,具体产品

分解掉简单工厂模式下,所有产品的创建均由一个工厂类来控制所造成的代码臃肿,使产品与工厂一一对应

优点:灵活性增强,在新产品添加时,只需多写一个对应的工厂类,解耦合

缺点:类的个数增多

三.抽象工厂模式

定义:提供一个创建一系列相关或相互依赖对象的接口,无需指定他们具体的类,适用于需要生产产品族的情景,区分产品族和产品等级,同一产品族下的各各等级的产品由同一个抽象工厂的实现类去创建(抽象出产品族和产品等级这两层关系,清晰化业务层次关系,更具有逻辑性)

角色:抽象工厂,具体工厂,抽象产品,具体产品

实际应用:

  1. 抽象工厂模式重构数据库连接池

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;
    }
}

优点:增加了程序的可扩展性,在需求新增时能不修改已有代码,只需实现新的具体工厂即可

缺点:在产品族中扩展的新的产品比较乏力,增加了系统的抽象理解难度

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/868134.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存