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


12

ดังนั้นฉันจึงสร้าง data access layer ผ่านทาง TDD และได้เข้าหาข้อกังวลเล็กน้อย ฉันไม่ควรเริ่มต้นเส้นทางที่ผิดดังนั้นฉันคิดว่าฉันขอให้พวกคุณดูว่าความคิดของฉันสอดคล้องกับสถาปัตยกรรมที่สะอาดหรือไม่

วิธีการภายใน Data Access Layer ของฉัน (สั้นสำหรับ DAL) จะค่อนข้างง่าย พวกเขาเป็นไปตามขั้นตอนการจัดเก็บในฐานข้อมูล (ไม่มีวิธีอื่นในการโทรเข้าเพื่อรักษาความสะอาด) และพวกเขามีพารามิเตอร์เดียวกันกับที่ทำ พวกเขาเพียงแค่เชื่อมต่อกับฐานข้อมูลและส่งคืนผลลัพธ์แบบสอบถาม นี่คือตัวอย่างหนึ่ง:

public int DeleteRecord(int recordId)
{
    recordId.RequireThat("recordId").NotZeroOrLess();

    List<SqlParameter> parameters = new List<SqlParameter>();
    parameters.Add(new SqlParameter { ParameterName = "@RecordId", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Input, Value = recordId});

    return this.ExecuteNonQuery("DeleteRecord", parameters.ToArray());
}

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

อย่างไรก็ตามพูดในวิธีอื่น DAL ฉันต้องการโหลดบันทึก ขั้นตอนการโหลดของฉันกำลังจะถูกดำเนินการselectsกับพวงของตารางและกลับมาได้DataSetแต่ฉันกำลังต่อสู้กับว่า DAL ฉันควรสร้าง Business Objects ภายในวิธีใช้DataSet, หรือถ้าธุรกิจของฉันวัตถุตัวเองก็ควรจะมีLoad()วิธีการที่ได้รับDataSetจาก DAL และจากนั้นจะเติมตัวเองโดยทั่วไป

การทำผ่าน DAL จะส่งผลให้เกิดตรรกะน้อยลงใน Business Objects (แม้ว่านี่จะเป็นเพียงการเลือกตรรกะมันยังคงเป็นตรรกะ) แต่จะทำให้ DAL ดูเล็กน้อยและทำให้รู้สึกว่ามันกำลังทำสิ่งที่ควรทำ ' ไม่ต้องทำ

พวกคุณคิดอย่างไร


ทำไมคุณไม่ใช้ Entity Framework?
jfrankcarr

@jfrankcarr - พูดตามตรงส่วนใหญ่เป็นเพราะฉันไม่คุ้นเคยกับมันเท่าที่ควร อย่างไรก็ตามฉันจะต้องปรับตารางของฉันใหม่และเพิ่มคีย์ต่างประเทศที่เหมาะสม ฯลฯ เพื่อให้ Entity Framework จดจำความสัมพันธ์ได้อย่างถูกต้อง แต่ถ้าฉันใช้มันด้วยความอยากรู้ฉันจะเลือกทั้งหมดโดยใช้เฟรมเวิร์กกับ Business Objects ด้วยตัวเองหรือจะมีการตัดสินใจว่าจะใส่เคียวรี LINQ เหล่านั้นไว้ที่ไหน

ฉันขอแนะนำให้สละเวลาเรียนภาษา EF ดูเหมือนจะเป็นเรื่องที่ค่อนข้างยุ่งยากในตอนแรกโดยเฉพาะอย่างยิ่งเมื่อพยายามทำให้มันพอดีกับฐานข้อมูลที่มีอยู่ซึ่งมีปัญหาการออกแบบที่มีอยู่แล้ว แต่ก็คุ้มค่า
jfrankcarr

คุณสามารถดู NHibernate ได้หากคุณต้องการดูตัวเลือกอื่น
ดอน 01001100

@jfrankcarr - แน่นอนฉันจะดูมัน แต่มันเข้ากับแอพพลิเคชั่นการเข้าถึงข้อมูลแบบหลายชั้นได้อย่างไร? เฟรมเวิร์กเอนทิตีจะถูกนำไปใช้ภายใน DAL เองหรือภายในเลเยอร์อื่นหรือแม้แต่ Business Objects ด้วยตัวเองหรือไม่

คำตอบ:


4

DAL ของคุณควรส่งคืนวัตถุข้อมูลของคุณ

อุดมคติของคุณ DAL ควรเป็นวัตถุ "กล่องดำ" ที่รหัสแอปพลิเคชันของคุณสามารถใช้เพื่อขอวัตถุข้อมูลหรือจัดการวัตถุข้อมูลที่มีอยู่ บางครั้งมีเลเยอร์อื่นวางอยู่ระหว่าง DAL และรหัสแอปพลิเคชันที่เรียกว่า the Repositoryซึ่งจะแยกเลเยอร์ทั้งสองออกไปแม้ว่าจะไม่จำเป็นเสมอไป

นอกจากนี้คุณมักไม่ต้องการให้วัตถุทางธุรกิจของคุณสามารถสร้างตัวเองได้ สิ่งนี้อาจทำให้เกิดช่องโหว่ด้านความปลอดภัยซึ่งใครบางคนสามารถใช้ไลบรารีของคุณและสร้างอินสแตนซ์ใหม่ของวัตถุของคุณโดยการเรียก.Load(someId)ใช้และรวมสองชั้นเข้าด้วยกันซึ่งควรแยกจากกันอย่างสมบูรณ์

ฉันยังไม่แนะนำให้ใช้.Load(DataSet ds)วิธีการเพราะหากคำจำกัดความชุดข้อมูลมีการเปลี่ยนแปลงคุณจะต้องค้นหาวัตถุข้อมูลที่ใช้ชุดข้อมูลนั้นและเปลี่ยนพวกเขา ง่ายกว่าที่จะเก็บรหัสการเข้าถึงข้อมูลทั้งหมดไว้ในที่เดียวดังนั้นหากคุณเปลี่ยนแบบสอบถามการเข้าถึงข้อมูลคุณควรเปลี่ยน DAL layer ของคุณเท่านั้น


ไม่แน่ใจว่าจะสามารถขึ้นอยู่กับเลเยอร์หนึ่งเพื่อ "ส่งคืนวัตถุที่ถูกต้อง" ได้อย่างไรหากคำจำกัดความของ "วัตถุที่ถูกต้อง" จัดขึ้นในอีกชั้นหนึ่ง
TMN

@TMN นั่นเป็นคำที่ไม่ดี ฉันเปลี่ยนถ้อยคำออกมาเล็กน้อยเพราะคุณพูดถูกรหัสแอปควรรู้ว่าวัตถุชนิดใดที่ขอ
Rachel

@Rachel - Gotcha ดังนั้นคุณจะแนะนำให้ DAL คืนอินสแตนซ์ของวัตถุธุรกิจของฉันเองให้ถูกต้องหรือไม่ ฉันสับสนกับถ้อยคำของ "data object" ของคุณ แต่ฉันคิดว่าฉันเข้าใจ วิธีการที่รหัสของฉันสามารถขอวัตถุธุรกิจจากที่ใดก็ตามจะต้อง (ไม่ผ่านพวกเขาตัวเอง) โดยเพียงแค่โทรBusinessObject bo = DAL.LoadRecord(id);- เสียงใช่มั้ย? ตรรกะในการจับคู่แบบสอบถามกับ BO เองจะมีอยู่ภายใน DAL และมีเพียงแห่งเดียวเท่านั้น

1
@Scott ที่ถูกต้องถึงแม้ว่าผมจะตั้งชื่อสิ่งที่วิธี DAL เช่นGetแทนLoadเช่นCustomer c = DAL.GetCustomer(id);
ราเชล

2

วิธีการของฉันแม้กระทั่งก่อน LINQ-To-SQL และ Entity Framework ก็คือการมีส่วนต่อประสานและไลบรารีระดับนามธรรมที่ให้ "สัญญาที่เป็นลายลักษณ์อักษร" สำหรับการสื่อสารระหว่างเลเยอร์ต่างๆของแอป บางครั้งสิ่งนี้เรียกว่าontologyซึ่งเป็นคำนิยามสำหรับโดเมนงาน สิ่งใดก็ตามที่ผ่านไปมาระหว่างเลเยอร์ใช้ 'สัญญา' นี้

ฉันไม่ชอบความคิดในการส่งข้อมูลชุดข้อมูลดิบจากชั้นข้อมูลไปยังชั้นธุรกิจ ฉันเห็นผลลัพธ์นี้ในปัญหาจำนวนหนึ่งโดยเฉพาะเมื่อรวมแหล่งข้อมูลดั้งเดิม นอกจากนี้ยังสามารถทำให้เป็นเรื่องยากมากสำหรับคนใหม่ที่เข้ามาในโครงการเพื่อทำความเข้าใจว่าข้อมูลมาจากไหน สุดท้ายมันต้องการให้เลเยอร์ธุรกิจของคุณอยู่ในธุรกิจการจัดการข้อมูลโดยตรงจากฐานข้อมูลซึ่งอาจนำไปสู่ปัญหาแทรกซ้อนที่เกิดขึ้นได้

โค้ดตัวอย่างที่คุณมีคล้ายกับรหัสที่ฉันเคยมีใน LINQ ฉันมีคลาสฟังก์ชัน DB ทั่วไปที่ฉันใช้ภายในวัตถุ DAL ของฉัน คลาส DAL จะอ่านข้อมูลและใส่ลงในวัตถุ 'สัญญา' ผลลัพธ์แบบสเกลาร์เช่นตัวอย่างการลบของคุณจะคืนค่ามักเป็นบูลีน


1
"ฉันไม่ชอบความคิดในการส่งวัตถุดาต้าเซ็ตแบบดิบจากชั้นข้อมูลไปยังชั้นธุรกิจ" นี้. พันครั้งนี้
Joshua Smith

@jfrankcarr - DAL ของฉันใช้อินเทอร์เฟซจริงและฉันวางแผนที่จะมีส่วนต่อประสานสำหรับทุกสิ่งที่ถ่ายโอนข้อมูลจากเลเยอร์หนึ่งไปยังเลเยอร์ดังนั้นฉันคิดว่าความคิดรูปแบบของเราตรงกับที่นั่น ดังนั้นคุณแนะนำให้ฉันเปลี่ยนวิธีที่ส่งคืนผลลัพธ์โดยตรงของการExecuteScalarสืบค้นเพื่อคืนค่าที่เหมาะสมกับเลเยอร์ธุรกิจเช่นbool? ฉันคิดว่าอย่างอื่นนี่เป็นคำตอบที่คล้ายกันมากกับราเชล

ปกติแล้วฉันจะส่งคืนบูลีนสำหรับการสร้าง / อัปเดต / ลบการโทรเว้นแต่ฉันต้องการจำนวนระเบียนที่ได้รับผลกระทบ ตัวอย่างเช่นฉันอาจส่งคืน int หาก proc ที่เก็บไว้กำลังประมวลผลคำสั่งซื้อหลายบรรทัดหรืออะไรทำนองนั้น
jfrankcarr

0

DAL ของคุณควรส่งคืนชุดข้อมูล ชุดข้อมูลที่ส่งคืนควรเป็นวัตถุธุรกิจไม่ควรมีสิ่งใดที่คุณต้องทำนอกเหนือจากการตรวจสอบว่ามีข้อมูลที่คาดหวัง หากคุณต้องการทำสิ่งต่าง ๆ ให้มากขึ้นจากนั้นคุณอาจพยายามทำมากเกินไปในขั้นตอนการจัดเก็บครั้งเดียวหรือไม่ส่งคืนข้อมูลอย่างถูกต้องในขั้นตอนการจัดเก็บ


0

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

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