原来写过一篇三层架构之泛型应用的简单登录,已经过去2年了,今天有一朋友问我关于抽象工厂的问题,就把自己后来解耦的方法从项目中拿出来了,方便大家学习。
我重新写了一个例子项目,如下截图:
XU.Model层中有一个抽象类BaseModel.cs,User.cs是用户实体类,继承与BaseModel类,是用于类型安全考虑的
1 using System; 2 3 namespace XU.Model 4 { 5 public abstract class BaseModel 6 { 7 } 8 }
1 using System; 2 3 namespace XU.Model 4 { 5 public class User : BaseModel 6 { 7 public string UserName { set; get; } 8 public string Password { set; get; } 9 } 10 }
XU.FactoryDAL层是用于反射获取实例,其中只有一个类
1 using System; 2 3 namespace XU.FactoryDAL 4 { 5 public class DataAccess<T> where T : class 6 { 7 //获取配置路径 8 private static readonly string path = System.Configuration.ConfigurationManager.AppSettings["DAL"]; 9 private DataAccess() { } 10 11 /// <summary> 12 /// 创建实例 13 /// </summary> 14 /// <param name="type"></param> 15 /// <returns></returns> 16 public static T CreateDAL(string type) 17 { 18 string className = string.Format(path + ".{0}", type); 19 try 20 { 21 return (T)System.Reflection.Assembly.Load(path).CreateInstance(className); 22 } 23 catch (Exception ex) 24 { 25 throw new Exception(ex.Message.ToString()); 26 } 27 } 28 } 29 }
XU.IDAL层依赖与XU.Model,其中包含一个基接口IBaseDAL.cs,还有一个用于定义一些基接口中没有方法的接口IUserDAL,继承与基接口IBaseDAL<T>
1 using System; 2 3 namespace XU.IDAL 4 { 5 public interface IBaseDAL<T> where T : XU.Model.BaseModel, new() 6 { 7 bool Add(T model); 8 bool Delete(int ID); 9 bool Update(T model); 10 T GetModel(int ID); 11 } 12 }
1 using System; 2 3 namespace XU.IDAL 4 { 5 public interface IUserDAL : IBaseDAL<XU.Model.User> 6 { 7 /// <summary> 8 /// 判断用户名是否存在 9 /// </summary> 10 /// <param name="userName"></param> 11 /// <returns></returns> 12 bool Exists(string userName); 13 } 14 }
实现XU.IDAL中接口有2个类库,一个是MSSQL方案,一个是MYSQL方案,这2个类库都依赖于XU.Model和XU.IDAL,下面是实现方案
XU.MSSQLDAL的实现如下
1 using System; 2 3 namespace XU.MSSQLDAL 4 { 5 public class UserDAL : XU.IDAL.IUserDAL 6 { 7 public bool Exists(string userName) 8 { 9 return true; 10 } 11 12 public bool Add(Model.User model) 13 { 14 return true; 15 } 16 17 public bool Delete(int ID) 18 { 19 return true; 20 } 21 22 public bool Update(Model.User model) 23 { 24 return true; 25 } 26 27 public Model.User GetModel(int ID) 28 { 29 return new XU.Model.User() { UserName = "MSSQL", Password = "123456" }; 30 } 31 } 32 }
XU.MYSQLDAL的实现如下
1 using System; 2 3 namespace XU.MYSQLDAL 4 { 5 public class UserDAL : XU.IDAL.IUserDAL 6 { 7 public bool Exists(string userName) 8 { 9 return false; 10 } 11 12 public bool Add(Model.User model) 13 { 14 return false; 15 } 16 17 public bool Delete(int ID) 18 { 19 return false; 20 } 21 22 public bool Update(Model.User model) 23 { 24 return false; 25 } 26 27 public Model.User GetModel(int ID) 28 { 29 return new XU.Model.User() { UserName = "MYSQL", Password = "123456" }; 30 } 31 } 32 }
XU.BLL业务逻辑层中包含了一个用于继承的基类BaseBLL<T>和用户业务逻辑UserBLL类,这层依赖XU.IDAL,XU.Model,XU.FactoryDAL库
1 using System; 2 3 namespace XU.BLL 4 { 5 public class BaseBLL<T> where T : XU.Model.BaseModel, new() 6 { 7 protected XU.IDAL.IBaseDAL<T> Dal; 8 public BaseBLL(string type) 9 { 10 Dal = XU.FactoryDAL.DataAccess<XU.IDAL.IBaseDAL<T>>.CreateDAL(type); 11 } 12 public virtual bool Add(T model) 13 { 14 return Dal.Add(model); 15 } 16 public virtual bool Delete(int ID) 17 { 18 return Dal.Delete(ID); 19 } 20 public virtual bool Update(T model) 21 { 22 return Dal.Update(model); 23 } 24 public virtual T GetModel(int ID) 25 { 26 return Dal.GetModel(ID); 27 } 28 } 29 }
1 using System; 2 3 namespace XU.BLL 4 { 5 public class UserBLL : BaseBLL<XU.Model.User> 6 { 7 private const string _Type = "UserDAL"; 8 private XU.IDAL.IUserDAL _Dal; 9 10 public UserBLL() 11 : base(_Type) 12 { 13 _Dal = base.Dal as XU.IDAL.IUserDAL; 14 if (_Dal == null) 15 { 16 throw new NullReferenceException(_Type); 17 } 18 } 19 20 public bool Exists(string userName) 21 { 22 return _Dal.Exists(userName); 23 } 24 } 25 }
XU.ConsoleDemo是一个控制台程序,本准备弄一个网站测试,觉得麻烦,用这个讲解抽象工厂更简单和直观
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <!--DAL路径--> <add key="DAL" value="XU.MYSQLDAL"/> </appSettings> </configuration>
1 using System; 2 3 namespace XU.ConsoleDemo 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 XU.BLL.UserBLL userBLL = new XU.BLL.UserBLL(); 10 XU.Model.User user=new XU.Model.User(); 11 int id = 1; 12 Console.WriteLine("添加------{0}", userBLL.Add(user)); 13 Console.WriteLine("删除------{0}", userBLL.Delete(id)); 14 Console.WriteLine("更新------{0}", userBLL.Update(user)); 15 XU.Model.User model = userBLL.GetModel(id); 16 Console.WriteLine("查询 用户名:{0} 密码:{1}", model.UserName, model.Password); 17 Console.ReadLine(); 18 } 19 } 20 }
注意:XU.ConsoleDemo是不会直接引用XU.MSSQLDAL和XU.MYSQLDAL的,但是XU.ConsoleDemo中的Debug目录下要把编译好的XU.MSSQLDAL.dll和XU.MYSQLDAL.dll放进去,如果是网站就要放入网站中的Bin文件夹下
以上就完成了抽象工厂的实现,是不是很简单,大家相互交流学习,如想讨论,请加群83455635
如发现哪里不足,请留言,谢谢!