升级版:由简单三层,升级到简单工厂模式
前面,复习了简单三层。可以看出三层的缺点,业务层和数据访问层耦合在一起了,如果后面我需要在上面扩展的话,就不方便了,比如,现在我只是支持微软的SQL Server数据库,要是我后面想支持MySQL,Oracle数据库呢。。。?这该咋办?你可以说,这好办,重新把访问数据库的类和方法写一遍。。显然这不是好方法。不符合,软件设计的封装性--封装变化点原则。
下面看下业务层的代码吧:
using DAL; using Entity; using IDAL; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BLL { public class ClassBLL { ClassDAL dal = new ClassDAL(); /// <summary> /// 获取Class列表 /// </summary> /// <returns></returns> public List<ClassEntity> GetList() { return dal.GetList(); } } }
可以看出,代码中标橙色的代码(数据访问类的实例化代码),和业务层耦合了。
我们可以做这样的一个改变:把数据访问层实例化的代码,进行一下封装。--封装变化点,这样在业务层里面实例化的数据层的时候,就可以调用我们封装的方法。
现在我们可以这样做,添加一个接口:
using Entity; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IDAL { public interface IClassDAL { List<ClassEntity> GetList(); } }
在接口里面定义数据访问层里面的方法:
然后,我们可以在数据层里面的类里面后面来实现这个接口:
using Entity; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using System.Data.SqlClient; using IDAL; namespace DAL { public class ClassDAL:IClassDAL { /// <summary> /// 获取班级列表数据 /// </summary> /// <returns></returns> public List<ClassEntity> GetList() { string sql = "SELECT * FROM dbo.MyClass;"; DataTable table = SQLHelper.GetDataTable(sql, CommandType.Text); //此处不能直接new一个对象 List<ClassEntity> classListModel = null; //table不为空 if (table.Rows.Count > 0) { //要在这里new ,创建对象 classListModel = new List<ClassEntity>(); ClassEntity model = null; foreach (DataRow row in table.Rows) { model = new ClassEntity(); //加载数据 LoadEntity(row, model); classListModel.Add(model); } } return classListModel; } /// <summary> /// 加载数据 /// </summary> /// <param name="row"></param> /// <param name="model"></param> public void LoadEntity(DataRow row, ClassEntity model) { if (row["C_ID"] != null) { model.CID = Convert.ToInt32(row["C_ID"]); } if (row["C_Name"] != null) { model.CName = row["C_Name"].ToString(); } if (row["C_Descr"] != null) { model.CDescription = row["C_Descr"].ToString(); } } } }
然后在业务层里面,实例化数据访问的类的时候,我们可以这样做:
using DAL; using Entity; using IDAL; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BLL { public class ClassBLL { //耦合度太高 // ClassDAL dal = new ClassDAL(); //这种还是有耦合,业务层和数据访问层耦合度太高 IClassDAL dal = new ClassDAL(); /// <summary> /// 获取Class列表 /// </summary> /// <returns></returns> public List<ClassEntity> GetList() { return dal.GetList(); } } }
图中代码标橙色的部分就是新的实例化方法:
IClassDAL dal = new ClassDAL();
可以看出这个方式,虽然较第一种直接实例化数据访问类的方式,进步了一点,但还是没能解决业务层和数据访问层耦合的问题!!!,怎么解决呢?
我们看出,主要在 new ClassDAL();这个部分,这个部分是变化的,所以基于封装变化点,我们还可以继续封装。
再新建一个工厂类:
using DAL; using IDAL; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DALFactory { public class DALFactory { public static IClassDAL GetClassInstance() { return new ClassDAL(); } } }
工厂类的作用就是,解决对象创建的问题,这里,解决了数据访问层类的创建问题。
这样写之后,我们在业务层就好办了!
using DAL; using Entity; using IDAL; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BLL { public class ClassBLL { //耦合度太高 // ClassDAL dal = new ClassDAL(); //这种还是有耦合,业务层和数据访问层耦合度太高 //IClassDAL dal = new ClassDAL(); //引入简单工厂模式 IClassDAL dal = DALFactory.DALFactory.GetClassInstance(); /// <summary> /// 获取Class列表 /// </summary> /// <returns></returns> public List<ClassEntity> GetList() { return dal.GetList(); } } }
这一行代码就实现了,业务层和数据层耦合的问题。
每天学一点,每天积累一天,进步就不止一点点!PS:好记性不如烂笔头,学会总结,学会思考~~~
----要飞翔,必须靠自己!