设计模式(2)-单例模式(Singleton) (二)

2014-11-24 11:48:38 · 作者: · 浏览: 1
->test;
i = Singleton::test;
s1->createInstance();

Singleton *s3 = new Singleton;
i = s3->test;

//Test2
qDebug()<test;//s1->test = 1
s2->test++;
qDebug()<test;//s1->test = 2
qDebug()<test;//s2->test = 2
Singleton *s4 = new Singleton;
qDebug()<test;//s4->test = 1
Singleton *s5 = new Singleton;
qDebug()<test;//s5->test = 1

s1->test++;
s4->test++;
qDebug()<test;//s1->test = 3
qDebug()<test;//s2->test = 3
qDebug()<test;//s3->test = 3
qDebug()<test;//s4->test = 3
qDebug()<test;//s5->test = 3

return 0;
}
#include
#include "singleton.h"

int main(void)
{
Singleton *s1 = Singleton::createInstance();
Singleton *s2 = Singleton::createInstance();

if(s1 == s2)
{
qDebug()<<"s1 , s2 are the same instance";
}


s1->setName("zhangsan");
qDebug()<getName();
qDebug()<getName();
s2->setName("lisi");
qDebug()<getName();
qDebug()<getName();

//Test1
int i;
i = s1->test;
i = Singleton::test;
s1->createInstance();

Singleton *s3 = new Singleton;
i = s3->test;

//Test2
qDebug()<test;//s1->test = 1
s2->test++;
qDebug()<test;//s1->test = 2
qDebug()<test;//s2->test = 2
Singleton *s4 = new Singleton;
qDebug()<test;//s4->test = 1
Singleton *s5 = new Singleton;
qDebug()<test;//s5->test = 1

s1->test++;
s4->test++;
qDebug()<test;//s1->test = 3
qDebug()<test;//s2->test = 3
qDebug()<test;//s3->test = 3
qDebug()<test;//s4->test = 3
qDebug()<test;//s5->test = 3

return 0;
}

【运行结果】

[html] view plaincopyprint construct
s1 , s2 are the same instance
"zhangsan"
"zhangsan"
"lisi"
"lisi"
construct
1
2
2
construct
1
construct
1
3
3
3
3
3
construct
s1 , s2 are the same instance
"zhangsan"
"zhangsan"
"lisi"
"lisi"
construct
1
2
2
construct
1
construct
1
3
3
3
3
3

s1、s2是同一实例,调用s2->setName修改s2的同时,修改了s1

【实例剖析】

实例1

QT中对SQL进行相关操作,就是采用单例模式。以sqlite3数据库进行说明。

1 建立连接时,调用类似下述代码:

[html] view plaincopyprint bool initSql::createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(dbName);
if (!db.open())
{
QMessageBox::warning(0, QObject::tr("Database Error"),db.lastError().text());
return false;
}
return true;
}
bool initSql::createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(dbName);
if (!db.open())
{
QMessageBox::warning(0, QObject::tr("Database Error"),db.lastError().text());
return false;
}
return true;
}

2 断开连接时,调用:

[html] view plaincopyprint void initSql::closeConnection()
{
QString name;
{
name = QSqlDatabase::database().connectionName();
}

QSqlDatabase::database().close();
QSqlDatabase::removeDatabase(name);
}
void initSql::closeConnection()
{
QString name;
{
name = QSqlDatabase::database().connectionName();
}

QSqlDatabase::database().close();
QSqlDatabase::removeDatabase(name);
}

这样做,好处是,只需要连接数据库一次,得到静态的实例,就可以在工程任何地方,通过该实例,对数据库进行操作,而不必连接第二次。缺陷是,不能同时创建一个以上的实例。

其实,单例模式,优点和缺陷都是由于只能创建一个实例引起的。

优点容易理解,讲讲缺点。

运用sqlite3建立了一个数据库,现在编程对数据库进行访问。现在的问题是,有可能会出现这样的情形,在同一时刻,网页cgi程序和QT编写的程序要同时对数据库访问。cgi没有采用单例模式,而Qt采用单例模式。CGI操作sqlite3请参考CGI如何用C控制sqlite3 一文。

假设,QT程序已经与数据库建立了连接。此时