รูปแบบ Data Mapper, Table Data Gateway (Gateway), Data Access Object (DAO) และ Repository แตกต่างกันอย่างไร


133

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

นอกเหนือจากรูปแบบการตั้งชื่อ (เช่น CustomerMapper กับ CustomerDAO เทียบกับ CustomerGateway กับ CustomerRepository) ความแตกต่างคืออะไรถ้ามี? หากมีความแตกต่างคุณจะเลือกอย่างใดอย่างหนึ่งเมื่อใด

ในอดีตฉันจะเขียนโค้ดคล้ายกับสิ่งต่อไปนี้ (ง่ายขึ้นโดยธรรมชาติ - ปกติฉันจะไม่ใช้คุณสมบัติสาธารณะ):

public class Customer
{
    public long ID;
    public string FirstName;
    public string LastName;
    public string CompanyName;
}

public interface ICustomerGateway
{
    IList<Customer> GetAll();
    Customer GetCustomerByID(long id);
    bool AddNewCustomer(Customer customer);
    bool UpdateCustomer(Customer customer);
    bool DeleteCustomer(long id);
}

และมีCustomerGatewayคลาสที่ใช้ตรรกะฐานข้อมูลเฉพาะสำหรับวิธีการทั้งหมด บางครั้งฉันจะไม่ใช้อินเทอร์เฟซและสร้างวิธีการทั้งหมดบน CustomerGateway แบบคงที่ (ฉันรู้ฉันรู้ว่ามันทำให้ทดสอบได้น้อยลง) ดังนั้นฉันจึงสามารถเรียกมันว่า:

Customer cust = CustomerGateway.GetCustomerByID(42);

นี่ดูเหมือนจะเป็นหลักการเดียวกันสำหรับรูปแบบ Data Mapper และ Repository รูปแบบ DAO (ซึ่งเหมือนกับเกตเวย์ฉันคิดว่า?) ดูเหมือนว่าจะสนับสนุนเกตเวย์เฉพาะฐานข้อมูล

ฉันพลาดอะไรไปรึเปล่า? ดูเหมือนจะแปลกเล็กน้อยที่มี 3-4 วิธีในการทำสิ่งเดียวกัน

คำตอบ:


97

เงื่อนไขตัวอย่างของคุณ DataMapper, DAO, DataTableGateway และ Repository ทั้งหมดมีจุดประสงค์ที่คล้ายกัน (เมื่อฉันใช้งานฉันคาดหวังว่าจะได้รับวัตถุของลูกค้ากลับคืนมา) แต่เจตนา / ความหมายที่แตกต่างกันและการใช้งานที่เป็นผลลัพธ์

Repository "ทำหน้าที่เหมือนคอลเลกชันยกเว้นมีความสามารถในการสอบถามซับซ้อนมากขึ้น" [ อีแวนส์, Domain ขับเคลื่อนการออกแบบ ] และอาจจะถือได้ว่าเป็น"วัตถุในซุ้มความทรงจำ" ( การอภิปราย Repository )

DataMapper "ข้อมูลการเคลื่อนไหวระหว่างวัตถุและฐานข้อมูลในขณะที่ทำให้พวกเขาเป็นอิสระจากกันและ mapper ตัวเอง" ( ฟาวเลอร์ PoEAA, Mapper )

TableDataGatewayเป็น"เกตเวย์ (วัตถุที่ห่อหุ้มการเข้าถึงระบบภายนอกหรือทรัพยากร) เพื่อตารางฐานข้อมูล. ตัวอย่างหนึ่งที่จับทุกแถวในตาราง " ( ฟาวเลอร์ PoEAA, TableDataGateway )

DAO "แยกติดต่อลูกค้าทรัพยากรข้อมูลจากกลไกการเข้าถึงข้อมูล / ปรับการเข้าถึง API ทรัพยากรข้อมูลที่เฉพาะเจาะจงไปติดต่อลูกค้าทั่วไป"ช่วยให้"กลไกการเข้าถึงข้อมูลที่จะเปลี่ยนเป็นอิสระของรหัสที่ใช้ข้อมูล" ( Sun พิมพ์เขียว )

ที่เก็บดูเหมือนทั่วไปมากโดยไม่เปิดเผยแนวคิดเกี่ยวกับการโต้ตอบกับฐานข้อมูล DAO มีอินเทอร์เฟซที่ช่วยให้สามารถใช้งานฐานข้อมูลพื้นฐานที่แตกต่างกันได้ TableDataGateway เป็นกระดาษห่อบาง ๆ รอบ ๆ ตารางเดียวโดยเฉพาะ DataMapper ทำหน้าที่เป็นตัวกลางที่ทำให้อ็อบเจ็กต์ Model มีวิวัฒนาการโดยไม่ขึ้นกับการแสดงฐานข้อมูล (เมื่อเวลาผ่านไป)


15
ความจริงแล้วไม่มีความแตกต่างอย่างมากระหว่าง DAO และ TableDataGateway และใน [Fowler, PoEAA] [1] พวกเขาพูดกันอย่างนั้น: "[Alur et al.] [2] กล่าวถึงรูปแบบ Data Access Object ซึ่งเป็น Table Data Gateway .. ฉันใช้ชื่ออื่นส่วนหนึ่งเป็นเพราะฉันเห็นว่ารูปแบบนี้เป็นการใช้งานเฉพาะของแนวคิดเกตเวย์ (466) ทั่วไปและฉันต้องการให้ชื่อรูปแบบสะท้อนถึงสิ่งนั้น " [1]: martinfowler.com/books/eaa.html [2]: books.google.pt/books/about/…
Miguel Gamboa

9
จุดดี. ความประทับใจของฉันคือ PoEAA ให้คำจำกัดความของ TableDataGateway นั้นแคบกว่า DataAccessObject ในอดีตดูเหมือนจะบ่งบอกถึงการทำแผนที่แบบหนึ่งต่อหนึ่งกับตารางฐานข้อมูล (เชิงสัมพันธ์) โดยที่ DAO อาจทำหน้าที่เป็น Facade ให้กับทรัพยากรที่ไม่เกี่ยวข้อง สิ่งที่เน้นใน DAO คือความสามารถในการแทนที่พื้นที่เก็บข้อมูลที่อยู่ภายใต้การเน้นใน TableDataGateway คือการห่อหุ้มการดำเนินการ SQL บนตารางเดียว (ไม่จำเป็นต้องอยู่ในรูปแบบที่เป็นกลาง / แบบพกพาของ datastore)
Pierce Hickey

31

มีแนวโน้มในโลกแห่งการออกแบบซอฟต์แวร์ (อย่างน้อยฉันก็รู้สึกเช่นนั้น) ที่จะคิดค้นชื่อใหม่สำหรับสิ่งและรูปแบบเก่า ๆ ที่รู้จักกันดี และเมื่อเรามีกระบวนทัศน์ใหม่ (ซึ่งอาจแตกต่างจากสิ่งที่มีอยู่แล้วเล็กน้อย) ก็มักจะมาพร้อมกับชื่อใหม่ทั้งหมดสำหรับแต่ละระดับ ดังนั้น "Business Logic" จึงกลายเป็น "Services Layer" เพียงเพราะเราบอกว่าเราทำ SOA และ DAO กลายเป็น Repository เพียงเพราะเราบอกว่าเราทำ DDD (ซึ่งจริงๆแล้วแต่ละอย่างก็ไม่ใช่ของใหม่และไม่เหมือนใคร แต่เป็นอีกครั้ง: ชื่อใหม่ สำหรับแนวคิดที่เป็นที่รู้จักแล้วรวมอยู่ในหนังสือเล่มเดียวกัน) ดังนั้นฉันไม่ได้บอกว่ากระบวนทัศน์และคำย่อสมัยใหม่ทั้งหมดเหล่านี้มีความหมายเหมือนกันทุกประการ แต่คุณไม่ควรหวาดระแวงกับมันมากเกินไป ส่วนใหญ่เป็นรูปแบบเดียวกันเพียงมาจากครอบครัวที่แตกต่างกัน


4
@MladenMihajlovic เพียงเพราะคุณไม่เข้าใจหรือเห็นด้วยไม่ได้หมายความว่าคำตอบนี้ไม่ถูกต้องหรือเหตุการณ์ถูกต้อง
Cypher

2
@MladenMihajlovic นั่นไม่ใช่คำตอบนี้ ประโยคสุดท้ายสรุปได้
ไซเฟอร์

2
@Cypher รูปแบบเหล่านี้ส่วนใหญ่เหมือนกันหรือไม่? ไม่พวกเขาไม่ได้เป็น. การนำรูปแบบเกตเวย์ไปใช้จะแตกต่างจากการนำรูปแบบที่เก็บไปใช้ พวกเขาอาจดูเหมือนกับดวงตาที่ไม่ได้รับการฝึกฝน แต่ไม่ใช่ นอกจากนี้ตามที่ Mladen Mihajlovic ชี้ให้เห็นอย่างถูกต้องคำตอบนี้ค่อนข้างผิด ตรรกะทางธุรกิจและชั้นบริการเป็นสองสิ่งที่แตกต่างกัน
Frederik Krautwald

1
@ ไซเฟอร์มันไม่ใช่เรื่องของความคิดเห็น แต่เป็นข้อเท็จจริง รูปแบบเกตเวย์ถูกกำหนดโดย Martin Fowler ใน PoEAA ของเขาและส่วนใหญ่เกี่ยวข้องกับรูปแบบ Facade หรือ Adapter [GoF] ความแตกต่างคือเกตเวย์ถูกเขียนขึ้นเพื่อการใช้งานเฉพาะและโดยปกติจะไม่มีอินเทอร์เฟซที่มีอยู่ โดยปกติเกตเวย์จะเกี่ยวข้องกับออบเจ็กต์สองชิ้นเท่านั้นและทรัพยากรที่ถูกห่อหุ้มจะไม่มีความรู้เกี่ยวกับเกตเวย์ (ต่อ ... )
Frederik Krautwald

3
นี่เป็นความคิดเห็นมากกว่าคำตอบ
Pétur Ingi Egilsson

31

Data Mapper vs Table Data Gateway ในการสร้างเรื่องสั้นให้สั้น:

  • Data Mapper จะรับอ็อบเจ็กต์ Domain Model (เอนทิตี) เป็นพารามิเตอร์และจะใช้เพื่อดำเนินการ CRUD
  • Table Data Gateway จะรับพารามิเตอร์ทั้งหมด (เป็นแบบดั้งเดิม) สำหรับวิธีการและจะไม่ทราบอะไรเกี่ยวกับอ็อบเจ็กต์ Domain Model (เอนทิตี)

    ในตอนท้ายทั้งสองจะทำหน้าที่เป็นสื่อกลางระหว่างวัตถุในหน่วยความจำและฐานข้อมูล


  • 6
    ลิงค์หายไปแล้ว
    imel96


    15

    คุณมีจุดที่ดี เลือกคนที่คุณคุ้นเคยมากที่สุด ฉันชอบที่จะชี้ให้เห็นบางสิ่งที่อาจช่วยชี้แจงได้

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

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

    ดังนั้นโดยทั่วไปใน mapper คุณจะเห็นเมธอดเช่นแทรกอัปเดตลบและในเกตเวย์ข้อมูลตารางคุณจะพบ getcustomerbyId, getcustomerbyName และอื่น ๆ

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

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


    1

    ด้านล่างนี้เป็นเพียงความเข้าใจของฉัน

    TableGateWay / RowDataGateWay : ในบริบทนี้เกตเวย์หมายถึงการนำไปใช้งานเฉพาะที่มีการแมป "อ็อบเจ็กต์โดเมน" แต่ละรายการกับ "เกตเวย์ออบเจ็กต์โดเมน" แต่ละรายการ ตัวอย่างเช่นถ้าเรามีPersonเราจะมีPersonGatewayเพื่อเก็บโดเมน object Person ไว้ในฐานข้อมูล หากเรามีบุคคลพนักงานลูกค้า ฯลฯ เราจะมี PersonGateway, EmployeeGateway และ CustomerGateway แต่ละเกตเวย์จะมีฟังก์ชัน CRUD เฉพาะสำหรับออบเจ็กต์นั้นและไม่มีส่วนเกี่ยวข้องกับเกตเวย์อื่น ไม่มีรหัส / โมดูลที่ใช้ซ้ำได้ที่นี่ เกตเวย์สามารถแบ่งออกเป็น RowDataGateway หรือ TableGateway ได้อีกขึ้นอยู่กับว่าคุณส่ง "id" หรือ "object" โดยปกติเกตเวย์จะถูกเปรียบเทียบกับ Active record มันเชื่อมโยงโมเดลโดเมนของคุณกับสคีมาฐานข้อมูล

    Repository / DataMapper / DAO : เหมือนกัน ทั้งหมดนี้อ้างถึงเลเยอร์ Persistence ที่ถ่ายโอนเอนทิตีฐานข้อมูลไปยังโมเดลโดเมน ไม่เหมือนกับเกตเวย์ Repository / DataMapper / DAO จะซ่อนการใช้งาน คุณไม่รู้ว่ามี PersonGateway อยู่ข้างหลัง Person หรือไม่ อาจหรือไม่ก็ได้คุณไม่สนใจ สิ่งที่คุณรู้ก็คือต้องมีการดำเนินการ CRUD ที่รองรับสำหรับวัตถุโดเมนแต่ละรายการ แยกแหล่งข้อมูลและแบบจำลองโดเมน

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