zoukankan      html  css  js  c++  java
  • 设计模式(1)-单例模式

    摘要

    • 简单介绍了什么是单例模式
    • 介绍了懒汉式和饿汉式的实现
    • 分析了单例模式出现的场景
    • 用数据库连接池的例子演示了单例模式

    概念

    确保一个类只能有一个实例,并提供一个全局访问点来访问这个实例。

    要点

    • 某一个类只能创建一个一个实例
    • 必须类内部自行创建这个实例
    • 必须向系统提供这个实例,也就是提供一个全局访问点

    优点

    • 保证内存中只有一个实例,减小内存开销
    • 避免对资源的多重占用
    • 设置全局访问点,优化和共享资源的访问

    缺点

    • 扩展困难,如果要扩展除了修改原来的代码没有第二种开发途径,违背开闭原则
    • 单例模式的功能通常都写在一个类中,如果功能设计不合理,则很容易违反单一职责原则
    • 并发测试中不好debug

    场景

    对于Java来说,单例模式的落地就是在JVM中只存在单一实例。

    • 需要频繁创建一些类,使用单例可以降低系统的内存压力,减少GC
    • 某类只要求生成一个对象的时候,比如一个班中的班长,一个人的身份证
    • 某些类创建实例时占用资源较多,或实例化耗时较长,且经常使用。
    • 某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。
    • 频繁访问数据库或文件的对象。
    • 对于一些控制硬件级别的操作,或者从系统上来讲应当是单一控制逻辑的操作,如果有多个实例,则系统会完全乱套。
    • 当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如 Web 中的配置对象、数据库的连接池等。

    实现方式

    懒汉式

    每次访问都需要同步,会影响性能,且消耗更多的资源,这就是懒汉式的缺点

    public class Lazy{
        private static volatile Lazy instance;
        private Lazy(){}
        //DLC
        public static getInstance(){
            if(instance==null){
                synchronized(Lazy.class){
                    if(instance==null){
                        instance = new Lazy();
                    }
                }
            }
            return instance;
        }
    }
    

    饿汉式

    public class Hungry{
        private static final Hungry instance = new Hungry();
        private Hungry() {}
        public static Hungry getInstance() {
            return instance;
        }
    }
    

    实例

    获取数据库连接池

    public final class DbConnectConfig {
     
        private static ComboPooledDataSource dataSource;
     
        static {
            dataSource = new ComboPooledDataSource();
            dataSource.setUser(JdbcPropertiesConfig.getUSERNAME());
            dataSource.setPassword(JdbcPropertiesConfig.getPASSWORD());
            dataSource.setJdbcUrl(JdbcPropertiesConfig.getDATABASEURL());
            dataSource.setDriverClass(xxxxxxx);
            //初始化连接数
            dataSource.setInitialPoolSize(xxx.getINITIALPOOLSIZE());
            //最小连接数
            dataSource.setMinPoolSize(xxx.getMINPOOLSIZE());
            //最大连接数
            dataSource.setMaxPoolSize(xxx.getMAXPOOLSIZE());
            //最长等待时间
            dataSource.setMaxStatements(xxx.getMAXSTATEMENTS());
            //最大空闲时间,单位毫秒
            dataSource.setMaxIdleTime(xxx.getMAXIDLETIME());
            dataSource.setCheckoutTimeout(5000);
            dataSource.setUnreturnedConnectionTimeout(20);
        }
     
     	//这里使用DLC好一点
        public synchronized static final Connection getConnection() {
            Connection conn = null;
            try {
                conn = dataSource.getConnection();
            } catch (SQLException e) {
                System.out.println("
    数据库连接异常");
                e.printStackTrace();
            }
            return conn;
        }
    }
    

    参考

    [1].单例模式设置mysql数据库连接池

    [2].单例模式(单例设计模式)详解

    [3].学习笔记 : Java设计模式之Singleton Pattern

    本文作者: Both Savage

    本文链接: https://bothsavage.github.io/2020/12/30/设计模式/设计模式(1)-单例模式/

    版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

  • 相关阅读:
    12
    11
    10
    9
    8
    6. iOS APP 设计规范大全
    4. iOS中常用演示方法以及利弊
    我要写一篇动态计算tableView-cell高度的随笔
    doclever 5.5.1 安装及升级【原创】
    SPARROW-JS 从0开始写 0依赖,原生JS框架
  • 原文地址:https://www.cnblogs.com/simon-idea/p/14233351.html
Copyright © 2011-2022 走看看