引言
上一篇介绍了设计模式中的工厂方法模式-C#设计模式(3)-工厂方法模式,本篇将介绍抽象工厂模式;
抽象工厂模式简介
抽象工厂模式(AbstractFactory):提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类;
工厂方法模式是为了克服简单工厂模式的缺点而设计出来的;工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题,可以在一个工厂中创建多个产品;
结构图
应用实例
这里实例继续采用上一篇中的实例:现在市面上很多种数据库,Oracle、SqlSever、Mysql等;比如我们现在需要对某个业务实体进行数据操作,新增。更新等,如果现在有用户user 、部门department;如果前期是使用的sqlserver,如果希望达到后期能够平滑切换数据库为oracle,而影响较小;
类图
代码实例
产品
用户User操作
用户接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { /// <summary> /// 用户 /// </summary> public interface IUserOpr { /// <summary> /// 新增 /// </summary> bool Insert(); /// <summary> /// 更新 /// </summary> /// <returns></returns> bool Update(); } }
oracle操作用户User
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { /// <summary> /// oracle操作用户 /// </summary> public class OracleUserOpr : IUserOpr { /// <summary> /// 新增 /// </summary> public bool Insert() { Console.WriteLine("Oracle新增用户记录"); return true; } /// <summary> /// 更新 /// </summary> /// <returns></returns> public bool Update() { Console.WriteLine("Oracle更新用户记录"); return true; } } }
sqlserver操作用户User
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { /// <summary> /// sqlServer操作用户 /// </summary> public class SqlServerUserOpr : IUserOpr { /// <summary> /// 新增 /// </summary> public bool Insert() { Console.WriteLine("SqlServer新增用户记录"); return true; } /// <summary> /// 更新 /// </summary> /// <returns></returns> public bool Update() { Console.WriteLine("SqlServer更新用户记录"); return true; } } }
部门Department操作
部门操作接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { /// <summary> /// 部门操作 /// </summary> public interface IDepartMentOpr { /// <summary> /// 新增 /// </summary> bool Insert(); /// <summary> /// 更新 /// </summary> /// <returns></returns> bool Update(); } }
oracle操作部门Department
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { /// <summary> /// oracle操作部门 /// </summary> public class OracleDepartMentOpr : IDepartMentOpr { /// <summary> /// 新增 /// </summary> public bool Insert() { Console.WriteLine("Oracle新增部门记录"); return true; } /// <summary> /// 更新 /// </summary> /// <returns></returns> public bool Update() { Console.WriteLine("Oracle更新部门记录"); return true; } } }
sqlserver操作部门Department
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { /// <summary> /// sqlServer操作部门 /// </summary> public class SqlServerDepartMentOpr : IDepartMentOpr { /// <summary> /// 新增 /// </summary> public bool Insert() { Console.WriteLine("SqlServer新增部门记录"); return true; } /// <summary> /// 更新 /// </summary> /// <returns></returns> public bool Update() { Console.WriteLine("SqlServer更新部门记录"); return true; } } }
工厂
这里如果是工厂方法模式将会对用户(sqlserver、oracle)、部门(sqlserver、oracle)分别创建工厂,将会创建四个工厂;
这里使用抽象工厂将产品在一个工厂中创建;
工厂接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { /// <summary> /// 工厂接口 /// </summary> public interface IFactory { /// <summary> /// 创建User /// </summary> /// <returns></returns> IUserOpr CreateUser(); /// <summary> /// 创建部门 /// </summary> /// <returns></returns> IDepartMentOpr CreateDepartMent(); } }
Oracle工厂
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { /// <summary> /// oracle工厂 /// </summary> public class OracleFactory:IFactory { public IUserOpr CreateUser() { return new OracleUserOpr(); } public IDepartMentOpr CreateDepartMent() { return new OracleDepartMentOpr(); } } }
sqlserver工厂
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { /// <summary> /// sqlServer工厂 /// </summary> public class SqlserverFactory:IFactory { public IUserOpr CreateUser() { return new SqlServerUserOpr(); } public IDepartMentOpr CreateDepartMent() { return new SqlServerDepartMentOpr(); } } }
业务调用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AbstractFactory { class Program { static void Main(string[] args) { //oracle操作 //IFactory dbFactory1 = new OracleFactory(); //切换数据库为sqlserver IFactory dbFactory1 = new SqlserverFactory(); IUserOpr oprUser = dbFactory1.CreateUser(); oprUser.Insert(); oprUser.Update(); IDepartMentOpr oprDepartMent = dbFactory1.CreateDepartMent(); oprDepartMent.Insert(); oprDepartMent.Update(); Console.WriteLine("-----------------------------------------"); Console.ReadKey(); } } }
调用结果
sqlserver调用结果如下
切换为oracle数据结果如下
总结
优点
抽象工厂模式最大的好处就是易于更换产品系列(如上述示例中的更改数据库)
缺点
抽象工厂模式中增加新产品没有很好支持"开放-封闭"原则。
抽象工厂接口中如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。