设计模式之单例模式

Posted shhome

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之单例模式相关的知识,希望对你有一定的参考价值。

设计模式(Design pattern),提供了在软件开发过程中面临的一些问题的最佳解决方案,是开发者

必修的一门课程。主要分创建型模式、结构型模式和行为型模式。其中接下来我们要写的是单例模式

,属于创建型模式。

文章目录

0x01 简 介

0x02 前提概要

0x03 单例模式之饱汉式

0x04 单例模式之饿汉式

0x05 单例模式之双锁判断

0x06 单例模式之静态内部

0x07 单例模式之枚举类

0x08 总 结

*0x01 简 介*

> *单例模式,顾名思义就是只有一个实例,并且她自己负责创建自己的对象,这个类提供了一种访问其
唯一的对象的方式,可以直接访问,不需要实例化该类的对象。下面我们来看下有哪几种实现方式吧。*

*0x02 前提概要*

/**
	warning    这里我为了维持自己的代码风格,进行快速开发,将导入外部头文件 global.h
*/

/**
	copyright	Copyright (c) 2020 怪小子
	contact	https://www.cnblogs.com/shHome/
	version	v1.0
	file		global.h
	
	rief		Project global header file definition.
	details	This header file does not depend on any platform environment or language environment. It is 
				responsible for declaring some common interfaces or global methods.

	include	nothing
	
	author		怪小子
	date		2020/11/1
	
amespace	nothing
	
	attention	matters needing attention
	par		Modify log
	<table>
	<tr><th>Date        <th>Version  	<th>Author    	<th>Description
	<tr><td>2020/11/1  	<td>1.0      	<td>26047 			<td>Create initial version
	</table>

*/

/**
	rief  The header file precompiles the macro to prevent repeated inclusion.
			Refer to document name for specific definition form.
	eg		_<ProjectName>_<ModuleNmae>_<FileName>_H_.
*/
#ifndef _DESIGNPATTERNS__GLOBAL_H_
#define _DESIGNPATTERNS__GLOBAL_H_

#if !defined(GLOBAL_QUICK_DEFINITION)
#	if !defined(interface_attribute_inline)
/**
	rief	inline Macro definition.
	li		Extending to inline keywords to improve code execution efficiency.
	li		In this way, it is easier to reconstruct the existing framework without affecting its stability.

	code
		interface_attribute_inline
			void setInterval(const Interval<int>& val) { m_interval = val; }
	endcode
*/
#		define interface_attribute_inline  inline
#	endif // !interface_attribute_inline

#	if !defined(interface_attribute_deprecated)
/**
	rief	__declspec(deprecated) Macro definition.
	li		Extend to obsolete keywords to remind users to use secure interfaces.
	li		In this way, it is easier to reconstruct the existing framework without affecting its stability.

	code
		// Remind that the interface is not secure because the setInterval_s interface should be used.
		interface_attribute_deprecated
			void setInterval(const Interval<int>& val) { m_interval = val; }

		interface_attribute_inline
			void setInterval_s(const Interval<unsigned int>& val) { m_interval = val; }
	endcode
*/
#		define interface_attribute_deprecated  __declspec(deprecated)
#	endif // !interface_attribute_deprecated

#	if !defined(STATEMENT_CLASS_ALIAS_NAME)
/**
	rief	Quickly define the alias of data type, which makes it convenient for developers to import target
			data types when developing independent functional modules.
*/
#		define STATEMENT_CLASS_ALIAS_NAME(classname,aligname)  typedef classname aligname
#	endif // !STATEMENT_CLASS_ALIAS_NAME
#endif // !GLOBAL_QUICK_DEFINITION
#endif  // !_DESIGNPATTERNS__GLOBAL_H_

/**
	warning    为了使我的代码不重复,我将声明一个测试父类,导入 basic.h
*/

/**
	copyright 	Copyright (c) 2020 Strange boy
	contact   	https://www.cnblogs.com/shHome/
	version   	v1.0
	file      	basic.h
	
	rief     	The parent class of all test class functions.
	details   	This class will replace the functional interface of all test classes.

	include   	std::memory,std::string
	
	author    	Strange boy
	date      	2020/11/1
	
amespace 	nothing
	
	attention 	matters needing attention
	par       	Modify log
	<table>
	<tr><th>Date        <th>Version  	<th>Author    	<th>Description
	<tr><td>2020/11/1  	<td>1.0      	<td>26047 			<td>Create initial version
	</table>

*/

/**
	rief  The header file precompiles the macro to prevent repeated inclusion.
			Refer to document name for specific definition form.
	eg		_<ProjectName>_<ModuleNmae>_<FileName>_H_.
*/
#ifndef _DESIGNPATTERNS__BASIC_H_
#define _DESIGNPATTERNS__BASIC_H_

#include "global.h"
#include <string>
#include <memory>

class BasicClass 
{
protected:
	BasicClass(const char* __name) : _classNameString(__name) { }
public:
	/**
		rief	Get the class name of the object.
		
eturn class name.
	*/
	virtual interface_attribute_inline 
		std::string getClassNameString() const { return _classNameString; }
protected:
	const std::string _classNameString;
};
#endif  // !_DESIGNPATTERNS__BASIC_H_

*0x03 单例模式之饱汉式*

特点
*线程安全,调用效率不高,但是能延时加载*
/**
	copyright 	Copyright (c) 2020 Strange boy
	contact   	https://www.cnblogs.com/shHome/
	version   	v1.0
	file      	Satiety.h
	
	rief     	Singleton pattern in design pattern -- test class declaration in Chinese style
	details   	sa class Satiety

	include   	std::memory,std::string
	
	author    	Strange boy
	date      	2020/11/1
	
amespace 	designer_mode
	
	attention 	matters needing attention
	par       	Modify log
	<table>
	<tr><th>Date        <th>Version  	<th>Author    	<th>Description
	<tr><td>2020/11/1  	<td>1.0      	<td>26047 			<td>Create initial version
	</table>

*/

/**
	rief  The header file precompiles the macro to prevent repeated inclusion.
			Refer to document name for specific definition form.
	eg		_<ProjectName>_<ModuleNmae>_<FileName>_H_.
*/
#ifndef _SINGLETONMODE__SATIETY_H_
#define _SINGLETONMODE__SATIETY_H_

/** 
	rief	Fullness: slightly different from starvation, fullness initializes the static class variable to
			nullptr in the construction method, which is created only when the instance reference object of
			the unique class is to be obtained.

	li NAMESPACE_SATIETY 		    : Scope macro definition declaration identity macro.
	li START_NAMESPACE_SATIETY	    : Expand scope macro.
	li END_NAMESPACE_SATIETY	    : End scope macro.
*/
#if !defined(NAMESPACE_SATIETY)
#	define NAMESPACE_SATIETY
#	define START_NAMESPACE_SATIETY	namespace designer_mode{
#	define END_NAMESPACE_SATIETY	};
#endif

#include "../../DesignPatterns/basic.h"

START_NAMESPACE_SATIETY

/**
	rief 	The starved Chinese test code of singleton mode.
			The core code of this method is to privatize the construction method so that external
			variables of this class cannot be created at will. The "static hungryman * getobject()"
			interface must be used to obtain the instance reference object of this class. Keep it
			one when used.
			Lazy, as the name implies, instances are created only when they are used, "relatively lazy".
			Only when they are used can instances be checked to see if they exist. If they exist, they
			return and if they are not, they are created. There are two ways to write thread safety and
			thread insecurity. The difference is the synchronized keyword.

	ug    Before using this class, you must_ Mode:: satisfaction initialization. I did not create it 
			for the sake of code simplicity Satiety.cpp File, this operation should be placed in the 
			Satiety.cpp Implemented in.
			If this operation is omitted, code errors such as unresolved will be thrown at compile time.
*/
class Satiety 
	: public BasicClass
{
protected:
	Satiety() :BasicClass("Satiety") {}
public:
	/**
		rief Get object pointer of singleton mode.
		
eturn Return value not null is a valid object.
		see satiety*
	*/
	static Satiety* getObject() {

		if (!Satiety::_instanceObject) {

			Satiety::_instanceObject = new Satiety();
		}
		return Satiety::_instanceObject;
	}
private:
	static Satiety* _instanceObject;
};

END_NAMESPACE_SATIETY
#endif  // !_SINGLETONMODE__SATIETY_H_

*0x04 单例模式之饿汉式*

特点
*线程安全,调用效率高,但是不能延时加载*
/**
	copyright 	Copyright (c) 2020 Strange boy
	contact   	https://www.cnblogs.com/shHome/
	version   	v1.0
	file      	HungryMan.h

	rief     	Singleton pattern in design pattern -- test class declaration in Chinese style
	details   	sa class HungryMan

	include   	std::memory,std::string

	author    	Strange boy
	date      	2020/11/1
	
amespace 	designer_mode

	attention 	matters needing attention
	par       	Modify log
	<table>
	<tr><th>Date        <th>Version  	<th>Author    	<th>Description
	<tr><td>2020/11/1  	<td>1.0      	<td>26047 			<td>Create initial version
	</table>

*/

/**
	rief  The header file precompiles the macro to prevent repeated inclusion.
			Refer to document name for specific definition form.
	eg		_<ProjectName>_<ModuleNmae>_<FileName>_H_.
*/
#ifndef _SINGLETONMODE__HUNGRYMAN_H_
#define _SINGLETONMODE__HUNGRYMAN_H_

/**
	rief	Fullness: slightly different from starvation, fullness initializes the static class variable to
			nullptr in the construction method, which is created only when the instance reference object of
			the unique class is to be obtained.

	li NAMESPACE_SATIETY 		    : Scope macro definition declaration identity macro.
	li START_NAMESPACE_SATIETY	    : Expand scope macro.
	li END_NAMESPACE_SATIETY	    : End scope macro.
*/
#if !defined(NAMESPACE_HUNGRY_MAN)
#	define NAMESPACE_HUNGRY_MAN
#	define START_NAMESPACE_HUNGRY_MAN	namespace designer_mode{
#	define END_NAMESPACE_HUNGRY_MAN		};
#endif

#include "../../DesignPatterns/basic.h"

START_NAMESPACE_HUNGRY_MAN

/**
	rief 	The starved Chinese test code of singleton mode.
			The core code of this method is to privatize the construction method so that external
			variables of this class cannot be created at will. The "static hungryman * getobject()"
			interface must be used to obtain the instance reference object of this class. Keep it
			one when used.
			It‘s also well understood from the name of the hungry Chinese style, which is "more
			frequent". The instance has been built during initialization. Whether you use it or not,
			you need to build it first. The advantage is that there is no thread safety problem,
			and the disadvantage is that memory space is wasted.

	ug    Before using this class, you must_ Mode:: satisfaction initialization. I did not create it
			for the sake of code simplicity Satiety.cpp File, this operation should be placed in the
			Satiety.cpp Implemented in.
			If this operation is omitted, code errors such as unresolved will be thrown at compile time.
*/
class HungryMan
	: public BasicClass
{
protected:
	HungryMan() :BasicClass("HungryMan") {}
public:
	/**
		rief Get object pointer of singleton mode.
		
eturn Return value not null is a valid object.
	*/
	static HungryMan* getObject() { return _instanceObject; }
private:
	static HungryMan* _instanceObject;
};

END_NAMESPACE_HUNGRY_MAN
#endif  // !_SINGLETONMODE__HUNGRYMAN_H_



/**
	rief  cpp实现部分
*/
#include "HungryMan.h"

START_NAMESPACE_HUNGRY_MAN

/** Initialize instance object. */
HungryMan* HungryMan::_instanceObject = new HungryMan();

END_NAMESPACE_HUNGRY_MAN

*0x05 单例模式之双锁判断*

特点
*双重校验是懒汉式的升级版,通过加锁实现了线程安全,并同时具备延迟加载的机制*




















以上是关于设计模式之单例模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之单例模式

Java设计模式之单例模式

设计模式之单例模式以及简单代码实现

设计模式之单例设计模式

设计模式之单例模式

设计模式之单例模式