การแยกการดึงข้อมูลและวัตถุธุรกิจระหว่างชั้น DAL และ BLL


9

ฉันได้ทำการวิจัยก่อนโพสต์คำถามนี้ ในบรรดาคำถามหรือโพสต์อื่น ๆ ข้อใดข้อหนึ่งมีให้ด้านล่าง ฉันไม่สามารถทราบวิธีการกำหนด ..

วัตถุธุรกิจภายใน Data Access Layer

ฉันมีที่เก็บและชั้นธุรกิจเรียกที่เก็บเพื่อเรียกข้อมูล ตัวอย่างเช่นสมมติว่าฉันมีคลาสต่อไปนี้สำหรับ BLL และ 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; }
}

ถ้า BLL ต้องการเรียกคืนออบเจกต์ลูกค้าจะเรียก GetCustomerById (customerId) ใน DAL

ต่อไปนี้เป็นข้อกังวลของฉันฉันไม่สามารถได้รับใจที่ชัดเจน:

  1. ฉันไม่เห็นวิธีการกำหนดว่าวัตถุใดที่ GetCustomerById ใน DAL ควรกลับมา มันควรจะส่งคืน BllCustomer หรือ DalCustomer หรือไม่

  2. ที่อยู่ที่ควรดึง (และ / หรือแปลงเป็นวัตถุธุรกิจ) ของที่อยู่ที่เชื่อมโยงกับลูกค้าอยู่ที่ไหน

หาก DAL ส่งคืนวัตถุ Dal แล้วตรรกะในการดึงและเติมที่อยู่จะต้องอยู่ใน BLL เท่านั้น หาก DAL ส่งคืนวัตถุ BLL แล้วตรรกะในการดึงและเติมที่อยู่สามารถอยู่ใน BLL หรือ DAL ขณะนี้ DAL กำลังส่งคืน Business Objects และตรรกะในการกรอกข้อมูลนั้นอยู่ใน DAL

จากสิ่งที่ฉันอ่านฉันเดาว่าไม่มีถูกหรือผิด จากลิงค์ด้านบนมีคนพูดทางเดียวและคนอื่นพูดทางอื่น แต่ฉันจะกำหนดได้อย่างไรว่าจะเหมาะที่สุดสำหรับกรณีของฉัน

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม


2
คำถามแรกของฉันคือ: นี่เป็นแอปพลิเคชั่นรุ่นเก่าหรือไม่ มีมากมายของการออมกรอบออกมีที่ทำให้ชนิดของรหัสนี้ล้าสมัยและฉันจะขอให้คุณพิจารณาเช่นกรอบ ...
— JDT

@JDT ฉันไม่แน่ใจว่าคุณหมายถึงอะไรฉันใช้ Entity Framework และมีปัญหาเดียวกัน ตามที่ฉันเข้าใจคุณไม่ควรใช้ ORM ของคุณเป็นวัตถุโดเมนดังนั้นการแปลจะทำที่ใด
— pseudocoder

ทำไมกรอบงาน ORM ของคุณจะไม่ส่งคืนวัตถุที่เป็นวัตถุโดเมนด้วย
— JDT

3
@JDT ORM (EF ในกรณีนี้) ส่งคืนคลาสเอนทิตีที่เป็นตัวแทนโดยปกติแล้วหนึ่งตารางฐานข้อมูลต่อชั้นเรียน ซึ่งมักจะคล้ายกับ แต่ไม่จำเป็นต้องเหมือนกับคลาสโดเมน บางทีคุณอาจจะบอกว่ามันก็โอเคที่จะใช้คลาส ORM เป็นคลาสโดเมน? ฉันได้อ่านในหลาย ๆ ที่ว่าไม่เป็นอะไร
— pseudocoder

คำตอบ:


5

ฉันไม่เห็นวิธีการกำหนดว่าวัตถุใดที่ GetCustomerById ใน DAL ควรกลับมา มันควรจะส่งคืน BllCustomer หรือ DalCustomer หรือไม่

มันควรจะคืนค่าวัตถุDalCustomer การคืนค่าวัตถุBllCustomerจะทำลายหลักการความรับผิดชอบเดี่ยว คุณสามารถดูวัตถุDalCustomerเป็นอินเทอร์เฟซหรือสัญญาที่ใช้โดยชั้นธุรกิจ (หรือผู้บริโภค) ผลถ้ามันคืนBllCustomer DAL จะต้องตอบสนองทุกวัตถุชั้นธุรกิจที่เรียกมันหรืออาจจะเรียกมันว่า

ที่อยู่ที่ควรดึง (และ / หรือแปลงเป็นวัตถุธุรกิจ) ของที่อยู่ที่เชื่อมโยงกับลูกค้าอยู่ที่ไหน

การแปลงควรทำในมุมมองรูปแบบหรือผู้จัดการ คุณต้องมีตัวกลางเพื่อโทรหาบริการหรือส่วนประกอบการเข้าถึงข้อมูลของคุณ หากคุณรู้สึกว่าจำเป็นต้องมีการแปลงในวัตถุBllCustomerของคุณ แต่เมื่อคุณสลับ DAL ของคุณจาก MSSQL เป็น Oracle เช่นวัตถุที่ส่งคืน (หรืออินเทอร์เฟซ) ของคุณจะต้องยังคงเหมือนเดิม

ชั้นธุรกิจของคุณควรเป็นอิสระจากชั้นข้อมูลของคุณด้วย ชั้นธุรกิจมีหน้าที่รับผิดชอบในกฎเกณฑ์ทางธุรกิจของคุณ ที่นี่คุณจะเพิ่มการตรวจสอบของคุณโดยใช้กรอบการตรวจสอบเพื่อบังคับใช้กฎทางธุรกิจของคุณ


4

ที่เก็บของคุณควรส่งคืน BLL หรือวัตถุโดเมน โอกาสที่คุณไม่ต้องการวัตถุ DAL เลย

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 หรือห้องสมุดชั้นแยกต่างหากเปิดเผยอินเตอร์เฟซแทนของการเรียนที่เป็นรูปธรรมเช่นCustomer?
— Yola

1
ไม่ดีที่จะเปิดเผยคลาสที่เป็นรูปธรรม อินเทอร์เฟซสำหรับที่เก็บจะเป็นประโยชน์
— Ewan

3

โดยทั่วไป DAL ไม่มีความรู้เกี่ยวกับ BLL ลองใช้วิธีนี้แอปพลิเคชันอื่นที่มี BLL อื่นสามารถใช้ DAL เดียวกันได้ แอปพลิเคชันเจ้าหนี้ / โมดูลและแอพบัญชีลูกหนี้สำหรับ บริษัท เดียวกันจะแบ่งปันข้อมูล (ลูกค้าค่าใช้จ่ายการชำระเงิน ฯลฯ ) การพยายามมี DLL หนึ่งตัวที่มีความรู้มากกว่าหนึ่ง BLL นั้นยากมากและไม่จำเป็น สิ่งนี้จะช่วยให้คุณเปลี่ยนการจัดเก็บข้อมูลโดยไม่มีผลกระทบกับ BLL (ตราบใดที่คุณไม่ทำลายส่วนต่อประสาน)

ตอนนี้คุณสามารถส่งวัตถุ DAL ไปยัง BLL หรือคุณสามารถสร้างวัตถุชุดที่สาม: เอนทิตี สิ่งเหล่านี้จะมีเพียงค่าที่จะส่งผ่านไปด้วยกัน DAL จะอ้างอิงเอนทิตีและโต้ตอบกับที่เก็บข้อมูล / ฐานข้อมูลของคุณและ BLL จะจัดการกับตรรกะทั้งหมดและอ้างอิง 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
}

ขอบคุณสำหรับความคิดเห็นของคุณ. ฉันเห็นด้วยกับคุณ .. ฉันเห็นแล้วว่า DAL / (Repository) ของเรานั้นเต็มไปด้วย logics เช่นถ้าประเภทคือ A จากนั้นไปเรียกข้อมูลจากตาราง B แต่ถ้าประเภทคือ C แล้วไปดึงข้อมูลจากตาราง C. แต่ฉันสับสนกับตัวอย่างของคุณโดยใช้ EntCustomer ในกรณีของฉัน DalCustomer เป็นมิเรอร์ของตารางใน DB คุณสามารถให้ตัวอย่างเพิ่มเติมเกี่ยวกับการใช้ EntCustomer ได้อย่างไรหรือทำไมฉันจึงควรใช้และประโยชน์ของมันฉันคิดว่าจะเปลี่ยน DAL เพื่อส่ง DalObjects กลับไปที่ BLL Bll จะหยุดการแปลงเป็น Business Objs ดึงและเติม obj ที่ซ้อนกัน
— ShamirDaj

คุณสามารถให้ข้อเสนอแนะเพิ่มเติมได้หรือไม่
— ShamirDaj

ฉันคิดว่าจุดประสงค์ของอ็อบเจกต์ Ent คือการถ่ายโอนข้อมูลระหว่าง DAL และ BLL คลาส DAL ของคุณสามารถทำมิเรอร์โครงสร้าง db ต่อไป แต่คลาสเหล่านั้นจะอยู่ภายในกับ DAL เมื่อ BLL ขอข้อมูลจาก DAL DAL จะดึงข้อมูล DAL- วัตถุที่ต้องการจากฐานข้อมูล (dalcustomer + daladdress) และสร้างอินสแตนซ์ของ EntCustomer จากพวกเขาและส่งกลับไปยัง BLL
— artokai

-1

DAL ควรเป็นอิสระจาก BL และ BL ขึ้นอยู่กับ DAL UI ของคุณควรเข้าถึงข้อมูลผ่าน BL เท่านั้น เป็นแนวปฏิบัติที่ดีหากคุณส่งคืน DataTable หรือ DataRow จาก DAL แล้วแปลง DataTable / DataRow เป็นวัตถุ BL เมื่อ UI ของคุณต้องการเข้าถึงข้อมูลก็สามารถเข้าถึงได้จาก BL ดังนั้น UI จะเป็นอิสระจากชื่อคอลัมน์และประเภทฐานข้อมูล (SQL Server, Oracle .. ) วิธีนี้ UI ของคุณจะเป็นอิสระจาก DAL โดยสิ้นเชิง ส่วนตัวฉันชอบชื่อชั้นเช่น "CustomerBL" อย่าใช้คำว่า BL ในการขอชื่อชั้น

ดูตัวอย่างด้านล่าง

//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;
    }
}

เอ่อ ... นั่นไม่ได้หมายความว่า BLL ของคุณจำเป็นต้องมีความรู้เกี่ยวกับรูปแบบ / โครงสร้างของตารางข้อมูลของคุณหรือไม่ ...
— Paul
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.