兩年未寫後台 CRUD,重拾時發現傳統寫法過於囉嗦。結合近期設計模式與 OOP 深度理解,嘗試用物件導向方式重構 CRUD 通用邏輯,提升代碼複用與團隊協作效率。
針對任意資料表的維護,操作無非四種:新增、刪除、修改、查詢。差異僅在於實體屬性與資料表欄位對應。利用 VS2005+ 的泛型特性,可將共同邏輯抽象封裝。
public abstract class DataOperation<T> {
// 新增
public abstract int Add(T entity);
// 修改
public abstract int Update(T entity);
// 查詢:提供預設分頁實作,避免循環依賴採虛擬方法
public virtual DataTable GetList(
int pageSize, int pageNumber, string procName,
string condition, string compositor,
out int pageCount, out int recordCount, out int nextPageNumber) {
pageCount = recordCount = nextPageNumber = 0;
return new DataTable();
}
}
設計考量:GetList 採虛擬方法而非抽象,因預設實作會呼叫 DAL 方法,若在抽象類別中實作會造成循環依賴(IInterface 參考 DAL)。實際邏輯留待 BLL 覆寫。
public class DAL_Regulations : DataOperation<Regulations> {
public override int Add(Regulations model) {
var parameters = new SqlParameter[] {
new SqlParameter("@ID", SqlDbType.Int, 4) { Direction = ParameterDirection.Output },
new SqlParameter("@Title", SqlDbType.NVarChar, 200) { Value = model.Title },
// ... 其他參數
};
SqlHelper.ExecuteNonQuery(connStr, CommandType.StoredProcedure, "usp_Regulations_ADD", parameters);
return (int)parameters[0].Value;
}
public override int Update(Regulations model) {
// 類似實作,呼叫 usp_Regulations_Update
}
// 不覆寫 GetList,避免循環依賴
}
public class BLL_Regulations : DataOperation<Regulations> {
private readonly DAL_Regulations _dal = new DAL_Regulations();
public override int Add(Regulations model) => _dal.Add(model);
public override int Update(Regulations model) => _dal.Update(model);
// 覆寫 GetList,呼叫通用 DAL 查詢方法
public override DataTable GetList(
int pageSize, int pageNumber, string procName,
string condition, string compositor,
out int pageCount, out int recordCount, out int nextPageNumber) {
return DAL_Comm.GetAllInformation(pageSize, pageNumber, procName, condition, compositor,
out pageCount, out recordCount, out nextPageNumber);
}
}
BLL 持有 DAL 參考,打破循環依賴,同時保留查詢邏輯擴展彈性。
// 介面導向程式設計
DataOperation<Regulations> operation = new BLL_Regulations();
// 所有資料表維護頁面統一調用方式
int addResult = operation.Add(model);
int updateResult = operation.Add(model);
DataTable list = operation.GetList(pageSize, pageNum, proc, cond, comp, out pc, out rc, out npn);
| 維度 | 改善說明 |
|---|---|
| 代碼結構 | 純 OOP 結構,操作契約集中在抽象類別,層次分明 |
| 客戶端簡化 | 統一 Add/Update/GetList,無需記憶各表專屬方法名 |
| 團隊協作 | 前端工程師專注 UI 調用抽象介面,後端工程師專注 DAL/BLL 實作,並行開發效率大增 |
| 擴展性 | 新增資料表僅需實作對應 DAL/BLL,介面不變 |