1. 程式人生 > >機房重構之七層登陸

機房重構之七層登陸

好不容易完成了機房重構的七層登陸架構,筆者感覺到非常心碎啊。七層登陸是三層登陸的加強版,可以說沒有三層登陸就沒有七層登陸。

七層登陸共分為UI(使用者介面層),FACADE(外觀層),FACTORY(工廠層),IDAL(介面),DAL(資料處理層),BLL(業務邏輯層),ENTITY(實體層)。

配置檔案:配置檔案是標準的XML檔案,XML標記和屬性區別大小寫。隨安裝程式一起被安裝到計算機上的檔案,裡面存放安裝號的應用程式執行時需要的引數,他可以按需求更改引數,開發人員可以使用配置檔案來更改設定,而不必重編譯應用程式。配置檔案能在資料庫連線字元和資料庫更換上,給我們省去大量的工作。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <appSettings>
      <!--預定義配置節,注意大小寫;它是整個程式的配置。如果是對當前使用者的配置,則使用userSettings配置節,格式要求與appSettings書寫要求一樣-->
      <add key="ConnStr" value="server=DESKTOP-C0UO8R2; database=login; User ID=sa; Password=123"/>
      <!--這裡的server、User ID、Password和database不區分大小寫,資料庫名稱YZY.Charge-->
      <add key="DB" value="DAL"/>
    </appSettings>

</configuration>

層與層之間的關係如下圖

UI(使用者介面層):收集使用者輸入的資料然後傳給外觀層,還有是把從外觀層接受到的資料顯示給使用者看,這一層是主要和使用者進行互動的。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using LoginUI;

namespace UI
{
    public partial class frmLogin : Form
    {
        public frmLogin()
        {
            InitializeComponent();
        }
       
        private void btnOK_Click(object sender, EventArgs e)
        {

            //登入前,先判斷是否為空
            if (txtUserID.Text.Trim() == "")
            {
                MessageBox.Show("未輸入使用者名稱,請先輸入!", "提示", MessageBoxButtons.OK);
                txtUserID.SelectAll();
                txtUserID.Focus();
            }
            if (txtPassword.Text == "")
            {
                MessageBox.Show("未輸入密碼,請先輸入!", "提示");
                txtPassword.SelectAll();
                txtPassword.Focus();

            }

            //修改密碼--窗體傳值
            Pass.txtPassword = txtPassword.Text;
            Pass.txtUserID = txtUserID.Text;

            try
            {
                Facade.LoginFacade Facade = new Facade.LoginFacade();//例項化一個外觀
                Entity.User_Info user = new Entity.User_Info();//例項化一個使用者
                user.UserID = txtUserID.Text.Trim();//接收控制元件傳來的使用者名稱資訊,將字串轉換成int型別
                user.PassWord = txtPassword.Text;//接收控制元件傳來的密碼資訊

                Boolean flag = false;//定義要給bool型變數
                Facade.LoginFacade Flogin = new Facade.LoginFacade();//例項化外觀
                flag = Flogin.SelectUser(user);//使用外觀方法,返回給User

                if (flag != false)
                {
                    MessageBox.Show("登入成功!", "提示");
                    this.Hide();//隱藏當前窗體
                    this.DialogResult = DialogResult.OK;//實現介面跳轉
                    frmMain main = new frmMain();//例項化一個窗體
                    main.Show();//顯示例項化的窗體

                }
                else
                {
                    MessageBox.Show("使用者名稱或者密碼錯誤", "提示");
                    txtUserID.SelectAll();
                    txtUserID.Focus();
                }

            }
            catch (Exception)
            {

                MessageBox.Show("出現錯誤", "提示");
                txtPassword.Clear();
                txtUserID.Clear();
                txtUserID.SelectAll();
                txtUserID.Focus();
            }
        }

FACADE(外觀層)

使用者提出請求後,外觀曾對使用者資料按照業務邏輯層要求的介面引數封裝規則封裝使用者資料,然後呼叫業務介面層對外提供相應的命令介面。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entity;
using BLL;

namespace Facade
{
    public class LoginFacade
    {
        public Boolean SelectUser(User_Info user)
        {
            bool flag;
            LoginBLL userBLL = new LoginBLL();//例項化LoginBLL
            flag = userBLL.UserBLL(user);//進入BLL層,並執行操作,返回有使用者為true,返回無使用者為false
            return flag;
        }
    }
}

IDAL:定義一個同意的介面,解除B層和D層的耦合

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;

namespace IDAL
{
    public interface LoginIDAL
    {
        DataTable SelectUser(Entity.User_Info User_Info);//DataTable表示記憶體中的資料的一個類,實現了增刪改查中的查---查詢使用者
    }

}

DAL層:對於資料和命令的不同,處理方式也不同,我們將不同的處理方式歸類,並將介面層傳入的資料及命令流入對應的處理流程。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;

namespace BLL
{
    public class LoginBLL
    {
        public bool UserBLL(Entity.User_Info User_Info)
        {
            Factory.LoginFactory factory = new Factory.LoginFactory();//例項化工廠
            IDAL.LoginIDAL idal = factory.CreateUser();//進入工廠層,使用工廠方法建立介面
            DataTable table = idal.SelectUser(User_Info);//接收D層的返回值

            bool flag;
            if (table.Rows.Count==0)//返回的DataTable型別,如果它的行數等於0,說明沒有符合該賬號密碼的使用者
            {
                flag = false;
            }
            else
            {
                flag = true;
            }
            return flag;
        }
    }
}

實體層:不同的處理流程分析資料和命令產生出對應的一個實體,這個實體根據其本身的屬性和方法一斤上層傳入的命令,將資料處理為資料訪問需要的介面引數,並將資料訪問層提交訪問資料庫的請求,並向業務介面層返回範文結果。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Entity
{
    public class Student_Info
    {
         //定義學號欄位
        private string studentNo;
        public string StudentNo
        {
            get { return studentNo; }
            set { studentNo = value; }
        }

        //定義學生姓名欄位
        private string studentName;
        public string StudentName
        {
            get { return studentName; }
            set { studentName = value; }
        }

資料訪問層:將資料轉化為資料庫可以識別的SQL語句,並訪問資料庫層,訪問結果會返回給實體層。

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 LoginDAL:LoginIDAL
    {
        public DataTable SelectUser(Entity.User_Info User_Info)//查詢使用者
        {
            SQLHelper sqlHelper = new SQLHelper();//例項化一個SQLHelper
            SqlParameter[] sqlParams = { new SqlParameter(@"UserID", User_Info.UserID),
                                        new SqlParameter("@Password", User_Info.PassWord) };

            string sql = @"SELECT * FROM [User_Info] WHERE [email protected] and [email protected]";//查詢語句
            DataTable table = sqlHelper.ExecuteQuery(sql, sqlParams, CommandType.Text);
            return table;
        }

    }
}

FACTORY層(工廠層)工廠通過讀取配置檔案,實現瞭解耦。在以後更換資料庫的時候,只需要修改配置檔案,增加一個新的類,而不需要修改原來的程式碼。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Configuration;

namespace Factory
{
    public class LoginFactory
    {
        string StrDB=ConfigurationManager.AppSettings["DB"];//接收來自配置檔案的資料

        public IDAL.LoginIDAL CreateUser()
        {
            string ClassName = StrDB + "." + "LoginDAL";//DAL層的類名
            return (IDAL.LoginIDAL)Assembly.Load(StrDB).CreateInstance(ClassName);//反射+工廠的應用
        }
    }
}