升级版:由简单三层,升级到简单工厂模式

     前面,复习了简单三层。可以看出三层的缺点,业务层和数据访问层耦合在一起了,如果后面我需要在上面扩展的话,就不方便了,比如,现在我只是支持微软的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();
        }
    }
}

这一行代码就实现了,业务层和数据层耦合的问题。

原文地址:https://www.cnblogs.com/caofangsheng/p/5002758.html