แบบแผนการตั้งชื่อ DAL, BAL และเลเยอร์ UI [ปิด]


35

ฉันกำลังพัฒนาเว็บแอปพลิเคชันทั่วไปด้วยเลเยอร์ต่อไปนี้

  1. เลเยอร์ UI (MVC)
  2. ชั้นตรรกะทางธุรกิจ (BAL)
  3. ชั้นการเข้าถึงข้อมูล (DAL)

แต่ละชั้นมีวัตถุ DTO ของตัวเองรวมถึง BAL และ DAL คำถามของฉันเกี่ยวกับเรื่องนี้มีดังนี้

  1. DTO ที่ส่งคืนโดย DAL จะถูกแปลงเป็น DTO ที่สอดคล้องกันใน BAL และส่งไปยังเลเยอร์ UI ทั้งคุณลักษณะและโครงสร้างของวัตถุ DTO เหมือนกันในบางกรณี ในสถานการณ์ดังกล่าวจะเป็นการดีกว่าที่จะเพียงแค่ส่งกลับ DTO ใน DAL ไปยังเลเยอร์ UI โดยไม่รวมวัตถุระดับกลาง

  2. เป็นวิธีที่ดีที่สุดในการตั้งชื่อวัตถุ DTO เหล่านี้และวัตถุอื่น ๆ ในแต่ละชั้น ฉันควรใช้คำนำหน้าเช่น DTOName, ServiceName หรือไม่ เหตุผลที่ฉันขอให้ใช้คำนำหน้าเป็นเพราะถ้าไม่ใช่คลาสในโซลูชันของฉันขัดแย้งกับคลาสอื่น ๆ ใน Framework และด้วยคำนำหน้ามันง่ายกว่าที่ฉันจะเข้าใจว่าแต่ละคลาสอยู่ที่ไหน?



1
คุณใช้เนมสเปซหรือไม่
JeffO

คำตอบ:


49

คำนำ

หวังว่านี่จะชัดเจน แต่ ... ในเนมสเปซที่แนะนำด้านล่างคุณจะแทนที่MyCompanyและMyProjectด้วยชื่อจริงของ บริษัท และโครงการของคุณ

DTOs

ฉันอยากจะแนะนำให้ใช้คลาส DTO เดียวกันกับทุกเลเยอร์ มีจุดบำรุงรักษาน้อยลง ฉันมักจะทำให้พวกเขาอยู่ภายใต้MyCompany.MyProject.Modelsnamespace ในโครงการ VS ของพวกเขาเองที่มีชื่อเดียวกัน และฉันมักจะตั้งชื่อพวกเขาตามเอนทิตีในโลกแห่งความจริงที่พวกเขาเป็นตัวแทน (เป็นการดีตารางฐานข้อมูลจะใช้ชื่อเดียวกันด้วย แต่บางครั้งมันก็สมเหตุสมผลที่จะตั้งค่าสคีมาให้แตกต่างกันเล็กน้อย)

ตัวอย่าง: Person, Address,Product

การพึ่งพา: ไม่มี (นอกเหนือจากมาตรฐาน. NET หรือไลบรารีผู้ช่วยเหลือ)

DAL

ความชอบส่วนตัวของฉันที่นี่คือการใช้คลาส DAL หนึ่งต่อหนึ่งที่ตรงกับคลาส DTO แต่ในMyCompany.MyProject.DataAccessเนมสเปซ / โปรเจ็กต์ ชื่อคลาสที่นี่ลงท้ายด้วยEngineคำต่อท้ายเพื่อหลีกเลี่ยงความขัดแย้ง (ถ้าคุณไม่ชอบคำนั้นDataAccessคำต่อท้ายก็จะใช้ได้เช่นกันเพียงแค่สอดคล้องกับสิ่งที่คุณเลือก) แต่ละคลาสจะมีตัวเลือก CRUD อย่างง่าย ๆ ที่กระทบฐานข้อมูลโดยใช้คลาส DTO สำหรับพารามิเตอร์อินพุตและประเภทการส่งคืน (ภายใน ทั่วไปListเมื่อมีมากกว่าหนึ่งเช่นผลตอบแทนจากFind()วิธีการ)

ตัวอย่าง: PersonEngine, AddressEngine,ProductEngine

อ้างอิง: MyCompany.MyProject.Models

BAL / BLL

นอกจากนี้การแม็พแบบหนึ่งต่อหนึ่งที่นี่ แต่ในMyCompany.MyProject.Logicเนมสเปซ / โปรเจ็กต์และด้วยคลาสที่ได้รับLogicส่วนต่อท้าย นี่ควรเป็นเลเยอร์เดียวที่เรียกใช้ DAL! ชั้นเรียนที่นี่มักจะเป็นเพียงการส่งผ่านไปยัง DAL ที่เรียบง่าย แต่ถ้า & เมื่อจำเป็นต้องดำเนินการตามกฎเกณฑ์ทางธุรกิจนี่เป็นสถานที่สำหรับมัน

ตัวอย่าง: PersonLogic, AddressLogic,ProductLogic

การพึ่งพา: MyCompany.MyProject.Models,MyCompany.MyProject.DataAccess

API

หากมีเลเยอร์ API ของบริการบนเว็บฉันจะใช้วิธีการแบบหนึ่งต่อหนึ่งเหมือนกัน แต่ในMyCompany.MyProject.WebApiเนมสเปซ / โครงการที่มีServicesส่วนต่อท้ายของคลาส (ยกเว้นว่าคุณกำลังใช้ ASP.NET Web API ซึ่งแน่นอนว่าคุณควรใช้Controllerส่วนต่อท้ายแทน)

ตัวอย่าง: PersonServices, AddressServices,ProductServices

การพึ่งพา: MyCompany.MyProject.Models, MyCompany.MyProject.Logic(อย่าข้ามสิ่งนี้โดยการเรียก DAL โดยตรง!)

ข้อสังเกตเกี่ยวกับตรรกะทางธุรกิจ

ดูเหมือนว่าจะเป็นเรื่องธรรมดามากขึ้นสำหรับคนที่จะไม่ละทิ้ง BAL / BLL และใช้ตรรกะทางธุรกิจในเลเยอร์อื่นอย่างน้อยหนึ่งชั้นทุกที่ที่เหมาะสมที่สุด หากคุณทำสิ่งนี้ให้แน่ใจว่า (1) รหัสแอปพลิเคชันทั้งหมดผ่านเลเยอร์พร้อมกับตรรกะทางธุรกิจและ (2) เป็นสิ่งที่ชัดเจนและ / หรือมีเอกสารชัดเจนที่มีการใช้กฎธุรกิจเฉพาะแต่ละรายการ หากมีข้อสงสัยอย่าลองทำที่บ้าน

หมายเหตุสุดท้ายเกี่ยวกับสถาปัตยกรรมระดับองค์กร

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


2
ฉันรู้ว่านี่เป็นโพสต์โบราณ แต่ในจิตวิญญาณของการรับรู้ ฉันแค่อยากจะบอกว่าฉันพบว่าเรื่องนี้เป็นประโยชน์อย่างยิ่งในหัวข้อที่ทำให้เกิดการอภิปราย ขอบคุณที่แชร์สิ่งนี้!
James Shaw

7

ฉันมักจะสร้างแอปพลิเคชันเป็น

ProjectName.Core            // "framework"/common stuff
|- Extenders
|- Gravatar.cs

ProjectName.DataProvider    // database provider layer
|- Migrations
|- ApplicationDbContext.cs  // entity framework

ProjectName.Domain          // database objects
|- Post.cs
|- Tag.cs

ProjectName.Services        // validations, database stuff
|- PostService.cs

มันจะค่อนข้างคล้ายกับSharp-Lite

เกี่ยวกับคำนำหน้าฉันเกลียดพวกเขา หลักเกณฑ์การเข้ารหัสภายในของ Microsoft ก็เกลียดพวกเขาเช่นกัน นอกจากนี้ยังมีเครื่องมือที่เรียกว่า StyleCop ที่บ่นเกี่ยวกับคำนำหน้าเช่นกัน


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