ฉันผิดที่คิดว่าต้องการบางอย่างเช่น AutoMapper เป็นสิ่งบ่งบอกถึงการออกแบบที่ไม่ดีหรือไม่?


35

Automapperเป็น "ผู้ทำแผนที่วัตถุ - วัตถุ" สำหรับ. Net ซึ่งหมายถึงการคัดลอกวัตถุจากคลาสไปยังคลาสอื่นที่แสดงถึงสิ่งเดียวกัน

ทำไมสิ่งนี้ถึงมีประโยชน์ การทำซ้ำของคลาสเคยมีประโยชน์ / ออกแบบดีหรือไม่?


ข้อมูลอ้างอิงเล็กน้อย: devtrends.co.uk/blog/…อ่านหัวข้อโดยเฉพาะ "ทำไมเราไม่ใช้ automapper?"
Jani Hyytiäinen

คำตอบ:


28

การค้นหา google อย่างรวดเร็วเปิดเผยตัวอย่างนี้:

http://www.codeproject.com/Articles/61629/AutoMapper

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

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

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


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

1
@static_rtti ตามทฤษฎีแล้วใช่ แต่คุณอาจไม่ต้องการให้คลาสดั้งเดิมของคุณเป็นแบบสาธารณะหรือ / และถูกเปิดเผยในที่ประชุม
Jalayn

2
@static_rtti: ใช่ว่าเป็นวิธีที่ถูกต้องสมบูรณ์แบบที่แตกต่างกัน ความแตกต่างที่สำคัญระหว่างการออกแบบทั้งสองคืออายุการใช้งานของข้อมูล / คุณสมบัติ การใช้สำเนาช่วยให้คุณมีภาพรวมของข้อมูลโดยใช้คุณสมบัติที่อ้างอิงข้อมูลต้นฉบับไม่ได้ ทั้งสองวิธีมีข้อดีข้อเสีย แต่ IMHO ไม่มี "ดีขึ้นหรือแย่ลง" โดยทั่วไป นอกจากนี้อาจมีข้อควรพิจารณาด้านประสิทธิภาพซึ่งอาจมีหรือไม่มีอิทธิพลต่อการตัดสินใจว่าจะใช้อะไร
Doc Brown

3
Decoupling มากที่สุดเป็นความคิดที่ดีเสมอ ไม่ใช่เพราะมันมีประโยชน์เป็นพิเศษสำหรับโครงการขนาดเล็ก แต่เป็นเพราะโครงการเติบโต
Tamás Szelei

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

45

การทำซ้ำของคลาสเคยมีประโยชน์ / ออกแบบดีหรือไม่?

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

ถ้าใช้ AutoMapper ต่อไปฉันจะหลีกเลี่ยงด้วยตนเองด้วยเหตุผล 3 ประการ:

ความล้มเหลวเงียบทั่วไปมากขึ้น

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

ขาดการวิเคราะห์แบบคงที่

ดังนั้นคุณจะได้รับรหัสฐานขนาดใหญ่เพื่อจัดการกับ มีล้านคลาสพร้อมด้วยคุณสมบัตินับล้าน ดูเหมือนว่าพวกเขาจะไม่ได้ใช้หรือซ้ำซ้อนกันมากมาย เครื่องมือ "ค้นหาการอ้างอิงทั้งหมด" ใน Visual Studio จะช่วยให้คุณเห็นว่ามีการใช้คุณสมบัติใดและช่วยสร้างแผนที่ในหัวของคุณว่าแอปพลิเคชันทั้งหมดจะทำงานร่วมกันอย่างไร แต่เดี๋ยวก่อนไม่มีการอ้างอิงที่ชัดเจนถึงคุณสมบัติครึ่งหนึ่งเนื่องจากมีการใช้ Automapper งานของฉันตอนนี้หนักขึ้น

ความต้องการที่ล่าช้าซึ่งเพิ่มความซับซ้อน

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

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

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

การเขียนโปรแกรมเป็นศิลปะในการบอกมนุษย์อีกคนหนึ่งว่าต้องการให้คอมพิวเตอร์ทำอะไร - Donald Knuth

ด้วยสิ่งนี้ในใจให้ถามตัวเองว่า "AutoMapper มีประโยชน์ในวันนี้และจะเป็นวันพรุ่งนี้หรือไม่"


[ถ้าคุณทำเว็บ dev ที่ทันสมัย] ดังนั้นถ้าคุณกำลังเขียนบริการเว็บ REST คุณมักจะตรวจสอบคุณสมบัติแต่ละรายการและทุกครั้งเพื่อให้แน่ใจว่ารูปแบบวัตถุ JavaScript ของคุณสอดคล้องกับวัตถุรูปแบบ. NET ของคุณหรือไม่
Den

3
@Den - ใช่ และคุณเขียนการทดสอบเพื่อให้แน่ใจว่าคุณได้รับคุณสมบัติทั้งหมดที่ถูกต้อง (เช่นการทดสอบของคุณจะแสดงคุณสมบัติใด ๆ ที่คุณได้เพิ่มไว้ในที่เดียวที่ไม่แพร่กระจายไปยังชั้นอื่น ๆ )
gbjbaanb

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

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

21

จากประสบการณ์ของฉันเมื่อมีคนบ่นเกี่ยวกับ 'สำเร็จรูปมากเกินไป' และต้องการใช้ AutoMapper มันเป็นหนึ่งในสิ่งต่อไปนี้:

  1. พวกเขาพบว่ามันน่ารำคาญที่จะเขียนรหัสเดียวกันซ้ำไปซ้ำมา
  2. พวกเขาขี้เกียจและไม่ต้องการเขียนโค้ดที่ใช้ Ax = Bx
  3. พวกเขาตกอยู่ภายใต้แรงกดดันเวลามากเกินไปที่จะคิดว่าการเขียน Ax = Bx ซ้ำแล้วซ้ำอีกเป็นความคิดที่ดีและจากนั้นเขียนโค้ดที่ดีสำหรับงาน

อย่างไรก็ตาม:

  1. หากเป็นเรื่องเกี่ยวกับการหลีกเลี่ยงการทำซ้ำคุณสามารถสร้างวัตถุหรือวิธีการที่เป็นนามธรรม คุณไม่จำเป็นต้องใช้ AutoMapper
  2. หากคุณขี้เกียจคุณจะขี้เกียจและจะไม่เรียนรู้วิธีการทำงานของ AutoMapper แต่คุณจะใช้รูปแบบ 'การเขียนโปรแกรมโดยบังเอิญ' และเขียนโค้ดที่น่ากลัวซึ่งคุณใช้กับตรรกะทางธุรกิจในโปรไฟล์ AutoMapper ในกรณีนี้คุณควรเปลี่ยนทัศนคติของคุณที่มีต่อการเขียนโปรแกรมหรือหาสิ่งอื่นเพื่อทำอาชีพ คุณไม่จำเป็นต้องใช้ AutoMapper
  3. หากคุณอยู่ภายใต้แรงกดดันเวลามากเกินไปปัญหาของคุณจะไม่เกี่ยวข้องกับการเขียนโปรแกรมเอง คุณไม่จำเป็นต้องใช้ AutoMapper

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

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

ดังนั้นการซ้ำซ้อนของคลาสการออกแบบที่ไม่ดีคืออะไร? ไม่จำเป็น.

AutoMapper เป็นความคิดที่ไม่ดีหรือไม่? ใช่แล้ว

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


1
กล่าวกันโดยเฉพาะอย่างยิ่ง 2
Mardoxx

2
ฉันรู้ว่านี่เป็นเธรดที่เก่ามาก แต่ฉันต้องไม่เห็นด้วยกับ 1 คุณไม่สามารถสร้างวิธีการทำแผนที่แบบนามธรรมได้ คุณสามารถเรียนได้ 1 คลาส แต่ถ้ามี 2 คุณต้องมี 2 วิธี 3 - 3 วิธี ด้วย AM นี่คือโค้ด 1 บรรทัด - นิยามของการแม็พ นอกจากนี้ฉันต่อสู้กับสถานการณ์จริง ๆ ซึ่งฉันมีรายการ <BaseType> ที่เต็มไปด้วย DTO ย่อย 10 รายการ เมื่อคุณต้องการแมปคุณต้องเปิดสวิตช์ชนิดและวิธีการเพื่อคัดลอกค่าของเขตข้อมูล และจะเกิดอะไรขึ้นถ้าฟิลด์ใดฟิลด์หนึ่งถูกแมปแยก? คำตอบของคุณนั้นดีถ้าคุณมีคลาสที่เรียบง่าย AutoMapper ชนะมือในสถานการณ์ที่ซับซ้อนมากขึ้น
user3512524

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

7

มีปัญหาที่ลึกกว่าที่นี่: ข้อเท็จจริงที่ว่า C # และ Java ยืนยันว่าส่วนใหญ่ / ทุกประเภทจะต้องแยกแยะได้ด้วยชื่อมากกว่าโครงสร้าง: เช่นclass MyPoint2Dและclass YourPoint2Dแยกประเภทแม้ว่าพวกเขาจะมีคำจำกัดความเดียวกันแน่นอน เมื่อประเภทที่คุณต้องการคือ "บางสิ่งที่ไม่ระบุชื่อด้วยxเขตข้อมูลและyเขตข้อมูล" (เช่นบันทึก ) คุณจะโชคไม่ดี ดังนั้นเมื่อคุณต้องการเปลี่ยนเป็นYourPoint2Da MyPoint2Dคุณมีสามตัวเลือก:

  1. เขียนแผ่นสำเร็จรูปที่น่าเบื่อซ้ำซากและน่าเบื่อตามแนวของ this.x = that.x; this.y = that.y
  2. สร้างรหัสอย่างใด
  3. ใช้การสะท้อนกลับ

ตัวเลือกที่ 1 นั้นง่ายพอในขนาดเล็ก แต่ก็เป็นงานที่น่าเบื่อเมื่อจำนวนประเภทที่คุณต้องการในการทำแผนที่มีขนาดใหญ่

ตัวเลือก 2 น้อยกว่าที่ต้องการเพราะตอนนี้คุณต้องเพิ่มขั้นตอนพิเศษในกระบวนการสร้างของคุณเพื่อสร้างรหัสและตรวจสอบให้แน่ใจว่าทีมทั้งหมดได้รับบันทึก ในกรณีที่เลวร้ายที่สุดคุณต้องหมุนเครื่องสร้างรหัสหรือระบบแม่แบบของคุณเองด้วย

ที่ทำให้คุณมีภาพสะท้อน คุณสามารถทำได้ด้วยตัวคุณเองหรือใช้ AutoMapper


2

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

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

ในกรณีที่ AutoMapper ไม่มีเงื่อนงำคุณต้องกำหนดค่าการแมปด้วยรหัสและตั้งค่าสถานะ หากคุณกำลังกังวลกับการตั้งค่าและการทำงานของรหัสทั้งหมดคุณต้องถามว่ามันประหยัดกว่าการทำแผนที่ด้วยตนเอง

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