泛型编程与设计新思维之二
设计新思维
将设计模式(design patterns)、泛型编程(generic programming)和面向对象编程(object-oriented programming)有机的结合起来,便形成了设计新思维。其中,设计模式是经过提炼的出色设计方法,对于很多情况下碰到的问题,它都是合理而可复用的解决方案;泛型编程是一种典范(paradigm),专注于将类型抽象化,形成功能需求方面的一个精细集合,并利用这些需求来实现算法,相同的算法可以运用于广泛的类型集中,所谓泛型,就是具有在多种数据类型上皆可操作的含意;最后同面象对象编程中的多态(polymorphism)和模板(templates)等技术相结合,便获得极高层次上的具有可复用性的泛型组件。泛型组件预先实现了设计模块,可以让用户指定类型和行为,从而形成合理的设计,主要特点是灵活、通用和易用。
policies和policy类,是一种重要的类设计技术,所谓policy,是用来定义一个类或类模板的接口,该接口由下列之一或全部组成:内部类型定义、成员函数和成员变量。基于policy的类由许多小型类(称为policies)组成,每一个这样的小型类只负责单纯如行为或结构的某一方面。Policies机制由模板和多重继承组成,它们可以互相混合搭配,从而形成设计戎的多样性,通过plicy类,不但可以定制行为,也可以定制结构。
下面简单举例说明泛化思维和面向对象思维在部分设计模式中的运用。
Singletons设计模式泛化实现
Singleton模式是一种保证一个对象(class)只有一个实体,并为它提供一个全局访问点。Singleton是一种经过改进的全局变量,既在程序中只能有唯一实体的类型,它的重点主要集中在产生和管理一个独立对象上,而且不允许产生另一个这样的对象。
先让我们看看一般的C++实现的基本手法,下面是实现源码:
// Singleton.h文件中
class Singleton
{
public:
static Singleton& Instance()
{
if(!pInstance_){
if(destroyed_){ // 引用是否已经失效
OnDeadReference();
}
else {
Create(); // 第一次时创建实例
}
}
return *pInstance_;
}
private:
Singleton(); // 禁止默认构造
Singleton(const Singleton&); // 禁止拷贝构造
Singleton& operator= (const Singleton&);// 禁止赋值操作
static void Create() // 传加创建的实例引用
{
static Singleton theInstance;
pInstance_ = &theInstance;
}
static void OnDeadReference()
{
throw std::runtime_error(“ 实例被不正当消毁”);
}
virtual ~Singleton()
{
pInstance- = 0;
destroyed_ = true;
}
static Singleton *pInstance_;
static bool destroyed_;
}
// Singleton.cpp中静态成员变量初始化
Singleton* Singleton::pInstance_ = 0;
Bool Singleton::destroyed_ = false;
如上所示,Singleton模式实现中只有一个public成员Instance()用来第一次使用时创建单一实例,当第二次使用时静态变量将已经被设定好,不会再次创建实例。还将默认构造函数、拷贝构造函数和赋值操作符放在private中,目地是不让用户使用它们。另外,为避免实例意外消毁后再实例化情况,加入静态布尔变量destroy_来进行判断是否出错,从而达到稳定性。
从上面一般实现可以看出Singleton模式实现主要在于创建(Creation)方面和生存期(Lifetime)方面,既可以通过各种方法来创建Singleton。Creation必然能创建和摧毁对象,必然要开放这两个相应函数,将创建作为独立策略分离开来是必需的,这样你就可以创建多态对象了,所以泛化Singleton并不拥有Creator对象,它被放在CreationPolicy<T>类模板之中。生命期是指要遵循C++规则,后创建都先摧毁,负责程序生命期某一时刻摧毁Singleton对象。
下面是一个简单的泛化Singleton模式的实现(不考虑线程因素)
template
<
class T,
template<class> calss CreationPolicy = CreateUsingNew,
template<class> class LifetimePolicy=DefaultLifetime,
>
classs SingletonHolder
{
public:
static T& Instance()
{
if(!pInstance_)
{
if(destroyed_)
{
LifetimePolicy<T>::OnDeadReference();
destroyed_ = false;
}
pInstance_ = CreationPolicy<T>::Create();
LifetimePolicy<T>::SchedultCall(&DestorySingleton);
}
return *pInstance_;
}
private:
static void DestroySinleton()
{
assert(!destroyed_);
CreationPlicy<T>::Destroy(pInstance_);
pInstance_ = 0;
destroyed_ = true;
}
SingletonHolder();
SingletonHolder (const SingletonHolder &);
SingletonHolder & operator= (const SingletonHolder &);
Static T* pInstance_;
Static bool destroyed_;
};
Instance()是SingletonHolder开放的唯一一个public函数,它在CreationPolicy、LifetimePolicy中打造了一层外壳。其中模板参数类型T,接收类名,既需要进行Singleton的类。模板参数内的类模板缺省参数CreateUsingNew是指通过new操作符和默认构造函数来产生对象,DefaultLifetime是通过C++规则来管理生命期。LifetimePolicy<T>中有二个成员函数,ScheduleDestrution()函数接受一个函数指针,指向析构操作的实际执行函数,如上面DestorySingleton析构函数;OnDeadReference()函数同上面一般C++中同名函数相同,是负责发现失效实例来抛出异常的。CreationPlicy<T>中的Create()和Destroy()两函数是用来创建并摧毁具体对象的。
下面是上述泛化Singleton模式实现的使用:
1、应用一
class A{};
typedef SingletonHolder<A, CreateUsingNew> SingleA;
2、应用二
class A{};
class Derived : public A {};
template<class T> struct MyCreator : public CreateUsingNew<T>
{
static T* Create()
{
return new Derived;
}
static void Destroy(T* pInstance)
{
delete pInstance;
}
}
typedef SingletonHolder<A,MyCreator> SingleA;
通过上面示例可以看出, SingletonHolder采用基于plicy设计实现,它将Singleton对象分解为数个policies,模板参数类中CreationPolicy和LifetimePolicy相当于二个policies封装体。利用它们可以协助制作出使用者自定义的Singleton对象,同时还预留了调整和扩展的空间。由此而得,泛型组件(generic components),是一种可复用的设计模板,结合了模板和模式,是C++中创造可扩充设计的新方法,提供了从设计到代码的简易过渡,帮助我们编写清晰、灵活、高度可复用的代码。
参考文献
C++ Primer(第三版) --- 潘爱民等译
Effective C++(第二版) --- 侯捷译
More Effective C++ --- 侯捷译
Exceptional C++ --- 卓小涛译
More Exceptional C++ --- 於春景译
深度探索C++对象模型 --- 侯捷译
泛型编程与STL --- 侯捷译
C++ STL程序员开发指南 --- 彭木根等箸
设计模式:可复用面向对象软件的元素 --- 李英军等译
C++设计新思维 --- 侯捷等译
联系方式:
地址:陕西省西安市劳动路90号院(台板厂家属院)六单元
邮编:710082
EMAIL:jingzhou_xu@163.net
未来工作室(Future Studio)