千家信息网

设计模式(创建型)之单例模式

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,单例模式的目的就是要控制特定的类只产生一个对象,当然也允许在一定情况下灵活的改变对象的个数。怎么来实现单例模式呢?一个类的对象的产生是由类构造函数来完成的,如果想限制对象的产生,一个办法就是:1,将构
千家信息网最后更新 2026年11月01日设计模式(创建型)之单例模式

单例模式的目的就是要控制特定的类只产生一个对象,当然也允许在一定情况下灵活的改变对象的个数。

怎么来实现单例模式呢?

一个类的对象的产生是由类构造函数来完成的,如果想限制对象的产生,一个办法就是:

1,将构造函数变为私有的(至少是受保护的),使得外面的类不能通过引用来产生对象;

2,同时为了保证类的可用性,就必须提供一个自己的对象以及访问这个对象的静态方法。

单例模式可分为有状态的和无状态的。

有状态的单例对象一般也是可变的单例对象,多个单态对象在一起就可以作为一个状态仓库一样向外提供服务。

没有状态的单例对象也就是不变单例对象,仅用做提供工具函数。

UML类图:

实现:

java:

一、饿汉式:

singleton1.java:

/*
* 创建人:颜超
* 创建时间:2013-6-26
* 文件名:singleton1.java
* 创建型设计模式
* 单例(singleton)
* 饿汉式
*/
public class Singleton1 {
//在自己内部定义自己一个实例
//注意这是private 只供内部调用
private static Singleton1 instance = new Singleton1();
//将构造函数设置为私有
private Singleton1(){
System.out.println("new an instance!");
}
//静态工厂方法,提供了一个供外部访问得到对象的静态方法
public static Singleton1 getInstance(){
return instance;
}
public static void main(String[] args) {
Singleton1.getInstance();
}
}

二、懒汉式:

singleton2.java:

/*
* 创建人:颜超
* 创建时间:2013-6-26
* 文件名:singleton2.java
* 创建型设计模式
* 单例(singleton)
* 懒汉式
*/
public class Singleton2 {
private static Singleton2 instance = null;
private Singleton2(){
System.out.println("new an instance!");
}
//对静态工厂方法进行了同步处理,原因很明显--为了防止多线程环境中产生多个实例
//将类对自己的实例化延迟到第一次被引用的时候。而在"饿汉式"则是在类被加载的时候实例化,这样多次加载会造成多次实例化
public static synchronized Singleton2 getInstance(){
if (instance == null){
instance = new Singleton2();
}
return instance;
}
public static void main(String[] args) {
// Singleton1 s1 = new Singleton1();
Singleton2.getInstance();
}
}
三、

以上两种实现方式均失去了多态性,不允许被继承。还有另外一种灵活点的实现,将构造函数设置为受保护的,这样允许被继承产生子类。

singleton3.java:

import java.util.HashMap;

public class Singleton3 {
private static HashMap sinRegistry = new HashMap();
private static Singleton3 instance = new Singleton3();
protected Singleton3(){
System.out.println("Construction for Singleton3!");
}
public static Singleton3 getInstance(String name){
if (name == null){
name = "Singleton3";
}
if (sinRegistry.get(name) == null){
try{
sinRegistry.put(name, Class.forName(name).newInstance());
}catch(Exception e){
e.printStackTrace();
}
}
return (Singleton3)(sinRegistry.get(name));
}

public void test(){
System.out.println("get Class Success!");
}
}

class Singleton3Child1 extends Singleton3 {

public Singleton3Child1(){
System.out.println("Construction for Singleton3Child1!");
}
public static Singleton3Child1 getInstance(){
return (Singleton3Child1)Singleton3.getInstance("Singleton3Child1");
}
public void test(){
System.out.println("get Child1 Class Success!");
}
}

class Singleton3Child2 extends Singleton3 {

public Singleton3Child2(){
System.out.println("Construction for Singleton3Child2!");
}
public static Singleton3Child2 getInstance(){
return (Singleton3Child2)Singleton3.getInstance("Singleton3Child2");
}
public void test(){
System.out.println("get Child2 Class Success!");
}
}

testMain.java:

public class testMain {

/**
* @param args
*/
public static void main(String[] args) {
System.out.println("#########################");
Singleton3Child1 s3c1 = new Singleton3Child1();
Singleton3Child2 s3c2 = new Singleton3Child2();
// 因为hashmap的key值是唯一的,所以,下面的三部分一次只能显示一部分

System.out.println("#########################");
Singleton3Child1.getInstance(); //add Singleton3Child1 into hashmap
Singleton3Child2.getInstance(); //add Singleton3Child2 into hashmap
System.out.println("#########################");
Singleton3.getInstance("Singleton3Child1"); //add Singleton3Child1 into hashmap
Singleton3.getInstance("Singleton3Child2"); //add Singleton3Child2 into hashmap
System.out.println("#########################");
Singleton3Child1.getInstance("Singleton3Child1"); //add Singleton3Child1 into hashmap
Singleton3Child1.getInstance("Singleton3Child2"); //add Singleton3Child2 into hashmap
Singleton3Child2.getInstance("Singleton3Child1"); //add Singleton3Child1 into hashmap
Singleton3Child2.getInstance("Singleton3Child2"); //add Singleton3Child2 into hashmap

}

}

由于在 java 中子类的构造函数的范围不能比父类的小,所以可能存在不守规则的客户
程序使用其构造函数来产生实例,造成单例模式失效。

C++:

Singleton.cpp:

#include
using namespace std;

class Singleton{

public:
static Singleton* getInstance(){
if(instance == NULL){
cout << "There is no instance!!!" << endl;
instance = new Singleton();
}
return instance;
}
private:
Singleton(){
cout << "new an instance!!!" << endl;
}
static Singleton* instance;
};

// static variable "instance" can not initialized in class
Singleton* Singleton::instance = NULL;

int main() {
Singleton::getInstance();
return 0;
}

对象 函数 模式 实例 状态 方法 静态 设计模式 设计 创建人 多个 子类 就是 工厂 懒汉 文件 文件名 时候 时间 保护 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网加科技 湖北九亚互联网络科技有限公司 广州紫鲸互联网科技有限公司 湖南永感互联网科技有限公司 互联网科技行业发展 科技平台互联网 互联网最新的科技有限公司 互联网科技ppt模板 火传媒上海互联网科技 深圳艾佳互联网科技 互联网科技公司招聘 博兴的互联网电子科技公司 科技与互联网的利与弊 河南猎农互联网科技有限公司 米聚互联网科技南京有限公司排面 浙南科技城互联网大厦建设工程 合肥互联网科技公司公章图片 从那以后互联网科技有限公司 互联网科技包装股份有限公司上市 广州梦谷互联网科技有限公司领导 互联网的科技 互联网 科技公司 致骋互联网科技 凡科互联网科技 奇酷互联网络科技公司 融贸通互联网科技 济南和联互联网科技有限公司 深圳国际航运科技和互联网 苏州铭阳互联网科技有限公司 互联网科技大会大佬
0