1. 程式人生 > >橋接模式的應用之三層架構中的業務邏輯層(BLL)與資料訪問層(DAL)的解耦

橋接模式的應用之三層架構中的業務邏輯層(BLL)與資料訪問層(DAL)的解耦

各層的作用

  ①使用者介面層:只負責顯示和採集使用者操作。

  ②業務邏輯層:負責UI和DAL層之間的資料交換,是系統架構中體現核心價值的部分。它關注點主要集中在業務規則的制定、業務流程的實現和業務需求的有關係統設計。它與系統所對應的領域(Domain)有關。也可以做一些如使用者許可權合法性和資料據式是否正確等驗證檢查。

  ③資料訪問層:與資料庫直接打交道,如資料庫進行增、刪、改、查等操作。常用的技術如ADO+SQL語句。這裡可能還會有DBUtility類(負責建立資料庫連線)、與工廠方法模式相關的DALFactory抽象類(用於建立如OracleDAL、SQLServerDAL物件之類的工廠)、DataAccess產品類(真正操作資料庫的類)

各層的互動

  ①UI和BLL:UI層引用BLL和實體類(Entity)。

  ②BLL和DAL橋接模式,在BLL中持有一個DAL介面的引用

  ③DAL與資料庫:工廠模式或抽象工廠模式。DAL與資料庫間的解耦可參考《抽象工廠模式》部分的內容

//宣告檔案

//結構型模式:橋接模式
//場景:三層架構業務邏輯層(BLL)與資料操作層(DAL)的解耦

#include <iostream>
#include <string>
#include <list>
using namespace std;

//抽象的資料訪問層(DAL)
class CAbsDataAccess{
public:
	virtual bool Insert(string name) = 0;
	virtual bool Delete(string name) = 0;
	virtual bool Update(string oldname, string newname) = 0;
	virtual string QueryByIndex(int iIndex) = 0;
	virtual void QueryAll() = 0;
};
//具體的資料訪問層(DAL)
class CDataAccess : public CAbsDataAccess{
private:
	list<string> lstCustomer;
public:
	CDataAccess();
	~CDataAccess();
	bool Insert(string name);
	bool Delete(string name);
	bool Update(string oldname, string newname);
	string QueryByIndex(int iIndex);
	void QueryAll();
};

//具體的業務邏輯類
class CCustomerBusiness{
private:
	CAbsDataAccess* pDAL;
public:
	CCustomerBusiness(CAbsDataAccess* dal);
	CCustomerBusiness(const CCustomerBusiness& other);
	void Add(string name);
	void Sub(string name);
	void Mod(string oldname, string newname);
	string GetBy(int index);
	void DispAll();
};

//實現檔案

//具體的DAL層
CDataAccess::CDataAccess()
{
	//實際工程中從資料庫中讀取資料再填充列表
	lstCustomer.push_back("ZhangSan");
	lstCustomer.push_back("LiSi");
	lstCustomer.push_back("WangWu");
	lstCustomer.push_back("ZhaoLiu");
}
CDataAccess::~CDataAccess()
{
	cout << "Bofore deleting, size = " << lstCustomer.size() << endl;
	for(list<string>::iterator it = lstCustomer.begin(); it != lstCustomer.end();){
		it = lstCustomer.erase(it);
	}
	cout << "After deleted, size = " << lstCustomer.size() << endl;
}
bool CDataAccess::Insert(string name){lstCustomer.push_back(name); return true;}
bool CDataAccess::Delete(string name)
{
	bool bDeleted = false;
	for(list<string>::iterator it = lstCustomer.begin(); it != lstCustomer.end();it++){
		if((*it) == name){
			it = lstCustomer.erase(it); bDeleted = true; break;
		}
	}
	return bDeleted;
}
bool CDataAccess::Update(string oldname, string newname)
{
	bool bUpdate = false;
	for(list<string>::iterator it = lstCustomer.begin(); it != lstCustomer.end();it++){
		if((*it) == oldname){
			(*it) = newname; bUpdate = true; break;
		}
	}
	return bUpdate;
}
string CDataAccess::QueryByIndex(int iIndex)
{
	string strRet = "";
	if(iIndex < 0 || iIndex > lstCustomer.size() -1)		return strRet;
	list<string>::iterator it = lstCustomer.begin();
	for(int i = 0; i < iIndex; i++){
		it++;
	}
	strRet = (*it);
	return strRet;
}
void CDataAccess::QueryAll()
{
	cout << "***************************************************************" << endl;
	int i = 1;
	for(list<string>::iterator it = lstCustomer.begin(); it != lstCustomer.end(); it++, i++){
		cout << i << "		" << (*it) << endl;
	}
	cout << "***************************************************************" << endl << endl;
}
//具體的業務邏輯類
CCustomerBusiness::CCustomerBusiness(CAbsDataAccess* dal = NULL){pDAL = dal;}
CCustomerBusiness::CCustomerBusiness(const CCustomerBusiness& other){
	cout << "拷貝建構函式" << endl;
	pDAL = other.pDAL;
}
void CCustomerBusiness::Add(string name){pDAL->Insert(name);}
void CCustomerBusiness::Sub(string name){pDAL->Delete(name);}
void CCustomerBusiness::Mod(string oldname, string newname){pDAL->Update(oldname, newname);}
string CCustomerBusiness::GetBy(int index){return pDAL->QueryByIndex(index);}
void CCustomerBusiness::DispAll(){pDAL->QueryAll();}

//測試客戶端

void main()
{
	CAbsDataAccess* pDAL = new CDataAccess();
	CCustomerBusiness oBLL(pDAL);
	oBLL.Add("Tony"); oBLL.Add("Mary"); oBLL.DispAll();

	oBLL.Mod("Tony", "ZhangSanfeng"); oBLL.Mod("Mary", "ZhouXingchi"); oBLL.DispAll();

	oBLL.Sub("ZhangSan"); oBLL.Sub("WangWu"); oBLL.DispAll();

	cout << "The first element in lst is " << oBLL.GetBy(0) << endl;


	CCustomerBusiness* pBLL = new CCustomerBusiness(oBLL);
	if(pBLL != NULL){
		pBLL->DispAll(); delete pBLL; 
	}

	delete pDAL;
}