Tôi đang xây dựng giải pháp cấp doanh nghiệp đầu tiên của mình (ít nhất tôi đang cố gắng để làm cho nó cấp doanh nghiệp). Tôi đang cố gắng làm theo các mẫu thiết kế thực hành tốt nhất nhưng tôi bắt đầu lo lắng rằng tôi có thể đi quá xa với sự trừu tượng.Thiết kế n-tier hướng đối tượng. Tôi có trừu tượng quá nhiều không? Hay không đủ?
Tôi đang cố gắng tạo ứng dụng web asp.net (trong C#) dưới dạng ứng dụng n-tier. Tôi đã tạo ra một Lớp truy cập dữ liệu bằng cách sử dụng một tập dữ liệu được đánh giá mạnh XSD có giao diện với một phần cuối máy chủ SQL. Tôi truy cập vào DAL thông qua một số đối tượng lớp kinh doanh mà tôi đã tạo trên cơ sở 1: 1 cho các datatables trong tập dữ liệu (ví dụ, một lớp UsersBLL cho Users datatable trong tập dữ liệu). Tôi đang kiểm tra bên trong BLL để đảm bảo rằng dữ liệu được chuyển đến DAL tuân theo các quy tắc kinh doanh của ứng dụng. Đó là tất cả tốt và tốt. Tôi đang gặp khó khăn mặc dù là điểm mà tại đó tôi kết nối BLL với lớp trình bày. Ví dụ, lớp UsersBLL của tôi giao dịch chủ yếu với toàn bộ datatables, vì nó giao tiếp với DAL. Tôi có nên tạo một lớp "Người dùng" (Singular) riêng biệt để ánh xạ các thuộc tính của một người dùng, thay vì nhiều người dùng không? Bằng cách này, tôi không phải thực hiện bất kỳ tìm kiếm nào thông qua các datatables trong lớp trình bày, vì tôi có thể sử dụng các thuộc tính được tạo trong lớp User. Hoặc nó sẽ là tốt hơn bằng cách nào đó cố gắng xử lý này bên trong UsersBLL?
Xin lỗi nếu điều này nghe có vẻ hơi phức tạp ... Dưới đây là mã từ UsersBLL:
using System;
using System.Data;
using PedChallenge.DAL.PedDataSetTableAdapters;
[System.ComponentModel.DataObject]
public class UsersBLL
{
private UsersTableAdapter _UsersAdapter = null;
protected UsersTableAdapter Adapter
{
get
{
if (_UsersAdapter == null)
_UsersAdapter = new UsersTableAdapter();
return _UsersAdapter;
}
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, true)]
public PedChallenge.DAL.PedDataSet.UsersDataTable GetUsers()
{
return Adapter.GetUsers();
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, false)]
public PedChallenge.DAL.PedDataSet.UsersDataTable GetUserByUserID(int userID)
{
return Adapter.GetUserByUserID(userID);
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, false)]
public PedChallenge.DAL.PedDataSet.UsersDataTable GetUsersByTeamID(int teamID)
{
return Adapter.GetUsersByTeamID(teamID);
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, false)]
public PedChallenge.DAL.PedDataSet.UsersDataTable GetUsersByEmail(string Email)
{
return Adapter.GetUserByEmail(Email);
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Insert, true)]
public bool AddUser(int? teamID, string FirstName, string LastName,
string Email, string Role, int LocationID)
{
// Create a new UsersRow instance
PedChallenge.DAL.PedDataSet.UsersDataTable Users = new PedChallenge.DAL.PedDataSet.UsersDataTable();
PedChallenge.DAL.PedDataSet.UsersRow user = Users.NewUsersRow();
if (UserExists(Users, Email) == true)
return false;
if (teamID == null) user.SetTeamIDNull();
else user.TeamID = teamID.Value;
user.FirstName = FirstName;
user.LastName = LastName;
user.Email = Email;
user.Role = Role;
user.LocationID = LocationID;
// Add the new user
Users.AddUsersRow(user);
int rowsAffected = Adapter.Update(Users);
// Return true if precisely one row was inserted,
// otherwise false
return rowsAffected == 1;
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Update, true)]
public bool UpdateUser(int userID, int? teamID, string FirstName, string LastName,
string Email, string Role, int LocationID)
{
PedChallenge.DAL.PedDataSet.UsersDataTable Users = Adapter.GetUserByUserID(userID);
if (Users.Count == 0)
// no matching record found, return false
return false;
PedChallenge.DAL.PedDataSet.UsersRow user = Users[0];
if (teamID == null) user.SetTeamIDNull();
else user.TeamID = teamID.Value;
user.FirstName = FirstName;
user.LastName = LastName;
user.Email = Email;
user.Role = Role;
user.LocationID = LocationID;
// Update the product record
int rowsAffected = Adapter.Update(user);
// Return true if precisely one row was updated,
// otherwise false
return rowsAffected == 1;
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteUser(int userID)
{
int rowsAffected = Adapter.Delete(userID);
// Return true if precisely one row was deleted,
// otherwise false
return rowsAffected == 1;
}
private bool UserExists(PedChallenge.DAL.PedDataSet.UsersDataTable users, string email)
{
// Check if user email already exists
foreach (PedChallenge.DAL.PedDataSet.UsersRow userRow in users)
{
if (userRow.Email == email)
return true;
}
return false;
}
}
Một số hướng dẫn đi đúng hướng sẽ được đánh giá rất nhiều !!
Cảm ơn tất cả!
Max
Cảm ơn Steven. Chỉ cần làm rõ, bạn có nghĩa là tôi sẽ nhận được DAL để trả về một UserRow đơn chứ không phải toàn bộ DataTable? Ngoài ra, bạn có thể mô tả thêm về phương pháp tải tĩnh không? Cảm ơn! – max
@max: Vui lòng cho tôi biết nếu tôi có thể làm rõ thêm. –
@Steven: Cảm ơn bạn đã làm rõ.Vì vậy, cách tôi hiểu phân lớp như sau (từ DB sang UI): 1) Lớp trừu tượng cơ sở dữ liệu, ví dụ: XSD, LINQ, v.v. * Bao gồm ~ 2 phương pháp - GetUser, GetUsers -> Điền DTO người dùng (a Lớp người dùng đơn giản?) 2) Lớp tĩnh UserDAL mà bạn đã nêu ở trên nhận được User DTO và tạo bộ sưu tập. 3) UserBLL gọi UserDAL của bạn để nhận đối tượng người dùng. 4) Trình diễn lớp gọi UserBLL Điều này có đúng không? Vẫn cố gắng để có được đầu của tôi xung quanh nó. Cảm ơn! – max