ผมเคยได้ยินคนบอกว่าเมื่อเร็ว ๆ นี้การถ่ายโอนข้อมูลวัตถุ (DTOs) เป็นต่อต้านรูปแบบ
ทำไม? ทางเลือกอื่นคืออะไร?
ผมเคยได้ยินคนบอกว่าเมื่อเร็ว ๆ นี้การถ่ายโอนข้อมูลวัตถุ (DTOs) เป็นต่อต้านรูปแบบ
ทำไม? ทางเลือกอื่นคืออะไร?
คำตอบ:
บางโครงการมีข้อมูลทั้งหมดเป็นครั้งที่สอง เมื่อเป็นวัตถุโดเมนและอีกครั้งเป็นวัตถุการถ่ายโอนข้อมูล
การทำสำเนานี้มีค่าใช้จ่ายสูงดังนั้นสถาปัตยกรรมจึงจำเป็นต้องได้รับประโยชน์มหาศาลจากการแยกนี้จึงจะคุ้มค่า
DTO ไม่ใช่รูปแบบการต่อต้าน เมื่อคุณส่งข้อมูลข้ามสาย (เช่นไปยังหน้าเว็บในการโทร Ajax) คุณต้องการให้แน่ใจว่าคุณประหยัดแบนด์วิดท์โดยการส่งเฉพาะข้อมูลที่ปลายทางจะใช้ นอกจากนี้บ่อยครั้งที่เลเยอร์การนำเสนอจะสะดวกในการมีข้อมูลในรูปแบบที่แตกต่างจากออบเจ็กต์ทางธุรกิจดั้งเดิมเล็กน้อย
ฉันรู้ว่านี่เป็นคำถามที่เน้น Java แต่ในภาษา. NET ประเภทที่ไม่ระบุชื่อการทำให้เป็นอนุกรมและ LINQ อนุญาตให้สร้าง DTO ได้ทันทีซึ่งจะช่วยลดการตั้งค่าและค่าใช้จ่ายในการใช้งาน
DTO an AntiPattern ใน EJB 3.0พูดว่า:
ลักษณะที่มีน้ำหนักมากของ Entity Beans ในข้อกำหนด EJB ก่อน EJB 3.0 ทำให้เกิดการใช้รูปแบบการออกแบบเช่น Data Transfer Objects (DTO) DTO กลายเป็นอ็อบเจ็กต์ที่มีน้ำหนักเบา (ซึ่งควรจะเป็นเอนทิตีถั่วเองในตอนแรก) ใช้สำหรับส่งข้อมูลข้ามระดับ ... ตอนนี้ EJB 3.0 spec ทำให้ Entity bean model เหมือนกับ Plain old Java object (POJO) ด้วยโมเดล POJO ใหม่นี้คุณไม่จำเป็นต้องสร้าง DTO สำหรับแต่ละเอนทิตีหรือชุดของเอนทิตีอีกต่อไป ... หากคุณต้องการส่งเอนทิตี EJB 3.0 ข้ามระดับให้ใช้ java.io.Serialiazable
ฉันไม่คิดว่า DTO เป็นรูปแบบการต่อต้าน แต่มีการต่อต้านรูปแบบที่เกี่ยวข้องกับการใช้ DTO Bill Dudney อ้างถึงการระเบิดของ DTO เป็นตัวอย่าง:
http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf
นอกจากนี้ยังมีการละเมิด DTO หลายประการที่กล่าวถึงที่นี่:
http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/
มีต้นกำเนิดมาจากระบบสามชั้น (โดยทั่วไปใช้ EJB เป็นเทคโนโลยี) เป็นวิธีการส่งผ่านข้อมูลระหว่างชั้น ระบบ Java สมัยใหม่ส่วนใหญ่ที่ใช้เฟรมเวิร์กเช่น Spring ใช้มุมมองแบบง่ายทางเลือกอื่นโดยใช้ POJO เป็นอ็อบเจ็กต์โดเมน (มักใส่คำอธิบายประกอบด้วย JPA เป็นต้น ... ) ในระดับเดียว ... การใช้ DTO ที่นี่ไม่จำเป็น
OO purists จะบอกว่า DTO ต่อต้านรูปแบบเนื่องจากวัตถุกลายเป็นตัวแทนตารางข้อมูลแทนวัตถุโดเมนจริง
บางคนคิดว่า DTO เป็นรูปแบบการต่อต้านเนื่องจากอาจเกิดการละเมิดได้ มักใช้เมื่อไม่ควร / ไม่จำเป็นต้องเป็น
บทความนี้อธิบายการละเมิดบางอย่างอย่างคลุมเครือ
หากคุณกำลังสร้างระบบแบบกระจาย DTO ไม่ใช่รูปแบบการต่อต้านอย่างแน่นอน ไม่ใช่ทุกคนที่จะพัฒนาในแง่นั้น แต่ถ้าคุณมี (ตัวอย่าง) เปิดแอปโซเชียลทั้งหมดที่รัน JavaScript
จะโพสต์ข้อมูลจำนวนมากไปยัง API ของคุณ จากนั้นจะถูก deserialized เป็นอ็อบเจ็กต์บางรูปแบบโดยทั่วไปคืออ็อบเจ็กต์ DTO / Request จากนั้นสามารถตรวจสอบความถูกต้องเพื่อให้แน่ใจว่าข้อมูลที่ป้อนนั้นถูกต้องก่อนที่จะถูกแปลงเป็นออบเจ็กต์แบบจำลอง
ในความคิดของฉันมันถูกมองว่าเป็นการต่อต้านรูปแบบเพราะใช้ผิดวิธี หากคุณไม่ได้สร้างระบบแบบกระจายโอกาสที่คุณจะไม่ต้องการมัน
วัตถุประสงค์ของData Transfer Objectคือการจัดเก็บข้อมูลจากแหล่งต่างๆแล้วถ่ายโอนไปยังฐานข้อมูล (หรือRemote Facade ) ในครั้งเดียว
อย่างไรก็ตามรูปแบบ DTO นั้นละเมิดหลักการความรับผิดชอบเดียวเนื่องจาก DTO ไม่เพียง แต่จัดเก็บข้อมูลเท่านั้น แต่ยังถ่ายโอนจากหรือไปยังฐานข้อมูล / ซุ้ม
ความจำเป็นในการแยกออบเจ็กต์ข้อมูลออกจากอ็อบเจ็กต์ทางธุรกิจไม่ใช่แอนตี้แพตเทิร์นเนื่องจากอาจจำเป็นต้องแยกเลเยอร์ฐานข้อมูลอยู่ดี
แทนที่จะใช้ DTO คุณควรใช้ Aggregate and Repository Patterns ซึ่งจะแยกการรวบรวมวัตถุ ( Aggregate ) และการถ่ายโอนข้อมูล ( Repository )
ในการถ่ายโอนกลุ่มของอ็อบเจ็กต์คุณสามารถใช้รูปแบบUnit Of Workซึ่งเก็บชุดของที่เก็บและบริบทธุรกรรม เพื่อถ่ายโอนแต่ละออบเจ็กต์ในการรวมแยกกันภายในธุรกรรม
DTO กลายเป็นสิ่งจำเป็นและไม่ใช่ ANTI-PATTERN เมื่อคุณมีอ็อบเจ็กต์โดเมนทั้งหมดของคุณโหลดอ็อบเจ็กต์ที่เกี่ยวข้อง EAGERly
หากคุณไม่ได้สร้าง DTO คุณจะมีการถ่ายโอนออบเจ็กต์ที่ไม่จำเป็นจากชั้นธุรกิจของคุณไปยังเลเยอร์ไคลเอนต์ / เว็บของคุณ
หากต้องการ จำกัด ค่าโสหุ้ยสำหรับกรณีนี้ให้โอน DTO
คำถามไม่ควรเป็น "ทำไม" แต่เป็น " เมื่อ "
แน่นอนว่ามันเป็นการต่อต้านรูปแบบเมื่อเพียงผลจากการใช้งานเท่านั้นที่มีค่าใช้จ่ายสูงขึ้น - เวลาทำงานหรือการบำรุงรักษา ฉันทำงานในโครงการที่มี DTO หลายร้อยตัวเหมือนกับคลาสเอนทิตีฐานข้อมูล ทุกครั้งที่คุณต้องการเพิ่มฟิลด์เดียวที่คุณโฆษณาเพื่อเพิ่ม id เช่นสี่ครั้ง - เป็น DTO เป็นเอนทิตีไปจนถึงการแปลงจาก DTO เป็นคลาสโดเมนหรือเอนทิตีการแปลงผกผัน ... คุณลืมสถานที่และข้อมูลบางส่วนที่ได้รับ ไม่แน่นอน
มันไม่ได้ต่อต้านรูปแบบเมื่อคุณต้องการการแสดงที่แตกต่างกันของการเรียนโดเมนจริงๆ - แบนเพิ่มเติมที่อุดมไปด้วยมากขึ้นแคบมากขึ้น ...
โดยส่วนตัวแล้วฉันเริ่มต้นด้วยคลาสโดเมนและผ่านมันไปโดยมีการตรวจสอบที่ถูกต้อง ฉันสามารถใส่คำอธิบายประกอบและ / หรือเพิ่มคลาส "ตัวช่วย" เพื่อสร้างการแมปฐานข้อมูลไปยังรูปแบบอนุกรมเช่น JSON หรือ XML ... ฉันสามารถแบ่งคลาสเป็นสองคลาสได้ตลอดเวลาหากฉันรู้สึกว่าต้องการ
มันเกี่ยวกับมุมมองของคุณ - ฉันชอบที่จะมองวัตถุโดเมนเป็นวัตถุชิ้นเดียวที่มีบทบาทต่าง ๆ แทนที่จะเป็นวัตถุหลายชิ้นที่สร้างจากกันและกัน หากออบเจ็กต์มีบทบาทเดียวคือการขนส่งข้อมูลแสดงว่าเป็น DTO
ฉันคิดว่าผู้คนหมายความว่ามันอาจเป็นการต่อต้านรูปแบบหากคุณใช้วัตถุระยะไกลทั้งหมดเป็น DTO DTO เป็นเพียงชุดของแอตทริบิวต์และหากคุณมีวัตถุขนาดใหญ่คุณจะโอนแอตทริบิวต์ทั้งหมดเสมอแม้ว่าคุณจะไม่ต้องการหรือใช้ก็ตาม ในกรณีหลังควรใช้รูปแบบ Proxy