"Mapper" เป็นรูปแบบการออกแบบที่ถูกต้องหรือเป็นรูปแบบของ "โรงงาน" หรือไม่


37

รูปแบบทั่วไปที่ฉันเห็นคือสิ่งที่เรียกว่าMapperรูปแบบ (เพื่อไม่ให้สับสนDataMapperซึ่งเป็นอย่างอื่นทั้งหมด) ซึ่งใช้เป็นอาร์กิวเมนต์แหล่งข้อมูล "ดิบ" บางชนิด (เช่น ADO.NET DataReaderหรือDataSet) และแมปเขตข้อมูลไปยัง คุณสมบัติบนวัตถุธุรกิจ / โดเมน ตัวอย่าง:

class PersonMapper
{
    public Person Map(DataSet ds)
    {
        Person p = new Person();
        p.FirstName = ds.Tables[0].Rows[0]["FirstName"].ToString();
        // other properties...
        return p;
    }
}

แนวคิดเป็นเกตเวย์ / DAO / Repository / ฯลฯ ของคุณ จะโทรเข้าไปใน Mapper ก่อนที่จะส่งคืนดังนั้นคุณจะได้รับวัตถุทางธุรกิจที่หลากหลายเมื่อเทียบกับที่เก็บข้อมูลพื้นฐาน

อย่างไรก็ตามดูเหมือนว่าจะเกี่ยวข้องกันหากไม่เหมือนกันกับแพทเทิร์น Factory (ใน DDL parlance, anyways) ซึ่งสร้างและส่งคืนวัตถุโดเมน Wikipedia บอกว่าเรื่องนี้: โรงงาน DDD:

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

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

ดังนั้นจะมีความแตกต่างระหว่างสองรูปแบบเหล่านี้หรือพวกเขาเป็นสิ่งเดียวกันกับชื่อที่แตกต่างกัน?


สิ่งนี้แตกต่างจาก ORM หรือไม่และถ้าใช่ความแตกต่างอยู่ที่ไหน
JB King

ORMs จัดการการจับคู่โดยอัตโนมัติสำหรับคุณ - เป็นมากกว่าสำหรับสถานการณ์ที่คุณไม่สามารถใช้ ORM (หรือต้องเขียนเลเยอร์ข้อมูลของคุณเอง / thin ORM)
Wayne Molina

1
ฉันกำลังดิ้นรนเพื่อดูว่า DataMapper เป็น "อย่างอื่นอย่างสิ้นเชิง"
pdr

บางทีฉันอาจเข้าใจผิด - ฉันคิดว่าDataMapperรูปแบบนั้นเข้าถึงฐานข้อมูลของตัวเองได้ในขณะที่ "Mapper" นี้ไม่ได้ดึงมาจากฐานข้อมูลเพียงแปลงชุดผลลัพธ์บางชนิดเป็นวัตถุ
Wayne Molina

martinfowler.com/eaaCatalog/dataMapper.htmlฉันดูว่าคุณหมายถึงอะไร แต่การอ่านย่อหน้าที่แล้วมันเกี่ยวกับสิ่งที่ถูกต้อง ดูแคตตาล็อก PEAA martinfowler.com/eaaCatalog/index.html สิ่งที่คุณอธิบายคือประเภทของ Mapper และเหมาะกับ DataMapper มากกว่าส่วนที่เหลือ
pdr

คำตอบ:


23

แม้ว่านี่จะเป็นครั้งแรกที่ฉันได้ยินรูปแบบ Mapper สำหรับฉันมันฟังดูเหมือนรูปแบบตัวสร้างมากกว่าโรงงาน

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

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

สำหรับฉัน Mapper ดูเหมือนว่าจะแตกต่างจาก Builder ซึ่งพารามิเตอร์ตัวสร้างมาในรูปแบบของการบันทึกฐานข้อมูลหรือโครงสร้างข้อมูล "ดิบ" อื่น ๆ


อืมฉันเคยได้ยินเกี่ยวกับผู้สร้าง แต่ไม่ได้ตระหนักถึงสิ่งที่มันมอบให้ 100% - สิ่งนี้ช่วยให้ชัดเจนขึ้น! ดูเหมือนว่าข้อแตกต่างที่สำคัญคือ Factory จะส่งคืนคลาสอินเตอร์เฟส / นามธรรมซึ่งเป็นคลาสคอนกรีตตามพารามิเตอร์ (ถ้าเหมาะสม) ในขณะที่ Builder / Mapper จะใช้ข้อมูลจริงและแมปคุณสมบัติเหล่านั้นโดยไม่มีตรรกะ (ถ้ามี) ?
Wayne Molina

1
@Waine M: ค่อนข้างมาก แม้ว่าอาจมีตรรกะจำนวนมากในตัวสร้างเนื่องจากการแมปข้อมูลไปยังคุณสมบัติอาจไม่ตรงไปตรงมาเลย ในความเป็นจริงผู้สร้างอาจมีผู้สร้างรายอื่นเพื่อสร้างพารามิเตอร์ :)
Dima

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

+1 ตกลงว่านี่เป็นวิธีการที่สมเหตุสมผลโดยมีคลาส 'ผู้ทำแผนที่' ที่แยกจากกันเพื่อทำหน้าที่เป็นสื่อกลางระหว่างวัตถุ DTO และวัตถุแบบจำลองโดเมน นอกจากนี้ยังมีประโยชน์เมื่อวัตถุแบบจำลองโดเมนต้องอยู่ในสถานะพิเศษบางอย่างเมื่อสร้าง (เช่น. NET ISupportInitialize interface)
MattDavey

@pdr ฉันยอมรับว่า Mapper ไม่เหมือนกับผู้สร้างจริง ๆ เพราะข้อมูลทั้งหมดพร้อมใช้งานในครั้งเดียว แต่มันก็คล้ายกันมากเพราะมันสร้างวัตถุประเภทเดียวเท่านั้น
Dima

8

สิ่งเดียวที่พบได้ทั่วไปเกี่ยวกับ Mapper, Builder และ Factory คือพวกเขาส่งมอบ "ผลิตภัณฑ์ที่สร้างขึ้น" - และวัตถุตัวอย่างของประเภท เพื่อหลีกเลี่ยงความสับสนใด ๆ ฉันหมายถึงการสนทนาต่อไปนี้สำหรับคำนิยามที่เกี่ยวข้อง

  1. Mapper - ใกล้กับสิ่งที่จะมีการอธิบายที่นี่: http://www.codeproject.com/KB/library/AutoMapper.aspx สิ่งนี้ไม่เหมือนกันกับด้านบน - แต่ใกล้เคียงที่สุดที่ฉันพบเกี่ยวกับผู้ทำแผนที่

  2. ตัวสร้าง - ตามที่กำหนดไว้ที่นี่: http://www.oodesign.com/builder-pattern.html

  3. โรงงาน - กำหนดไว้ที่นี่: http://www.oodesign.com/factory-pattern.html

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

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

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

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

Dipan



4

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

เมื่อในความเป็นจริง Mapper ไม่เหมือนกับโรงงานหรือผู้สร้าง Mapper เป็นเหมือนรูปแบบของอะแดปเตอร์ (ใช้ GoF parlance) รูปแบบของอะแดปเตอร์จัดเตรียมฟังก์ชันการทำงานสำหรับการแปลงการนำเสนอหนึ่งไปเป็นอีกอัน OP อ้างถึงชุดข้อมูลและ DataReader ใน ADO.NET แล้ว SqlDataAdapter นั้นดีแค่ไหน? คำตอบอยู่ในชื่อ Mapper เป็นชื่อใหม่สำหรับสิ่งที่โปรแกรมเมอร์รุ่นเก่ารู้จักกันมานาน: อะแดปเตอร์

Mapper แปลงการเป็นตัวแทนหนึ่งไปยังอีก - ความหมายมากของรูปแบบอะแดปเตอร์


1

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


0

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

ตัวอย่างเช่นแผนที่จากฐานข้อมูลพนักงานวัตถุไปยังโดเมนพนักงานวัตถุแผนที่จากโดเมนพนักงานวัตถุสัญญาลูกค้า

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

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