设计模式 笔记 单例模式 Singleton
//---------------------------15/04/09----------------------------
//Singleton 单例模式-----对象创建型模式
/*
1:意图:
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2:动机
3:适用性:
1>当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2>当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码
就能使用一个扩展的实例时。
4:结构:
Singleton:
static Instance()
{return uniqueInstance}
SingletonOperation()
GetSingletonData()
static uniqueInstance
singletonData
5:参与者:
Singleton:
1>定义一个Instance操作,允许客户访问它的唯一实例。Instance时一个类操作:
就是C++中的一个静态成员函数。
2>可能负责创建它自己的唯一实例。
6:协作:
客户只能通过Singleton的Instance操作访问一个Singleton实例。
7:效果:
1>对唯一实例的受控访问:
因为Singleton类封装它的唯一实例,所以它可以严格的控制客户怎样以及何时访问它。
2>缩小名空间:
Singleton模式是对全局变量的一种改进。它避免了那些存储唯一实例的全局变量污染名空间。
3>允许对操作和表示的精华:
Singleton类可以有子类,而且用这个扩展类的实例来配置一个应用是很容易的。
可以用需要的类的实例在运行时刻配置应用。<未知标记>
4>允许可变数目的实例:
通过改变允许访问Singleton实例的操作,来实现控制应用所使用的实例的数目。
5>比类操作更灵活:
另一种封装单件功能的方式是使用类操作:就是静态成员函数。
8:实现:
1>保证一个唯一的实例:
就是使用一个类操作来获得实例: */
//这样实现是有线程安全问题的
class Singleton
{
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
Singleton* Singleton::_instance =0;
Singleton* Singleton::Instance()
{
if(_instance == 0)
_instance =new Singleton;
return _instance;
}
// 2>创建Singleton类的子类:
// 使用单件注册表:
class Singleton
{
public:
static void Register(constchar* name, Singleton*);
static Singleton* Instance();
protected:
static Singleton* Lookup(constchar* name);
private:
static Singleton* _instance;
static map<char*,Singleton*> _registry;//感觉map更好用
};
Singleton* Singleton::Instance()
{
if(_instance == 0)
{
const char* singletonName = getenv("SINGLETON");
_instance = Lookup(singletonName);
}
return _instance;
}
//子类注册:在构造函数中注册自己
MySingleton::MySingleton()
{
Singleton::Register("MySingleton",this);
}
//这个构造函数只有被调用了,注册表中才有MySingleton,所以要在实现文件中定义一个静态实例
static MySingleton theSingleton;
// 9:代码示例:
class MazeFactory
{
public:
static MazeFactory* Instance();
static void Register(constchar* name, MazeFactory*);
protected:
MazeFactory();
static MazeFactory* Lookup(constchar* name);
private:
static MazeFactory* _instance;
static map<char*,MazeFactory*> _registry;
};
MazeFactory* MazeFactory::_instance =0;
MazeFactory* MazeFactory::Instance()
{
if(_instance = 0)
{
const char* mazeName = getenv("MAZESTYLE");
_instance = Lookup(mazeName);
}
return _instance;
}
void MazeFactory::Register(constchar* name, MazeFactory* fac)
{
_registry.insert(std::make_pair(name,fac));
}
MazeFactory* MazeFactory::Lookup(constchar* name)
{
map<char*,MazeFactory*>::iterator it=_registry.find(name);
if(it != _registry.end())
return it->second;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫