去年买了GoF的设计模式的书,始终无法能够入门。 由于平时的编程以C语言为主,C++也只是用到了一些容器的便利性,没有真正的面向对象的思维方式,看这本设计模式的书时,始终无法理解其中的深意。
今年买了本大话设计模式,照着书中的例子学习,再加上书本中对设计模式较为浅显的讲解----有的地方讲的并不准确,但却可以用例子让我最快的明白这个模式的大意。
粗粗的看完大话,再看GOF的书,才觉得有点能够看得下去了,终于明白了“抽象工厂”和“工厂方法”之间的差别。这里练习了一个大话中的“抽象工厂”的例子,突然觉得理解了许多。
//抽象工厂,将生成“产品”的接口提炼出来,客户代码不再去关心哪个工厂产出了哪个产品,只要用抽象工厂得到抽象产品,再去使用“抽象产品”的功能、享受“抽象产品”的服务,至于到底是哪个“具体的产品”在工作,客户代码也不关心。
//这样,当客户代码需要换一种”服务“时,只需要换一个具体的产品来工作即可;而生成该具体的产品,只要换一个”具体的工厂“即可; 这就极大的增大 了代码的灵活性!!
#include <string>
#include <iostream>
//产品类功能接口要处理的类
class User
{
public:
void SetName(std::string name) {name_ = name;}
void SetId(int id) {id_ = id;}
std::string GetName(){return name_;}
int GetId() {return id_;}
private:
std::string name_;
int id_;
};
//抽象产品类,定义产品的功能接口
class DataBase
{
public:
virtual void InsertUser(User user) = 0;
virtual void GetUser(int id) = 0;
};
//具体产品类,实现产品的功能接口,不同的具体产品虽然具有抽象接口定义的共同的功能接口,但功能接口实现的效果却不一样
class AccessServer : public DataBase
{
public:
void InsertUser(User user)
{
std::cout<<"----ACCESS Server---- add a record in table"<<std::endl;
std::cout<<"User ID is :\t"<<user.GetId()<<std::endl;
std::cout<<"User name is :\t"<<user.GetName()<<std::endl;
std::cout<<"-------------------------------------------"<<std::endl;
}
void GetUser(int id)
{
std::cout<<"----ACCESS SERVER----Get user by id:\t"<<id<<std::endl;
}
};
class SqlServer : public DataBase
{
public:
void InsertUser(User user)
{
std::cout<<"----SQLServer---- add a record in table"<<std::endl;
std::cout<<"User ID is :\t"<<user.GetId()<<std::endl;
std::cout<<"User name is :\t"<<user.GetName()<<std::endl;
}
void GetUser(int id)
{
std::cout<<"----SQLServer----Get a record from table by the id:\t"<<id<<std::endl;
//std::cout<<"User ID is :\t"<<user.GetId()<<std::endl;
//std::cout<<"User name is :\t"<<user.GetName()<<std::endl;
}
};
class DataBaseFactoryItf // 抽象工厂类,定义接口
{
public:
virtual DataBase* CreateDataBase() = 0;
};
//定义具体工厂类,实现生产产品的接口,不同的具体工厂生产不同的具体产品
class SqlServerFactory : public DataBaseFactoryItf
{
public:
DataBase* CreateDataBase()
{
return new SqlServer;
}
};
class AccessFactory : public DataBaseFactoryItf
{
public:
DataBase* CreateDataBase()
{
return new AccessServer;
}
};
int main(int _Argc, char* _Arg[])
{
User jjp;
jjp.SetId(100);
jjp.SetName("Jinjupeng");
//定义抽象工厂指针,指向具体的工厂类; 如果要在后面的代码中替换具体的产品,只要在这里修改需要的具体工厂类
//即可,后面的抽象产品类指针,保证运行时的动态绑定,不需要改写具体产品使用的代码,极大的增强了灵活性。
DataBaseFactoryItf *pDbF = new AccessFactory;
//定义抽象产品指针,指向由具体工厂生产的具体产品
DataBase* pDb = pDbF->CreateDataBase();
pDb->InsertUser(jjp);
pDb->GetUser(100);
DataBase* pDb2 = pDbF->CreateDataBase();
pDb2->InsertUser(jjp);
pDb2->GetUser(100);
return 0;
}