การแยกการดึงข้อมูลและวัตถุธุรกิจระหว่างชั้น 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.