Tách các dữ liệu và các đối tượng kinh doanh giữa các lớp DAL và BLL


9

Tôi đã làm một số nghiên cứu trước khi đăng câu hỏi này. Trong số các câu hỏi hoặc bài đăng khác, một trong những câu hỏi được cung cấp dưới đây. Tôi không thể có được một tâm trí rõ ràng làm thế nào để xác định ..

Đối tượng kinh doanh trong lớp truy cập dữ liệu

Tôi có một Kho lưu trữ và Lớp nghiệp vụ gọi kho lưu trữ để lấy dữ liệu. Ví dụ: giả sử tôi có các lớp sau cho BLL và DAL:

class BllCustomer
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public BllAddress Address {get; set;}
}

class BllAddress
{
     public int AddressId {get; set;}
     public String Street {get; set;}
     public String City {get; set;}
     public String ZipCode {get; set; }
}

class DalCustomer 
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public int AddressID {get; set;}
}

class DalAddress
{
     public int AddressId {get; set;}
     public String Street {get; set;}
     public String City {get; set;}
     public String ZipCode {get; set; }
}

Nếu BLL muốn truy xuất một đối tượng Khách hàng, nó sẽ gọi GetCustomerById (customerId) trong DAL.

Sau đây là những lo lắng của tôi, tôi không thể có được một tâm trí rõ ràng:

  1. Tôi không thể thấy cách xác định đối tượng mà GetCustomerById trong DAL sẽ trả về? Nó nên trả lại BllCustomer hoặc DalCustomer?

  2. Nơi nào nên truy xuất (và / hoặc chuyển đổi thành đối tượng Doanh nghiệp) của địa chỉ được liên kết với khách hàng?

Nếu DAL trả về các đối tượng Dal thì logic để truy xuất và điền Địa chỉ chỉ có thể có trong BLL. Nếu DAL trả về các đối tượng BLL, thì logic để truy xuất và điền vào Địa chỉ có thể ở trong BLL hoặc DAL. Hiện tại DAL đang trả về các Đối tượng Kinh doanh và logic để điền vào đó là trong DAL.

Từ những gì tôi đọc, tôi đoán không có đúng hay sai. Từ liên kết bao gồm ở trên, có những người nói một cách và những người khác đang nói theo cách khác. Nhưng làm thế nào để tôi xác định cái nào sẽ hoạt động tốt nhất cho trường hợp của tôi?

Bất kỳ trợ giúp sẽ được đánh giá cao.


2
Câu hỏi đầu tiên của tôi sẽ là: đây có phải là một ứng dụng cũ không? Có rất nhiều Khung ORM ngoài kia làm cho loại mã này trở nên lỗi thời và tôi mong bạn hãy xem xét một khung như vậy ...
JDT

@JDT Tôi không chắc ý của bạn là gì, tôi đang sử dụng Entity Framework và có cùng một vấn đề. Theo tôi hiểu, bạn không được phép sử dụng ORM của mình làm đối tượng miền, vậy bản dịch được thực hiện ở đâu?
giả mã

Tại sao khung ORM của bạn cũng không trả về các đối tượng là đối tượng miền?
JDT

3
@JDT ORM (EF trong trường hợp này) trả về các lớp thực thể đại diện, thông thường, một bảng cơ sở dữ liệu cho mỗi lớp. Điều này thường tương tự, nhưng không nhất thiết giống như các lớp miền. Có lẽ bạn chỉ nói rằng sử dụng các lớp ORM làm các lớp miền là ổn? Tôi đã đọc ở một số nơi rằng điều này là không.
giả mã

Câu trả lời:


5

Tôi không thể thấy cách xác định đối tượng mà GetCustomerById trong DAL sẽ trả về? Nó nên trả lại BllCustomer hoặc DalCustomer?

Nó sẽ trả về một đối tượng DalCustomer , trả về một đối tượng BllCustomer sẽ phá vỡ nguyên tắc trách nhiệm đơn lẻ . Bạn có thể xem đối tượng DalCustomer là giao diện hoặc hợp đồng được sử dụng bởi tầng doanh nghiệp (hoặc người tiêu dùng). Trong thực tế, nếu nó trả về BllCustomer , DAL sẽ phải phục vụ cho mọi đối tượng lớp doanh nghiệp gọi nó hoặc có khả năng gọi nó.

Nơi nào nên truy xuất (và / hoặc chuyển đổi thành đối tượng Doanh nghiệp) của địa chỉ được liên kết với khách hàng?

Việc chuyển đổi nên được thực hiện trong mô hình xem hoặc trình quản lý. Bạn cần phải có một trung gian để gọi dịch vụ hoặc thành phần truy cập dữ liệu của bạn. Nếu bạn cảm thấy cần thiết, bạn có thể có một chuyển đổi trong đối tượng BllCustomer của mình . Nhưng sau đó khi bạn trao đổi DAL của bạn từ MSSQL sang Oracle, ví dụ đối tượng (hoặc giao diện) được trả về của bạn phải giữ nguyên.

Tốt nhất là lớp doanh nghiệp của bạn cũng phải độc lập với Lớp dữ liệu của bạn. Tầng doanh nghiệp chịu trách nhiệm cho các quy tắc kinh doanh của bạn. Tại đây, bạn sẽ thêm các xác nhận của mình bằng khung xác thực để thực thi các quy tắc kinh doanh của bạn.


4

Kho lưu trữ của bạn sẽ trả về BLL hoặc đối tượng miền. rất có thể bạn không cần một đối tượng DAL nào cả.

public class Customer
{
    public string Name {get; private set;}
    public Customer(string name)
    {
        this.Name = name;
    }
}

public class Repository
{
    public Customer GetCustomer(string id)
    {
        //get data from db
        return new Customer(datarow["name"]);
    }
}

BLL hoặc thư viện lớp riêng biệt nên phơi bày giao diện thay vì các lớp cụ thể như thế Customernào?
Yola

1
Không. Nó tốt để lộ các lớp bê tông. Một giao diện cho kho lưu trữ sẽ hữu ích
Ewan

3

Thông thường, DAL không có kiến ​​thức về BLL. Hãy nghĩ về nó theo cách này, một ứng dụng khác với BLL khác có thể sử dụng cùng một DAL. Ứng dụng / mô-đun phải trả và ứng dụng Phải thu cho cùng một công ty sẽ chia sẻ dữ liệu (khách hàng, chi phí, thanh toán, v.v.). Cố gắng để có một DLL có kiến ​​thức về nhiều hơn một BLL sẽ rất khó khăn và không cần thiết. Điều này cũng sẽ cho phép bạn thay đổi bộ lưu trữ dữ liệu của mình mà không ảnh hưởng đến BLL (miễn là bạn không phá vỡ các giao diện).

Bây giờ bạn có thể chuyển một đối tượng DAL cho BLL hoặc bạn có thể tạo một bộ đối tượng thứ ba: Thực thể. Chúng chỉ chứa các giá trị được truyền xung quanh cùng nhau. DAL sẽ tham chiếu thực thể và tương tác với bộ lưu trữ / cơ sở dữ liệu của bạn và BLL sẽ xử lý tất cả logic và tham chiếu DAL.

class EntCustomer
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public BllAddress Address {get; set;}
}
class BllCustomer
{
   //reference EntCustomer, DalCustomer and handle business rules/logic
}

class DalCustomer 
{
   //reference EntCustomer and interact with data storage
}

Cảm ơn bình luận của bạn. Tôi đồng ý với bạn .. Tôi có thể thấy rằng DAL / (Kho lưu trữ) của chúng tôi đã được điền đầy đủ các logic như nếu loại là A, sau đó truy xuất dữ liệu từ bảng B, nhưng nếu loại là C, thì hãy truy xuất dữ liệu từ bảng C. Nhưng tôi bối rối với ví dụ của bạn khi sử dụng EntCustomer. Trong trường hợp của tôi, DalCustomer là tấm gương của các bảng trong DB. Bạn có thể cung cấp thêm ví dụ, cách EntCustomer được sử dụng hoặc lý do tôi nên sử dụng nó và lợi ích của nó. Tôi đang suy nghĩ thay đổi DAL để trả lại DalObjects cho BLL. Bll sẽ treo chuyển đổi sang Business Objs, truy xuất và điền vào obj lồng nhau.
ShamirDaj

Bạn có thể cung cấp thêm thông tin phản hồi?
ShamirDaj

Tôi nghĩ rằng mục đích của các đối tượng Ent là chỉ truyền dữ liệu giữa DAL và BLL. Các lớp DAL của bạn có thể tiếp tục phản chiếu cấu trúc db, nhưng các lớp đó sẽ là nội bộ của DAL. Khi BLL yêu cầu dữ liệu từ DAL, DAL sẽ tìm nạp các đối tượng DAL cần thiết từ cơ sở dữ liệu (dalcustomer + daladdress) và xây dựng một thể hiện của EntCustomer từ chúng và trả lại cho BLL.
artokai

-1

DAL phải độc lập với BL và BL phụ thuộc vào DAL. Giao diện người dùng của bạn chỉ nên truy cập dữ liệu qua BL. Thực hành tốt nếu bạn trả lại DataTable hoặc DataRow từ DAL và sau đó Chuyển đổi DataTable / DataRow thành (các) đối tượng BL. Khi UI của bạn cần truy cập dữ liệu, nó có thể truy cập từ BL. Vì vậy, UI sẽ độc lập với tên cột và loại Cơ sở dữ liệu (SQL Server, Oracle ..). Bằng cách này, UI của bạn sẽ hoàn toàn độc lập với DAL. Cá nhân tôi thích tên lớp như "CustomerBL", Đừng sử dụng từ BL trong việc cầu xin tên lớp.

Dưới đây xem Mã mẫu.

//Customer Class
class BllCustomer
{
    public int CustomerId { get; set; }
    public String Name { get; set; }
    public BllAddress Address { get; set; }

    public static BllCustomer GetByCustomerId(int id)
    {
        DataRow dr = DalCustomer.GetByCustomerId(id);
        if (dr == null)
            return null;
        BllCustomer oCust = new BllCustomer();
        oCust.CustomerId = int.Parse(dr["CustomerId"].ToString());
        //Do for other class members and load values

        return oCust;
    }
}


class DalCustomer
{

    public static DataRow GetByCustomerId(int id)
    {
        //Get Data row from Database and return Datarow
        DataRow CustomerRow = GETFROMDATABASE("SELECT * from CUSTOMER");
        return CustomerRow;
    }
}

Err ... Điều đó không có nghĩa là BLL của bạn cần có kiến ​​thức về định dạng / cấu trúc của các bảng dữ liệu của bạn phải không? ...
Paul
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.