ด้วยบริการเหล่านี้ทั้งหมดฉันจะไม่เป็นโลหิตจางได้อย่างไร


90

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

ใช้ความกังวลต่อไปนี้เป็นตัวอย่าง:

การอนุญาต วัตถุโดเมนควรรับผิดชอบในการรักษากฎการควบคุมการเข้าถึง (เช่นคุณสมบัติ CanEdit) หรือควรมอบให้แก่ส่วนประกอบ / บริการอื่นที่รับผิดชอบการจัดการการเข้าถึงเช่น IAuthorizationService.CanEdit (วัตถุ)? หรือมันควรจะเป็นการรวมกันของทั้งสอง? บางทีวัตถุโดเมนมีคุณสมบัติ CanEdit ซึ่งมอบหมายให้กับ IAuthorizationService ภายในเพื่อทำงานจริงหรือไม่

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

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

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

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

ดูว่าฉันจะไปกับอะไร

Rockford Lhotka มีการสนทนาที่ยอดเยี่ยมเกี่ยวกับเหตุผลของเขาในการไปสู่เส้นทาง Class-in-Charge สำหรับกรอบ CSLA ของเขาและฉันมีประวัติเล็กน้อยเกี่ยวกับกรอบนั้นและสามารถเห็นความคิดของเขาเกี่ยวกับวัตถุทางธุรกิจที่ขนานกับวัตถุโดเมนในหลาย ๆ แต่พยายามที่จะยึดมั่นในอุดมคติ DDD ที่ดีขึ้นฉันสงสัยว่าเมื่อใดที่การทำงานร่วมกันมากเกินไป

ถ้าฉันจบด้วย IAuthorizationService, IValidator, IFactory และ IRepository สำหรับรูทรวมของฉันจะมีอะไรเหลือ มีวิธีการเผยแพร่ที่เปลี่ยนสถานะของวัตถุจากแบบร่างเป็นเผยแพร่มากพอที่จะพิจารณาว่าเป็นวัตถุโดเมนแบบไม่มีโลหิตหรือไม่

ความคิดของคุณ?


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

คำถามที่ดีอยากจะเห็นลุงบ๊อบมาร์ตินเลอร์เอริคแวนและคนอื่น ๆ ในเรื่องนี้ ตอนนี้ให้ฉันจากไปและลองคิดดู
Martijn Verburg

ฉันพบว่าตัวเองกำลังพัฒนาเป็นแบบจำลองโลหิตจางตลอดเวลา และฉันก็ต้องดิ้นรนกับสิ่งเดียวกันนี้ เป็นคำถามที่ดีมาก!
L-Four

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

นี่คือตัวอย่างของเทคนิคบางอย่างที่ใช้เมื่อสร้างโมเดลโดเมนจากมุมมองเชิงพฤติกรรม (ไม่ใช่ข้อมูลเป็นศูนย์กลาง): medium.com/@wrong.about/…
Zapadlo

คำตอบ:


66

ความสับสนส่วนใหญ่ดูเหมือนว่าจะมีฟังก์ชั่นการใช้งานที่ไม่ควรมีอยู่ในตัวแบบโดเมนเลย:

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

  • การอนุมัติไม่ได้โดยทั่วไปส่วนหนึ่งของรูปแบบโดเมนของคุณจนกว่ามันเป็นจริงส่วนหนึ่งของโดเมนเช่นถ้าคุณกำลังเขียนซอฟต์แวร์รักษาความปลอดภัย กลไกของผู้ที่ได้รับอนุญาตให้ดำเนินการสิ่งที่อยู่ในแอปพลิเคชันได้รับการจัดการตามปกติที่ "edge" ของชั้นธุรกิจ / โดเมนส่วนสาธารณะที่ UI และส่วนการรวมได้รับอนุญาตให้พูดคุยกับ - คอนโทรลเลอร์ใน MVC บริการ หรือระบบการส่งข้อความใน SOA ... คุณจะได้ภาพ

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

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

ดังนั้นเมื่อคุณสนามหญ้าเหล่านั้นทั้งหมดที่เพิ่งออกการตรวจสอบ นั่นเป็นเพียงคนเดียวที่มีเล่ห์เหลี่ยม

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

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

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

ตามกฎทั่วไปเมื่อพิจารณาว่ามีบางสิ่งอยู่ในรูปแบบโดเมนหรือไม่ให้ถามคำถามต่อไปนี้กับตัวเอง:

"ฟังก์ชันนี้สามารถเปลี่ยนแปลงด้วยเหตุผลทางเทคนิคได้หรือไม่" ในคำอื่น ๆ ไม่ใช่เนื่องจากการเปลี่ยนแปลงที่สังเกตเห็นได้ในธุรกิจหรือโดเมนโลกแห่งความจริง?

หากคำตอบคือ "ใช่" แสดงว่าไม่ได้อยู่ในรูปแบบโดเมน มันไม่ได้เป็นส่วนหนึ่งของโดเมน

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

หากหลังจากที่คุณแยกสิ่งที่ไม่สำคัญออกแล้วคุณจะพบว่ารูปแบบโดเมนนั้นเป็นโลหิตจางจริง ๆและนั่นควรจะเป็นตัวบ่งชี้ที่ดีว่า DDD เป็นเพียงกระบวนทัศน์ที่ผิดสำหรับโครงการของคุณ

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

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


2
นอกจากนี้ @SonOfPirate ก็ไม่น่าเป็นไปได้อย่างสิ้นเชิงที่คุณต้องการเปลี่ยนรูปแบบการรักษาความปลอดภัยทั้งหมดของคุณในบางครั้ง; การรักษาความปลอดภัยตามบทบาทมักล้าสมัยเพื่อรักษาความปลอดภัยตามการเรียกร้องหรือตามสิทธิหรือคุณอาจต้องการความปลอดภัยระดับเขต ลองนึกภาพการพยายามสร้างโมเดลโดเมนทั้งหมดของคุณใหม่หากเกิดเหตุการณ์นี้
Aaronaught

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

1
@ LaurentBourgault-Roy: ขอโทษฉันไม่เชื่อคุณ ทุก บริษัท สามารถพูดได้ว่าเกี่ยวกับทุกการใช้งาน ท้ายที่สุดแล้วการเปลี่ยนฐานข้อมูลเป็นเรื่องยาก นั่นไม่ได้ทำให้มันเป็นส่วนหนึ่งของโดเมนของคุณและตรรกะทางธุรกิจที่อยู่คู่กับเลเยอร์คงอยู่ก็หมายถึงสิ่งที่เป็นนามธรรม รูปแบบโดเมนมุ่งเน้นไปที่พฤติกรรมซึ่งเป็นสิ่งที่ติดตาไม่ นี่ไม่ใช่หัวข้อที่ผู้คนสามารถประดิษฐ์คำจำกัดความของตนเอง มันสะกดออกมาได้ชัดเจนใน DDD บ่อยครั้งที่คุณไม่ต้องการรูปแบบโดเมนสำหรับ CRUD หรือแอปรายงาน แต่คุณไม่ควรอ้างว่าคุณมีรูปแบบเมื่อคุณไม่ต้องการ
Aaronaught

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

1
การอนุญาตประเภทอื่นอาจเป็นการ จำกัด บัญชีลูกค้า พนักงานบริการลูกค้าตามปกติสามารถยกระดับเป็นจุดหนึ่งได้ แต่ข้อ จำกัด ที่สูงขึ้นอาจต้องได้รับการอนุมัติจากฝ่ายบริหาร นั่นคือตรรกะการอนุญาต
Andy

6

การอนุญาต หากวัตถุโดเมนมีหน้าที่รับผิดชอบในการรักษากฎการควบคุมการเข้าถึง

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

การแบ่งปันกลยุทธ์การให้สิทธิ์ข้ามเลเยอร์ (ใน UI และเพิ่มเติมในบริการหรือตัวจัดการคำสั่ง) นั้นง่ายขึ้นเมื่อการอนุญาตถูกแยกเป็นส่วนประกอบจากโมเดลโดเมน

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

การตรวจสอบ การสนทนาเช่นเดียวกับข้างต้นเกี่ยวข้องกับการตรวจสอบ

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

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

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

การสร้างวัตถุ คลาสของโรงงานเทียบกับวิธีการของโรงงานกับ 'newing'

ฉันใช้การเบี่ยงเบนชั้นหนึ่ง ในโครงการเมื่อเร็ว ๆ นี้ของฉันนี้เป็นคำสั่ง + CreateNewAccountCommandจัดการสำหรับการสร้างบางสิ่งบางอย่างเช่น อาจมีทางเลือกอื่นให้ใช้โรงงาน (แม้ว่าอาจจะอึดอัดใจหากการดำเนินงานส่วนที่เหลือถูกเปิดเผยโดยชั้นบริการที่แยกจากชั้นโรงงาน)

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

วิริยะ. ... ทำไมไม่มีวิธีการบันทึกบนวัตถุโดเมนของเรา

นี่เป็นความคิดที่ไม่ค่อยดีนัก ฉันคิดว่ามีการแบ่งปันประสบการณ์มากมายเพื่อสนับสนุนสิ่งนั้น

ถ้าฉันจบด้วย IAuthorizationService, IValidator, IFactory และ IRepository สำหรับรูทรวมของฉันจะมีอะไรเหลือ มีวิธีการเผยแพร่ที่เปลี่ยนสถานะของวัตถุจากแบบร่างเป็นเผยแพร่มากพอที่จะพิจารณาคลาสของวัตถุโดเมนที่ไม่เป็นโลหิตจางหรือไม่ ???

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


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

@SonOfPirate: ตัวจัดการเหตุการณ์ที่ฟังเหตุการณ์โดเมนและอัปเดตตารางที่เฉพาะเจาะจงมากกับความต้องการของแบบสอบถามที่ตรวจสอบการอนุญาต ตรรกะที่ตรวจสอบสถานะและกำหนดว่าบทบาทหรือบุคคลนั้นได้รับอนุญาตหรือไม่อาศัยอยู่ในตัวจัดการเหตุการณ์ (ดังนั้นตารางมักจะเป็นใช่ / ไม่ใช่ง่ายๆเสมอทำให้การตรวจสอบรับรองความถูกต้องเป็นการค้นหาที่ง่าย) นอกจากนี้ทันทีที่มีการใช้ตรรกะใด ๆ ในมากกว่าหนึ่งที่มันจะได้รับการปรับโครงสร้างใหม่จากตัวจัดการและเป็นบริการที่ใช้ร่วมกัน
quentin-starin

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

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

1
ฉันขอยกตัวอย่างที่จับต้องได้บนโต๊ะเพื่อดูว่าคุณ (ทั้งคู่) จัดการกับเรื่องนี้อย่างไร ฉันมีการดำเนินการเผยแพร่บนวัตถุโดเมนของฉันที่ต้องการให้ผู้ใช้อยู่ในบทบาทผู้เผยแพร่และวัตถุนั้นอยู่ในสถานะที่แน่นอน ฉันต้องการซ่อนหรือปิดการใช้งานปุ่ม "เผยแพร่" ใน UI คุณจะทำสิ่งนี้ให้สำเร็จได้อย่างไร?
SonOfPirate

4

ตกลงไปที่นี่เพื่อฉัน ฉันจะล้างมันด้วยการพูดว่า:

  • การเพิ่มประสิทธิภาพก่อนวัยอันควร (และที่มีการออกแบบ) มักจะทำให้เกิดปัญหา

  • IANMF (ฉันไม่ใช่ Martin Fowler);)

  • ความลับเล็ก ๆ น้อย ๆ ที่สกปรกคือในโครงการขนาดเล็ก (แม้แต่เนื้อหาขนาดกลาง) มันเป็นความสอดคล้องของแนวทางของคุณที่จะสำคัญ

การอนุญาต

สำหรับฉันการรับรองความถูกต้องและการอนุญาตเป็นสิ่งที่ต้องคำนึงถึงเสมอ ในโลก Java เล็ก ๆ ของฉันมีความสุขที่ได้รับมอบหมายให้รักษาความปลอดภัยในฤดูใบไม้ผลิหรือกรอบ Apache Shiro

การตรวจสอบ สำหรับฉันการตรวจสอบความถูกต้องเป็นส่วนหนึ่งของวัตถุตามที่ฉันเห็นว่าเป็นการกำหนดว่าวัตถุคืออะไร

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

ในโลก Java ที่มีความสุขฉันใช้กรอบการตรวจสอบความถูกต้อง Bean และใช้คำอธิบายประกอบแบบง่ายในฟิลด์ Bean ส่วนใหญ่ของฉัน มันง่ายในการตรวจสอบวัตถุของคุณไม่ว่าคุณจะอยู่ในชั้นใด

การสร้างวัตถุ

ฉันดูคลาสของโรงงานด้วยความระมัดระวัง บ่อยครั้งที่ฉันได้เห็นxyxFactoryFactoryชั้นเรียน;)

ฉันมักจะสร้างnewวัตถุตามต้องการจนกว่าฉันจะพบกรณีที่มีการรับประกันการฉีด Dependency (และเนื่องจากฉันพยายามติดตามวิธี TDD สิ่งนี้จึงเกิดขึ้นบ่อยกว่า)

ในโลก Java ของฉันที่มีความสุขมากขึ้นเรื่อย ๆ แต่ฤดูใบไม้ผลิยังคงเป็นราชาอยู่ที่นี่

วิริยะ

นี่คือการถกเถียงกันที่เกิดขึ้นเป็นวงกลมและวงเวียนและฉันมักจะนึกถึงมันเสมอ

บางคนบอกว่าถ้าคุณมองวัตถุด้วยวิธี 'บริสุทธิ์' การคงอยู่ไม่ใช่คุณสมบัติหลักมันเป็นเพียงความกังวลจากภายนอก

คนอื่น ๆ มองว่าวัตถุโดเมนของคุณใช้อินเทอร์เฟซแบบ 'คงอยู่' ได้โดยปริยาย (ใช่ฉันรู้ว่าฉันกำลังขยายที่นี่) ดังนั้นจึงเป็นเรื่องที่ดีที่จะมีการต่างๆsave, deleteฯลฯ วิธีการที่พวกเขา สิ่งนี้ถูกมองว่าเป็นวิธีปฏิบัติและเทคโนโลยี ORM (JPA ในโลก Java ที่มีความสุขของฉัน) จัดการกับวัตถุด้วยวิธีนี้

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

HTH!


2

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

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


เสียงเหมือนข้อกำหนดเฉพาะ - นำโครงสร้างข้อมูล (ความเครียด 'ข้อมูล') ไปใช้ใหม่ - นำไปสู่ส่วนทั่วไปที่ลดลงเป็น DTO แบบธรรมดา
Victor Sergienko

แบบจำลองโลหิตจางช่วยให้นำมาใช้ซ้ำได้ดีขึ้นหรือไม่ ฟังดูเหมือน DTO มากขึ้นและโดยส่วนตัวแล้วฉันไม่ได้ให้คำจำกัดความเกี่ยวกับการใช้คำจำกัดความคุณสมบัติซ้ำ ฉันอยากจะนำพฤติกรรมกลับมาใช้ใหม่
แอนดี้

@Andy - ฉันจะเห็นด้วยหากพฤติกรรมของคุณอยู่ในบริการโดเมนและพวกเขาทำงานกับวัตถุที่เป็นโลหิตจาง (ตกลง DTOs ถ้าคุณต้องการ) ถ้าเช่นนั้นจะไม่เพิ่มการใช้พฤติกรรมเหล่านั้นซ้ำอีกหรือ เพียงแค่เล่นเป็นผู้สนับสนุนของปีศาจ
jpierson

@jpierson ฉันได้พบว่าพฤติกรรมนั้นมักจะเฉพาะกับกรณีการใช้งานเฉพาะ หากมีการนำมาใช้ซ้ำนั่นจะอยู่ในคลาสอื่น แต่ผู้บริโภคจะไม่ใช้คลาสเหล่านั้นพวกเขาจะใช้คลาสที่เจาะจงกับกรณีการใช้งาน ดังนั้นการใช้ซ้ำคือ "เบื้องหลัง" ดังนั้นต้องพูด นอกจากนี้การพยายามนำโมเดลกลับมาใช้ใหม่จะทำให้โมเดลใช้งานได้ยากขึ้นสำหรับผู้บริโภคดังนั้นคุณจึงต้องสร้างมุมมอง / แก้ไขโมเดลในเลเยอร์ UI บ่อยครั้งที่คุณต้องละเมิด DRY เพื่อให้ประสบการณ์การใช้งานที่สมบูรณ์ยิ่งขึ้น (ตัวอย่างเช่น DataAnnotations รุ่นแก้ไข)
Andy

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

2

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

ไม่มี "รูปแบบโดเมน" ในสถาปัตยกรรม DDD

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

ฉันเกลียดตัวอย่างที่เรียบง่ายและถูกประดิษฐ์เพราะพวกเขามักจะสับสนมากกว่าที่พวกเขารู้แจ้ง แต่ลองทำเป็นว่าเรามีสองโดเมนที่ต่างกัน อันดับแรกคือแพลตฟอร์ม CMS สำหรับหน่วยงานการตลาด เอเจนซี่นี้มีลูกค้าจำนวนมากที่มีเนื้อหาออนไลน์ที่ต้องจัดการโดยนักเขียนและศิลปินกราฟิก เนื้อหารวมถึงการโพสต์บล็อกเช่นเดียวกับหน้า Landing Page สำหรับลูกค้าที่แตกต่างกัน

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

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

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

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

หากคุณพบว่าคุณมีโมเดลโดเมนโลหิตจางบางทีคุณอาจต้องใช้เวลามากขึ้นในการทำแผนที่บริบทก่อนที่คุณจะเริ่มเขียนโค้ด

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