抽象工厂模式(Abstract Factory) 抽象工厂模式(Abstract Factory),提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。
抽象工厂模式结构图 略,用途较少,缺点很多
抽象工厂的优点 最大的优点是:易于交互产品系列,由于具体工厂类,在一个应用中只需要在初始化时出现一次,这使得改变一个应用的具体工厂非常容易,它只需要改变具体工厂即可使用不同的产品配置。如果需要更改数据库访问,只需要更改具体工厂即可。
第二:它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂实现分离,不会出现在客户代码中。(客户端只需要认识IUser和IDepartment,即数据操作的抽象接口即可)
抽象工厂的缺点 缺点是显而易见的,如果需求的更改来自于增加功能,如增加项目表
我们就需要多写IProject、SqlServerProject、AccessProject三个类。
还要更改IFactory、SqlServerFactory、AccessFactory。非常糟糕。
实例——不同的数据库访问 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 在数据库中的实践,在设计数据库访问底层持久时,需要考虑到底使用哪种数据库,如果一开始没有对此进行设计,碰到更换数据库时,将会是一场灾难。class Department { interface IDepartment { void Insert (Department department ) ; Department GetDepartment (int id ) ; } class SqlSeverDepartment : IDepartment { public Department GetDepartment (int id ) { return null ; } public void Insert (Department department ) { } } class AccessDepartment : IDepartment { public Department GetDepartment (int id ) { return null ; } public void Insert (Department department ) { } } interface IFactory { IUser CreateUser () ; IDepartment CreateDepartment () ; } class SqlServerFactory : IFactory { public IDepartment CreateDepartment () { return new SqlSeverDepartment(); throw new NotImplementedException(); } public IUser CreateUser () { return new SqlServerUser(); throw new NotImplementedException(); } } class AccessFactory : IFactory { public IDepartment CreateDepartment () { return new AccessDepartment(); throw new NotImplementedException(); } public IUser CreateUser () { return new AccessUser(); throw new NotImplementedException(); } } class solution { static void Main (string [] args ) { User user = new User(); Department dept = new Department(); IFactory factory = new SqlServerFactory(); IUser iu = factory.CreateUser(); iu.Insert(dept); iu.GetUser(); IDepartment id = factory.CreateDepartment(); id.Insert(dept); id.GetDepartment(1 ); } }
用简单工厂方式改进抽象工厂模式 去除三个类:IFactory、SqlServerFactory和AccessFactory
取代之用DataAccess类通过简单工厂来实现
改进后的抽象工厂结构图:
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 代码实现:class DataAccess { private static readonly string db = "sqlserver" ; public static IUser CreateUser () { IUser result = null ; switch (db) { case "sqlserver" : result = new SqlServerUser(); break ; case "Access" : result = new AccessUser(); break ; } return result; } public static IDepartment CreateDepartment () { IDepartment result = null ; switch (db) { case "sqlserver" : result = new SqlServerDept(); break ; case "Access" : result = new AccessDept(); break ; } return result; } } User user = new User(); Department dept = new Department(); IUser iu = DataAccess.CreateUser(); iu.Insert(user); iu.GetUser(1 ); IDepartment id = DataAccess.CreateDepartment(); id.Insert(dept); id.GetDepartment(1 ); 如果要增加Oracle数据库访问,只需要在DataAccess类中每个方法的switch 分支中添加Oracle分支。
抽象工厂模式+反射(+配置)实现数据访问