抽象工厂模式
理论
抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
抽象工厂模式的优点:
1. 最大的好处是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
2. 第二好处是,它让具体的创建实例过程于客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
实例
实现数据库访问,要求包含“新增用户”和“得到用户”
用户有 ID 和 Name 两个属性
初步实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #include <iostream> using namespace std; //用户类 class User { public : User( int id, string name){ ID = id; Name = name; } private : int ID; string Name; }; //Sqlserver数据库类 class SqlserverUser { public : void Insert(User* user) { cout << "在SQL Server中给User表增加一条记录" << endl; } void GetUser( int id){ cout << "在SQL Server中根据ID得到User表一条记录" << endl; } }; //Access数据库类 class AccessUser { public : void Insert(User* user) { cout << "在Access中给User表增加一条记录" << endl; } void GetUser( int id) { cout << "在Access中根据ID得到User表一条记录" << endl; } }; //客户端 int main() { User* user = new User(1, "小明" ); SqlserverUser* su = new SqlserverUser(); su->Insert(user); //插入用户 su->GetUser(1); //得到ID为1的用户 delete user; system ( "pause" ); return 0; } |
工厂方法模式
UML类图
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #include <iostream> using namespace std; class User { public : User( int id, string name) { ID = id; Name = name; } private : int ID; string Name; }; //抽象数据库类 class AbstractUser { public : virtual void Insert(User* user) {}; virtual void GetUser( int id) {}; }; //具体数据库类 class SqlserverUser : public AbstractUser { public : void Insert(User* user) { cout << "在SQL Server中给User表增加一条记录" << endl; } void GetUser( int id) { cout << "在SQL Server中根据ID得到User表一条记录" << endl; } }; class AccessUser : public AbstractUser { public : void Insert(User* user) { cout << "在Access中给User表增加一条记录" << endl; } void GetUser( int id) { cout << "在Access中根据ID得到User表一条记录" << endl; } }; //抽象工厂类 class AbstractFactory { public : virtual AbstractUser* CreateUser() = 0; }; //具体工厂类 class SqlServerFactory : public AbstractFactory { public : AbstractUser* CreateUser() { return new SqlserverUser(); } }; class AccessFactory : public AbstractFactory { public : AbstractUser* CreateUser() { return new AccessUser(); } }; int main() { User* user = new User(1, "小明" ); AbstractFactory* factory = new SqlServerFactory(); AbstractUser* iu = factory->CreateUser(); iu->Insert(user); iu->GetUser(1); delete factory; delete user; delete iu; system ( "pause" ); return 0; } |
抽象工厂模式
UML类图
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #include <iostream> using namespace std; class User { public : User( int id, string name) { ID = id; Name = name; } private : int ID; string Name; }; class Department { public : Department(string _department) { department = _department; } private : string department; }; //抽象部门类 class AbstractDepartment { public : virtual void Insert(Department* department) {}; virtual void GetDepartment( int id) {}; }; //具体部门类 class SqlserverDepartment : public AbstractDepartment { public : void Insert(Department* department) { cout << "在SQL Server中给Department表增加一条记录" << endl; } void GetDepartment( int id) { cout << "在SQL Server中根据ID得到Department表一条记录" << endl; } }; class AccessDepartment : public AbstractDepartment { public : void Insert(Department* department) { cout << "在Access中给Department表增加一条记录" << endl; } void GetDepartment( int id) { cout << "在Access中根据ID得到Department表一条记录" << endl; } }; //抽象数据库类 class AbstractUser { public : virtual void Insert(User* user) {}; virtual void GetUser( int id) {}; }; //具体数据库类 class SqlserverUser : public AbstractUser { public : void Insert(User* user) { cout << "在SQL Server中给User表增加一条记录" << endl; } void GetUser( int id) { cout << "在SQL Server中根据ID得到User表一条记录" << endl; } }; class AccessUser : public AbstractUser { public : void Insert(User* user) { cout << "在Access中给User表增加一条记录" << endl; } void GetUser( int id) { cout << "在Access中根据ID得到User表一条记录" << endl; } }; //抽象工厂类 class AbstractFactory { public : virtual AbstractUser* CreateUser()= 0; virtual AbstractDepartment* CreateDepartment() = 0; }; //具体工厂类 class SqlServerFactory : public AbstractFactory { public : AbstractUser* CreateUser() { return new SqlserverUser(); } AbstractDepartment* CreateDepartment() { return new SqlserverDepartment(); } }; class AccessFactory : public AbstractFactory { public : AbstractUser* CreateUser() { return new AccessUser(); } AbstractDepartment* CreateDepartment() { return new AccessDepartment(); } }; int main() { User* user = new User(1, "小明" ); Department* department = new Department( "研发部" ); AbstractFactory* factory = new SqlServerFactory(); AbstractUser* iu = factory->CreateUser(); iu->Insert(user); iu->GetUser(1); delete user; delete iu; AbstractDepartment* id = factory->CreateDepartment(); id->Insert(department); id->GetDepartment(1); delete department; delete factory; delete id; system ( "pause" ); return 0; } |
只有一个 User 类和 User 操作类的时候,只需要工厂方法模式。当数据库中有很多的表,而 SOL Server 和 Access 又是两个不同的分类,所以解决这种涉及到多个产品系列的问题,就需要用一种专门的工厂模式叫抽象工厂模式。
抽象工厂模式的缺点:
如果有增加功能的需求,比如要增加项目表 Project,就需要增加三个类 AbstractProject、SqlserverProject、AccessProject,还需要更改对应的三个工厂类才可以完全实现。
而且当有很多客户端程序时,会有很多地方在使用 AbstractUser 或 AbstractDepartment, 这样的设计需要在每一个类的开始声明 AbstractFactory* factory = new SqlServerFactory(); 会导致在更改数据库时改动所有的声明。
简单工厂+抽象工厂
UML类图
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | #include <iostream> using namespace std; class User { public : User( int id, string name) { ID = id; Name = name; } private : int ID; string Name; }; class Department { public : Department(string _department) { department = _department; } private : string department; }; //抽象部门类 class AbstractDepartment { public : virtual void Insert(Department* department) {}; virtual void GetDepartment( int id) {}; }; //具体部门类 class SqlserverDepartment : public AbstractDepartment { public : void Insert(Department* department) { cout << "在SQL Server中给Department表增加一条记录" << endl; } void GetDepartment( int id) { cout << "在SQL Server中根据ID得到Department表一条记录" << endl; } }; class AccessDepartment : public AbstractDepartment { public : void Insert(Department* department) { cout << "在Access中给Department表增加一条记录" << endl; } void GetDepartment( int id) { cout << "在Access中根据ID得到Department表一条记录" << endl; } }; //抽象数据库类 class AbstractUser { public : virtual void Insert(User* user) {}; virtual void GetUser( int id) {}; }; //具体数据库类 class SqlserverUser : public AbstractUser { public : void Insert(User* user) { cout << "在SQL Server中给User表增加一条记录" << endl; } void GetUser( int id) { cout << "在SQL Server中根据ID得到User表一条记录" << endl; } }; class AccessUser : public AbstractUser { public : void Insert(User* user) { cout << "在Access中给User表增加一条记录" << endl; } void GetUser( int id) { cout << "在Access中根据ID得到User表一条记录" << endl; } }; class DataSelect { public : AbstractUser* CreatUser() { AbstractUser* result = NULL; if (db == "Sqlserver" ) { result = new SqlserverUser(); } else if (db == "Access" ) { result = new AccessUser(); } return result; } AbstractDepartment* CreatDepartment() { AbstractDepartment* result = NULL; if (db == "Sqlserver" ) { result = new SqlserverDepartment(); } else if (db == "Access" ) { result = new AccessDepartment(); } return result; } private : string db = "Sqlserver" ; //string db = "Access" }; int main() { User* user = new User(1, "小明" ); Department* department = new Department( "研发部" ); DataSelect* data = new DataSelect(); AbstractUser* iu = data->CreatUser(); iu->Insert(user); iu->GetUser(1); delete user; delete iu; AbstractDepartment* id = data->CreatDepartment(); id->Insert(department); id->GetDepartment(1); delete department; delete data; delete id; system ( "pause" ); return 0; } |
另外, 在 C# 中,所有在用简单工厂的地方,都可以考虑用反射技术来去除 switch 和 if,解除分支判断带来的耦合。
后续:C++中也可继续改进。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧