Pattern(笔记) - 享元模式

享元模式

本篇文章是通过看视频学习总结的内容, 如有错误的地方请谅解,并联系博主及时修改,谢谢您的阅读.

何为享元模式?

享元模式借名之意就是指,通过设计模式来对数据的共享

适用场景:

数据库连接池、线程池、包装数据类型的 cache,String字符串常量池等,都属于享元模式的使用

享元模式的优点:

  • 享元模式起到了对象的复用,减少内存中对象的数量,省去了创建对象消耗的时间,节约内存,提高性能

享元模式的缺点:

  • 享元模式存在一定的隐秘性,如果在不了解享元模式的情况下你根本不知道
    Integer.valueOf(127) == Integer.valueOf(127) -> true ;
    Integer.valueOf(128) == Integer.valueOf(128) -> false;
  • 一般情况下,享元模式都是和工厂模式结合使用,例如数据库连接池只能有一个,增加了程序复杂度。

举个例子(连接池):

  • 数据库连接池
/**
 * <p>
 *      享元模式:
 *          对象的重复利用,降低重复多次创建可复用的对像的成本
 * </p>
 *
 * @author Zyred
 * @date 2020/9/7 21:58
 **/
public class ConnectionPool {

    private Vector<Connection> pool;

    private int initializePoolSize = 127;
    private String userName = "root";
    private String password = "root";
    private String url = "jdbc:mysql://localhost:3306/test";
    private String driverClassName ="com.mysql.jdbc.Driver";

    public ConnectionPool() {
        try {
            pool = new Vector<Connection>();
            Class.forName(this.driverClassName);
            for (int i = 0; i < initializePoolSize; i++) {
                Connection conn = DriverManager.getConnection(this.url, this.userName, this.password);
                this.pool.add(conn);
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    public synchronized Connection getConnection(){
        Connection connection = this.pool.get(0);
        this.pool.remove(connection);
        return connection;
    }

    public synchronized void release(Connection conn){
        this.pool.add(conn);
    }
}
  • 连接池客户端
/**
 * <p>
 *      连接池客户端
 * </p>
 *
 * @author zyred
 * @createTime 2020/9/8 17:07
 **/
public class ConnectionPoolClient {

    public static void main(String[] args) {
        ConnectionPool pool = new ConnectionPool();
        // 得到连接
        Connection connection = pool.getConnection();

        // TODO

        // 关闭
        pool.release(connection);
    }
}

举个例子 (String 类)

public class StringFlyweight {

    public static void main(String[] args) {

        String s1 = "hello";
        String s2 = "he" + "llo";
        String s3 = "he";
        String s4 = "llo";
        String s5 = s3 + s4;

        //  true, JDK只对常量的加法做了优化处理,但是没有对定义常量的变量进行处理
        System.out.println(s1 == s2);
        // false, 这里  s5 是由s3变量加上s4变量得到的,所以,s5不等于 s1
        System.out.println(s1 == s5);
    }

}

举个例子(Integer 类)

public class IntegerValueOfFlyweight {

    /**
     *  以下是Integer.valueOf的源码
     * public static Integer valueOf(int i) {
     *       IntegerCache.low = -128;
     *       IntegerCache.high = 127
     *     if (i >= IntegerCache.low && i <= IntegerCache.high)
     *         return IntegerCache.cache[i + (-IntegerCache.low)];
     *     return new Integer(i);
     * }
     * @param args
     */
    public static void main(String[] args) {
        Integer i1 = 127;
        Integer i2 = Integer.valueOf(127);
        
        Integer i3 = 128;
        Integer i4 = Integer.valueOf(128);
        // true
        System.out.println(i1 == i2);
        // false
        System.out.println(i3 == i4);
    }
}

总结:

  • 在不了解享元模式的情况下,会出现很多的疑惑,例如Integer,Long … 面试一问一个懵
  • 使用享元模式,能给系统带来很高性能的提升,如果说到现在我们连接数据库还是用的手动开关 JDBC的方式,那么我们的系统肯定达不到高性能的水平。所以,在某些特定的场景下,如果对象创建销毁特别的消耗性能,那么直接采用享元模式来对齐缓存对象,要使用的时候就直接能获取到。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值