ฉันได้ปรับการออกแบบที่ขับเคลื่อนด้วยโดเมนมาประมาณ 8 ปีแล้วและแม้กระทั่งหลังจากทุกปีเหล่านี้ก็ยังมีสิ่งหนึ่งที่ทำให้ฉันเบื่อ นั่นคือการตรวจสอบระเบียนที่ไม่ซ้ำกันในการจัดเก็บข้อมูลกับวัตถุโดเมน
ในเดือนกันยายน 2013 Martin Fowler ได้กล่าวถึงหลักการ TellDonnaAskซึ่งหากเป็นไปได้ควรนำไปใช้กับวัตถุโดเมนทั้งหมดซึ่งควรจะส่งคืนข้อความว่าการดำเนินการเป็นไปอย่างไร (ในการออกแบบเชิงวัตถุ การดำเนินการไม่สำเร็จ)
โครงการของฉันมักจะแบ่งออกเป็นหลายส่วนโดยที่สองในนั้นเป็นโดเมน (ที่มีกฎเกณฑ์ทางธุรกิจและไม่มีสิ่งอื่นใดโดเมนนั้นยังคงอยู่อย่างไม่รู้ตัว) และบริการ บริการที่ทราบเกี่ยวกับเลเยอร์พื้นที่เก็บข้อมูลที่ใช้กับข้อมูล CRUD
เนื่องจากความเป็นเอกลักษณ์ของคุณสมบัติที่เป็นของวัตถุคือกฎของโดเมน / ธุรกิจจึงควรจะยาวไปยังโมดูลของโดเมนดังนั้นกฎจึงตรงตามที่ควรจะเป็น
เพื่อให้สามารถตรวจสอบเอกลักษณ์ของระเบียนคุณต้องค้นหาชุดข้อมูลปัจจุบันซึ่งมักจะเป็นฐานข้อมูลเพื่อค้นหาไม่ว่าจะมีระเบียนอื่นที่มีการสมมติว่าName
มีอยู่แล้ว
เมื่อพิจารณาว่าเลเยอร์ของโดเมนนั้นไม่รู้มานานแล้วและไม่รู้ว่าจะดึงข้อมูลได้อย่างไร แต่จะทำอย่างไรกับการดำเนินการกับมันพวกมันไม่สามารถสัมผัสที่เก็บข้อมูลได้
การออกแบบที่ฉันได้รับการปรับตัวแล้วมีลักษณะเช่นนี้:
class ProductRepository
{
// throws Repository.RecordNotFoundException
public Product GetBySKU(string sku);
}
class ProductCrudService
{
private ProductRepository pr;
public ProductCrudService(ProductRepository repository)
{
pr = repository;
}
public void SaveProduct(Domain.Product product)
{
try {
pr.GetBySKU(product.SKU);
throw Service.ProductWithSKUAlreadyExistsException("msg");
} catch (Repository.RecordNotFoundException e) {
// suppress/log exception
}
pr.MarkFresh(product);
pr.ProcessChanges();
}
}
สิ่งนี้นำไปสู่การมีบริการที่กำหนดกฎของโดเมนแทนที่จะเป็นเลเยอร์ของโดเมนและคุณมีกฎที่กระจัดกระจายในหลายส่วนของรหัสของคุณ
ฉันพูดถึงหลักการ TellDonnaAsk เพราะอย่างที่คุณสามารถเห็นได้อย่างชัดเจนบริการนั้นมีการดำเนินการ (ซึ่งจะช่วยประหยัดProduct
หรือทำให้เกิดข้อยกเว้น) แต่ภายในวิธีการที่คุณใช้กับวัตถุผ่านการใช้วิธีการตามขั้นตอน
วิธีแก้ปัญหาที่ชัดเจนคือการสร้างDomain.ProductCollection
คลาสด้วยAdd(Domain.Product)
วิธีการขว้างProductWithSKUAlreadyExistsException
แต่มันขาดประสิทธิภาพมากเพราะคุณจะต้องได้รับผลิตภัณฑ์ทั้งหมดจากการจัดเก็บข้อมูลเพื่อหารหัสว่าผลิตภัณฑ์มี SKU เดียวกันหรือไม่ เป็นผลิตภัณฑ์ที่คุณพยายามเพิ่ม
พวกคุณแก้ปัญหาเฉพาะนี้ได้อย่างไร นี่ไม่ใช่ปัญหาจริง ๆ ต่อฉันมีเลเยอร์บริการแสดงกฎของโดเมนบางปี เลเยอร์บริการมักจะให้บริการการดำเนินงานโดเมนที่ซับซ้อนมากขึ้นฉันเพียงแค่สงสัยว่าคุณได้เจอปัญหาที่ดีกว่าและรวมศูนย์มากขึ้นในระหว่างการทำงานหรือไม่