DDD - รูปแบบโดเมนโลหิตจางเป็นปฏิปักษ์หรือไม่? เราใช้โมเดลโดเมนที่หลากหลายใช่ไหม [ปิด]


11

รูปแบบของโดเมนโลหิตจางถูกวิพากษ์วิจารณ์เมื่อนานมาแล้วโดยEvans และ Fowlerเนื่องจากเห็นได้ชัดว่ามันขัดกับหลักการเชิงวัตถุ ฯลฯ ชุมชน DDD นั้นสอดคล้องกับข้อความนี้อย่างชัดเจน

อย่างไรก็ตามในช่วงไม่กี่ปีที่ผ่านมามีเสียงไม่เห็นด้วยที่อ้างว่ามันไม่ได้เป็นปฏิปักษ์เลยและเป็นตัวอย่างของการปฏิบัติตามหลักการของโซลิด

ฉันใช้งาน Spring Framework มาหลายปีแล้ว ทุกโครงการในทุก บริษัท มีชั้นบริการที่มีตรรกะทางธุรกิจอยู่เสมอโดยใช้แหล่งเก็บข้อมูลที่ทำงานกับโมเดลโลหิตจาง (เอนทิตี JPA) นอกจากนี้ตัวอย่างส่วนใหญ่แม้แต่คนที่เป็นทางการจากพวก Spring ก็แสดงวิธีการทำงานนี้

คำถามของฉันคือ: โมเดลโดเมนโลหิตจางยังถือว่าเป็น antipattern หรือไม่? เราทุกคนทำสิ่งต่าง ๆ (เกี่ยวกับ DDD) ผิดหรือเปล่า? คุณไม่คิดว่าการมีโมเดล Rich Domain ละเมิดหลักการของ SOLID หรือไม่


2
" โมเดลโดเมนโลหิตจางยังถือว่าเป็นปฏิปักษ์อยู่หรือไม่ " โดยบางคนใช่ คนอื่น ๆ รวมตัวเองแล้วเห็นว่าเป็นวิธีที่ดีกว่าในการเขียนโค้ดส่วนใหญ่ แต่ถ้า RDM เหมาะสมกับคุณให้ใช้มัน ดังนั้นการลงคะแนนเพื่อปิดนี้เป็นการแสดงความคิดเห็นอย่างหมดจด
David Arno

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

คำตอบ:


9

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

พิจารณาว่าเรามีวัตถุโดเมนคำสั่งซื้อหรือไม่ ด้วยวิธีการของ OOP เราจะเพิ่ม Order.Purchase () Order.Cancel () ฯลฯ มันจะทำงานได้ดีในแอพเดสก์ท็อปที่เราเก็บคำสั่งซื้อไว้ในหน่วยความจำและทำหลาย ๆ

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

PurchaseSystemOrder.Purchase()

และ

CancelSystemOrder.Cancel();

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

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

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

PurchaseService.Purchase(Order order)

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

Fowler and Co มาจากพื้นหลังระบบเดียวในโลกของพวกเขาแนวทางของ ADM จะหมายถึงแอพเดียวที่มีบริการแยกต่างหากทั้งหมดเหล่านี้ซึ่งสร้างอินสแตนซ์ในหน่วยความจำและ OrderDTO ถูกส่งผ่านและกลายพันธุ์ สิ่งนี้จะแย่กว่าการวางวิธีการในแบบจำลองการสั่งซื้อที่หลากหลาย

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

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

รวมทั้งการเปลี่ยนเป็นวิธีการเดียวจะต้องมีการอัพเดทส่วนประกอบแบบกระจายทั้งหมดเนื่องจากทั้งหมดขึ้นอยู่กับ Rich Model สำหรับตรรกะของพวกเขา

ฉันไม่มีที่ว่างในรหัสฐานสำหรับสิ่งที่พวกเขาไม่ต้องการ


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

ฉันไม่เห็นด้วย ADM สามารถเป็น DDD ได้หากคุณโทรติดต่อ PurchaseService CashRegister และทำให้เป็นส่วนหนึ่งของภาษาโดเมนของคุณ
Ewan

คุณสามารถทำอย่างละเอียด? ฉันคิดเสมอว่า YMMV เมื่อ ADM และ DDD อยู่ในฐานรหัส SOLID J2EE หรือ. NET C # MVC EF
RibaldEddie

สิ่งที่ฉันหมายถึงคือบริบทการสั่งซื้อที่ถูกผูกไว้ PurchaseSystemOrder.Purchase () จะเป็นรหัสที่เหมือนกันมากกับ รูปแบบโดเมนที่หลากหลายหมายถึงการมีทั้งวิธีซื้อและยกเลิกในชั้นเรียนเดียวกัน
Ewan

1
@RibaldEddie ในหลอดเลือดดำของความหนาของที่ javascript "ส่วนดี" หนังสือผมจะนำเสนอภาพนี้เป็น (ไม่ร้ายแรงอย่างสมบูรณ์) โต้แย้งกับการใช้ DDD สำหรับการดำเนินการ microservices;)
เดวิดอาร์โน

3

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

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

DDD เป็นกระบวนทัศน์ที่ยอดเยี่ยมสำหรับบริการไมโครเนื่องจากแนวคิดบริบทที่ล้อมรอบ

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

หลักการ SOLID เป็นชุดของแนวคิด OOP ทั่วไปที่คุณสามารถใช้เพื่อสร้างรหัส OOP ที่ดีขึ้น คุณสามารถเขียนฐานข้อมูล DDD ที่ดีได้โดยใช้มัน


เกี่ยวกับการแยกรหัสโครงสร้างพื้นฐานจากโดเมน จนถึงตอนนี้ฉันได้พิจารณา JPA Entities โดเมนของฉันโดยมีเลเยอร์แอปพลิเคชันต่อไปนี้: คอนโทรลเลอร์ -> บริการ -> ที่เก็บ -> โดเมน (JPA Entities) อะไรคือสิ่งที่ถูกต้อง (หรือหนึ่งในวิธีที่ถูกต้อง) ในการสร้างแบบจำลองตามที่คุณต้องการ สิ่งที่ต้องการ: คอนโทรลเลอร์ -> รุ่นที่หลากหลาย -> x? ฉันจะจัดการกับการทำธุรกรรมได้อย่างไรและที่ไหน และการทำแผนที่ JPA ล่ะ? เราจะไม่ต้องจำลองรูปแบบที่หลากหลายของเรากับเอนทิตี JPA ที่แยกจากกันหรือไม่
cod cod

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

1

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

หากโดเมน anemic เป็นสิ่งที่คุณต้องการให้คุณเลือกภาษาผิดเมื่อคุณเลือกภาษาที่ใช้งานทั่วไป ภาษารุ่นที่ 4 มีความเชี่ยวชาญเฉพาะด้าน ถ้าโลหิตจางดีพอที่จะใช้มันจะทำให้ชีวิตของคุณง่ายขึ้น

เฟรมเวิร์กหลายเวิร์มเข้าไปในพื้นที่ภาษาจนกว่าคุณจะไม่สามารถโฆษณางานเป็นงานจาวาอีกต่อไป มันเป็นงาน Java / Spring สิ่งที่พวกเขาทำนอกเหนือจากการทำให้คุณต้องพึ่งพาพวกเขาคือเปลี่ยนภาษาวัตถุประสงค์ทั่วไปให้กลายเป็นรูปแบบของไอ้รุ่นที่ 4

นั่นเป็นวิธีปฏิบัติที่ดีที่สุดหรือรูปแบบการต่อต้านหรือไม่? คุณบอสส่วนใหญ่แค่ใส่ใจว่าคุณสามารถจ้างคนทำงานบนฐานรหัสได้หรือไม่ ดังนั้นถ้าเราต้องแกล้งทำเป็นว่าเราใช้ภาษาที่มีวัตถุประสงค์ทั่วไปเพื่อจ้างคนเราจะ

หากคุณตกลงกับที่แล้วก็ดี แน่นอนคุณไม่ใช่คนเดียว

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

ฉันไม่มีที่ว่างในฐานรหัสสำหรับสิ่งที่ไม่ต้องการ

สำหรับ SOLID และหลักการออกแบบอื่น ๆ ฉันสามารถติดตามสิ่งเหล่านั้นได้แม้ในโดเมนที่เป็นโลหิตจาง การไม่ติดตามพวกเขาทำให้เกิดปัญหาประเภทอื่น


ฉันขอขอบคุณคำตอบของคุณและยอมรับอย่างแน่นอนว่าเฟรมเวิร์กบางอย่างเช่น Spring หรือ JPA-Hibernate ได้พิชิตภูมิทัศน์ Java อย่างไรก็ตามมันก็ปฏิเสธไม่ได้ว่าพวกเขาได้จัดทำแนวปฏิบัติที่ดีและเรียบง่ายที่ Java (JEE) ไม่ได้กล่าวถึงทั้งหมดหรือทำผิดฉันรู้สึกกระตือรือร้นเกี่ยวกับ DDD และอยากเข้าใจหลักการทั้งหมดที่พวกเขาบอกคุณ ประสบการณ์แพลตฟอร์ม / ภาษา / กรอบการทำงานที่ดีที่สุดกับแอพ DDD บริสุทธิ์ (กับ Rich Domain Models) คืออะไรตัวอย่าง Github ที่ดีที่คุณรู้ อย่างที่คุณบอกว่าฉันต้องการทำสิ่งที่ดีไม่สอดคล้องกับแนวทางปฏิบัติ
cod cod

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

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

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

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