1
.
Singleton
模式简介
Singleton 是 GOF 圣经中最简单的一个模式了,主要用于创建在系统中具有唯一实例又需要到处使用的类,实现起来非常简单。
Singleton 是 GOF 圣经中最简单的一个模式了,主要用于创建在系统中具有唯一实例又需要到处使用的类,实现起来非常简单。
using namespace std ;
class my_singleton
{
public :
static my_singleton * instance ();
void show_my_life ();
protected :
my_singleton ();
private :
static my_singleton * m_instance ;
};
my_singleton * my_singleton :: m_instance = NULL
my_singleton * my_singleton :: instance ()
{
if ( m_instance == NULL )
{
m_instance = new my_singleton ;
}
return m_instance ;
}
void my_singleton :: show_my_life ()
{
cout << "i'm living at " << ( void *) this << endl ;
}
my_singleton :: my_singleton (){}
my_singleton ::~ my_singleton ()
{
if ( m_instance != NULL )
{
delete m_instance ;
m_instance = NULL ;
}
}
int main ()
{
my_singleton :: instance ()-> show_my_life ();
return 0 ;
};
2 . ACE 中如何使用 Singleton
如上例中, singleton 代码非常简单,也很成熟,但是如果在一个系统中有很多地方都需要使用 singleton 模式,则需要写相当多的类似重复代码,枯燥且低效,如果碰巧使用了 ACE ,那么使用 ACE 封装的 singleton ,则可以更加简单:
class normal_test
{
friend class ACE_Singleton< normal_test , ACE_Null_Mutex> ;
void show_my_life ();
private :
normal_test ();
};
normal_test :: normal_test (){}
typedef ACE_Singleton< normal_test , ACE_Null_Mutex> NORMAL_TEST ;
void normal_test :: show_my_life ()
{
cout << "i'm living at " << ( void *) this << endl ;
}
int ACE_TMAIN ( int argc , ACE_TCHAR * argv [])
{
my_singleton :: instance ()-> show_my_life ();
NORMAL_TEST :: instance ()-> show_my_life ();
};
如上所示,获得了以下优点:
1 . 代码减少了一半还多,变得更加简洁、清晰,
2 . 使用了 double - check 技术,免费的获得了线程安全。
3 . 没有使用继承、虚函数,性能、效率不会受影响。
3 . ACE 的 singleton 是如何实现的?
以下代码节选自 ACE 的源代码,为清晰起见,去除了一些无关的宏开关
a ) 以下是 ACE_Singleton 的定义:
template < class TYPE , class ACE_LOCK>
class ACE_Singleton : public ACE_Cleanup
{
public :
/// Global access point to the Singleton.
static TYPE * instance ( void );
/// Cleanup method, used by <ace_cleanup_destroyer> to destroy the
/// ACE_Singleton.
virtual void cleanup ( void * param = 0 );
/// Dump the state of the object.
static void dump ( void );
protected :
/// Default constructor.
ACE_Singleton ( void );
/// Contained instance.
TYPE instance_ ;
/// Pointer to the Singleton (ACE_Cleanup) instance.
static ACE_Singleton< TYPE , ACE_LOCK> * singleton_ ;
/// Get pointer to the Singleton instance.
static ACE_Singleton< TYPE , ACE_LOCK> *& instance_i ( void );
};
b ) 看一下 instance 的实现:
template < class TYPE , class ACE_LOCK> TYPE *
ACE_Singleton< TYPE , ACE_LOCK> :: instance ( void )
{
ACE_TRACE ( "ACE_Singleton<TYPE, ACE_LOCK>::instance" );
ACE_Singleton< TYPE , ACE_LOCK> *& singleton =
ACE_Singleton< TYPE , ACE_LOCK> :: instance_i ();
// Perform the Double-Check pattern...
if ( singleton == 0 )
{
static ACE_LOCK * lock = 0 ;
if ( ACE_Object_Manager :: get_singleton_lock ( lock ) != 0 )
// Failed to acquire the lock!
return 0 ;
ACE_GUARD_RETURN
if ( singleton == 0 )
{
ACE_NEW_RETURN ( singleton , ( ACE_Singleton< TYPE , ACE_LOCK> ), 0 );
// Register for destruction with ACE_Object_Manager.
ACE_Object_Manager :: at_exit ( singleton );
}
}
return & singleton -> instance_ ;
}
说明: double - check 技术主要是解决线程安全问题,避免在初始化时多线程重入,导致 instance 被实例化两次。
c ) 再看一下 instance_i 的实现:
template < class TYPE , class ACE_LOCK> ACE_Singleton< TYPE , ACE_LOCK> *&
ACE_Singleton< TYPE , ACE_LOCK> :: instance_i ( void )
{
static ACE_Singleton< TYPE , ACE_LOCK> * singleton_ = 0 ;
return singleton_ ;
}
4 . 题外话:
ACE_Singleton 较好的封装了 Singleton 模式,对于现代应用系统,一般而言会有相当多的地方需要使用 Singleton 模式,如线程池、内存池、数据连接池等,通过 ACE_Singleton 类,可以达到简化代码的目的,同时解决 GOF 圣经中未提的线程安全的问题。后续我会继续就 ACE 中的使用的设计模式提出来与大家进行探讨、学习。