妙解设计模式之单例模式

单例模式的概念

单例模式(Singleton Pattern)是一种设计模式,用于确保一个类在整个程序运行过程中只有一个实例,并提供一个全局访问点来获取该实例。这种模式在需要控制资源使用(如数据库连接、文件访问)或者需要全局共享状态的场景中非常有用。

单例模式的具体概念

  1. 唯一实例
    • 单例模式确保一个类只有一个实例存在。任何时候,任何地方访问这个类时,都能获得相同的实例。这就避免了多个实例带来的资源浪费和状态不一致问题。
  2. 全局访问点
    • 单例模式提供一个全局访问点,可以通过这个访问点获取唯一的实例。通常是通过一个静态方法来实现。

单例模式的实现要点

  1. 私有构造函数
    • 将类的构造函数定义为私有,防止外部类直接通过new关键字创建多个实例。
  2. 静态变量
    • 使用一个私有的静态变量来保存类的唯一实例。
  3. 静态方法
    • 提供一个公共的静态方法,用于返回唯一的实例。在这个方法中,通常会检查实例是否已经存在,如果不存在则创建新的实例,如果存在则直接返回。

生活中的例子

单例模式,用来确保一个类只有一个实例,并且提供一个全局访问点来访问这个实例。想象一下你家里的冰箱。

  1. 冰箱只有一个:家里通常只有一个冰箱,不需要多个冰箱来储存食物。单例模式就像这个冰箱,确保只有一个实例存在。

  2. 全家人都能用:家里所有人都可以打开冰箱拿食物。单例模式也一样,程序中的所有部分都可以访问这个唯一的实例。

编程中的例子

下面是用Java实现单例模式的例子。我们来创建一个名为Singleton的类,确保这个类只能有一个实例,并且全局可访问。

public class Singleton {
    // 私有静态实例变量,用来存储唯一的实例
    private static Singleton instance;

    // 私有化构造函数,防止外部类创建实例
    private Singleton() {}

    // 公共的静态方法,返回唯一的实例
    public static Singleton getInstance() {
        // 第一次调用时创建实例,以后调用直接返回现有实例
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    // 其他方法
    public void showMessage() {
        System.out.println("Hello, I am a Singleton!");
    }
}

class Main {
    public static void main(String[] args) {
        // 尝试获取Singleton实例
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();

        // 比较两个实例,看看它们是否是同一个
        System.out.println(singleton1 == singleton2); // 这会打印 true

        // 调用实例的方法
        singleton1.showMessage(); // 这会打印 "Hello, I am a Singleton!"
    }
}

软件工程中的实际应用

配置管理

场景

  • 在一个大型应用程序中,配置参数可能需要被多个模块访问和修改。

实践

  • 使用单例模式确保配置管理类只有一个实例,从而保证所有模块访问的都是同一个配置实例,避免配置不一致的问题。
public class ConfigurationManager {
    private static ConfigurationManager instance;
    private Properties configProperties;

    private ConfigurationManager() {
        configProperties = new Properties();
        // 加载配置文件
        // configProperties.load(...);
    }

    public static synchronized ConfigurationManager getInstance() {
        if (instance == null) {
            instance = new ConfigurationManager();
        }
        return instance;
    }

    public String getProperty(String key) {
        return configProperties.getProperty(key);
    }

    public void setProperty(String key, String value) {
        configProperties.setProperty(key, value);
    }
}

日志管理

场景

  • 应用程序需要记录日志,并且这些日志信息需要集中管理和输出。

实践

  • 使用单例模式确保日志管理类只有一个实例,所有日志记录都通过这个实例进行处理,避免多个日志实例造成的混乱。
public class Logger {
    private static Logger instance;

    private Logger() {
        // 初始化日志配置
    }

    public static Logger getInstance() {
        if (instance == null) {
            instance = new Logger();
        }
        return instance;
    }

    public void log(String message) {
        // 记录日志信息
        System.out.println(message);
    }
}

数据库连接池

场景

  • 数据库连接是昂贵的资源,频繁创建和销毁连接会导致性能问题。

实践

  • 使用单例模式创建数据库连接池,确保全局只有一个连接池实例,从而管理和复用数据库连接,提升性能。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class DatabaseConnectionPool {
    private static DatabaseConnectionPool instance;
    private List<Connection> connectionPool;

    private DatabaseConnectionPool() {
        connectionPool = new ArrayList<>();
        // 初始化连接池
        for (int i = 0; i < 10; i++) {
            connectionPool.add(createNewConnection());
        }
    }

    public static DatabaseConnectionPool getInstance() {
        if (instance == null) {
            instance = new DatabaseConnectionPool();
        }
        return instance;
    }

    private Connection createNewConnection() {
        try {
            return DriverManager.getConnection("jdbc:yourdatabaseurl", "user", "password");
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    public Connection getConnection() {
        if (connectionPool.isEmpty()) {
            return createNewConnection();
        } else {
            return connectionPool.remove(connectionPool.size() - 1);
        }
    }

    public void releaseConnection(Connection connection) {
        connectionPool.add(connection);
    }
}

缓存管理

场景

  • 在应用程序中,某些数据需要频繁访问,但计算或获取这些数据的成本很高。

实践

  • 使用单例模式创建一个缓存管理类,确保全局只有一个缓存实例,从而共享缓存数据,提升访问速度。
import java.util.HashMap;
import java.util.Map;

public class CacheManager {
    private static CacheManager instance;
    private Map<String, Object> cache;

    private CacheManager() {
        cache = new HashMap<>();
    }

    public static CacheManager getInstance() {
        if (instance == null) {
            instance = new CacheManager();
        }
        return instance;
    }

    public void put(String key, Object value) {
        cache.put(key, value);
    }

    public Object get(String key) {
        return cache.get(key);
    }

    public void remove(String key) {
        cache.remove(key);
    }
}

线程池管理

场景

  • 在并发编程中,创建和销毁线程是开销很大的操作。

实践

  • 使用单例模式创建一个线程池管理类,确保全局只有一个线程池实例,从而管理和复用线程,提升并发性能。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolManager {
    private static ThreadPoolManager instance;
    private ExecutorService executorService;

    private ThreadPoolManager() {
        executorService = Executors.newFixedThreadPool(10);
    }

    public static ThreadPoolManager getInstance() {
        if (instance == null) {
            instance = new ThreadPoolManager();
        }
        return instance;
    }

    public void execute(Runnable task) {
        executorService.execute(task);
    }

    public void shutdown() {
        executorService.shutdown();
    }
}
  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑的像个child

好人一生平安,先磕为敬

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值