定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类 。我的理解是:1.有多产品(需要生产创建)2.多工厂(每个工厂都创建所有的产品)3.在工厂接口包含所有的产品创建
优点:1.调用的时候只需要初始化一次,就可以完全工厂的切换。增加新的工厂也符合开放封闭-封闭原则 2.创建实例的过程隐藏,客户端完全面向接口编程,产品的具体名称也被具体的工厂实现分离,不会出现再客户端。完全符合依赖倒转原则。
缺点:不够灵活,如果业务代码新增一个产品的方法,则需要改动的至少改动 工厂,工厂的实现类,外加新增产品和产品的实现类。
改进:下一章,我将利用反射,简单工厂,配置等方式简单化和改进一下抽象工厂模式。
类图:
案例:多数据库下的应用。假设现在有2个产品需要创建,同时也需要支持比较容易的支持SQLServer和MySQL数据库,该如何设计?
1.把每一个产品,抽象出一个接口或者抽象类,作用:定义规范,面向对象编程。(产品)
public interface IUser { void InsertUser(); void GetUser(); }
public interface IDepartment { void InsertDepartment(); void GetDepartment(); }
2..不同工厂下的(多数据库)实现类。(产品)
department:
public class MySqlDepartment : IDepartment { public void InsertDepartment() { Console.WriteLine("插入一条Department数据---mysql"); } public void GetDepartment() { Console.WriteLine("查询Department信息---mysql"); } } public class SqlDepartment : IDepartment { public void InsertDepartment() { Console.WriteLine("插入一条Department数据---sqlserver"); } public void GetDepartment() { Console.WriteLine("查询Department信息---sqlserver"); } }
User:
public class SqlUser : IUser { public void InsertUser() { Console.WriteLine("插入一条User数据---sqlserver"); } public void GetUser() { Console.WriteLine("查询User信息---sqlserver"); } } public class MySqlUser : IUser { public void InsertUser() { Console.WriteLine("插入一条User数据---mysql"); } public void GetUser() { Console.WriteLine("查询User信息---mysql"); } }
3.定义工厂,创造所有产品的方法,面向接口编程,定义规范。(工厂)
interface I工厂 { IUser CreateUser(); IDepartment CreateDepartment(); }
4.工厂实现类,依赖具体的产品,工厂和产品的耦合就这这里。(工厂)
public class MySql工厂 : I工厂 { public IUser CreateUser() { return new MySqlUser(); } public IDepartment CreateDepartment() { return new MySqlDepartment(); } } public class Sql工厂:I工厂 { public IUser CreateUser() { throw new NotImplementedException(); } public IDepartment CreateDepartment() { throw new NotImplementedException(); } }
5.调用,只需要new 不同的工厂。其他不变,都是面向接口,客户端和实际操作的实例分离。也就是说,我只要工厂和接口,不用需要知道具体的类。如果要成其他数据库,那我只需要new 不同数据库就可以了。其他的没有任何改动。
static void Main(string[] args) { //如果需要换成sqlserver,只需要更改这里 I工厂 factory = new MySql工厂(); //工厂创建用户对象 IUser iu = factory.CreateUser(); //执行正常业务操作 iu.InsertUser(); iu.GetUser(); //工厂创建部门对象 IDepartment idepart = factory.CreateDepartment(); //执行正常业务操作 idepart.InsertDepartment(); idepart.GetDepartment(); Console.ReadLine(); }
现在的这种模式就是写起来有点费劲,创建很多的类或接口,调试也不那么方便,下一章,会稍微简化下,敬请期待。