Voice in the Gentle Wind

พฤษภาคม 29, 2007

คุณสมบัติที่ดีของ DAO + เทคนิกการเสริมหล่อ

Filed under: java, worth a read — deans4j @ 10:50 am

สืบเนื่องจากรวมกระทู้ดีๆ ใน narisa ที่น้อง idome คัดมาส่วนใหญ่ว่าด้วยเรื่องสถาปัตยกรรมการออกแบบซอฟต์แวร์และ design pattern ต่างๆ ประจวบเหมาะพอดีว่า Erik Bruke คงอ่านไทยออก : ) เลยได้สรุปคุณสมบัติของ DAO ที่ดีควรเป็นอย่างไรเอาไว้ ลองอ่านดู แม้คอนเซปต์พวกนี้เรานักพัฒนาก็น่าจะรู้กันอยู่แล้ว แต่รวบรวมไว้ใช้เป็นข้อเตือนใจก็ดี ผมเลยถือโอกาสนี้เรียบเรียงให้ฟัง

[DAO คืออะไร ไม่ขออธิบายแล้วนะ]

  • DAO หนึ่งตัวต้องประกอบไปด้วยอย่างน้อยหนึ่ง interface และตัว implementation อย่างน้อยหนึ่ง
  • ตัว client ใดๆ กระทำกับ DAO ผ่านทาง interface เท่านั้นโดยห้ามคำนึงถึงชนิดของ implementation ใดๆ เป็นหลัก
  • ตัว interface ต้องไม่แสดงออกถึง compile-time dependency ที่เกิดจากตัว implementation ซึ่งได้แก่
    • คลาสที่เกิดจากตัว persistence framework ที่ใช้ เช่น Session เป็นต้น
    • Exception ที่เกิดจาก persistence framework เช่น IOException หรือ SQLException เป็นต้น

    ตัว Interface ต้องสามารถถูกคอมไพลได้โดยปราศจากไลบรารี่ของ persistance framework นั้นๆ ใน classpath

  • DAO ไม่ใช่ที่ที่ต้องมาใส่ใจเกี่ยวกับ connection pool, การจัดการ session หรือ transaction
  • และไม่ใช่หน้าที่ของ DAO implementation ใดๆ เช่นกันที่จะจัดการ Exception ใดๆ ที่เกิดขึ้นกับการจัดเก็บ กลับกัน ทุกๆ Exception ที่เกิดขึ้นภายใต้การทำงานของมันต้องถูกส่งทอดออกไปจัดการข้างนอกที่เลเยอร์สูงกว่า
  • DAO ส่วนมากทั้งหมดไม่มีสถานะ ทำงานจบในตัว
  • DAO แต่ละตัวมักนำเสนอวิธีการเข้าถึงข้อมูลเพียงกลุ่มก้อนหนึ่งที่สัมพันธ์กันเท่านั้น หลายคนมักจะมองหนึ่ง DAO ต่อหนึ่งตารางในฐานข้อมูล หรือมองเป็นต่อหนึ่งคลาสที่ทำหน้าที่จัดเก็บ หรือบางคนอาจจะรวบเอากลุ่มก้อนของข้อมูลเล็กๆ ที่สัมพันธ์กันเอาไว้ใน DAO ตัวเดียว จะใช้วิธีไหนก็แล้วแต่ แต่อย่าเขียน DAO ยักษ์อันเดียวที่ยัดทุกอย่างเอาไว้รวมกัน
  • นานๆ ทีอาจจะมีบ้างที่เห็นว่าในหนึ่ง transaction มีการเรียกใช้เมธอดใน DAO แค่ตัวเดียว เพราะว่าส่วนใหญ่แล้วโดยธรรมชาติเรามักจะเรียก DAO เมธอดหลายๆ ตัวเพื่อทำหนึ่ง transaction ใดๆ
  • DAO ไม่ควรใส่ใจว่าใครเป็นผู้เรียกใช้ โดยแอพลิเคชันส่วนมากจะใช้ business object layer เป็นผู้เรียก พบว่าการใช้ AOP เข้าช่วยสร้าง transaction boundary ณ เลเยอร์นี้ก็เป็นอะไรที่สะดวกดีเหมือนกัน
  • DAO ไม่สร้างตัวเอง ให้ใช้ Factory สร้างเอา หรือมอบหมายให้ IoC Framework ฉีดให้ดีกว่า
  • และเช่นเดียวกัน business Object ไม่มีหน้าที่สร้าง/เลือก DAO แต่ด้วยวิธีการฉีด reference เข้ามาแทนช่วยให้เราสามารถ test ได้ง่ายกว่าด้วยการเลือกฉีด mock DAO เพื่อทดสอบ
  • DAO ควรมี business logic ให้น้อยที่สุด (จริงๆ ไม่ควรมี แต่งานบางอย่างเช่นการทำ validation logic เล็กๆ น้อย มองไปมองมาธุรกรรมน่าจะตกที่เลเยอร์นี้ถึงจะเป็นธรรมชาติกว่า) DAO ควรทำงานแค่ CRUD ได้ก็พอแล้ว การมี business logic ผสมใน DAO จะก่อให้เกิดปัญหาในกรณีมีตัว implementation ใหม่ เพราะเราอาจจะต้องคัดลอกโ้ค้ดส่วนนั้นติดไปด้วยถึงจะทำงานได้ถูกต้อง หรืออีกกรณีตอน test ก็อาจจะยุ่งยากเพราะมี business logic ผูกติดไปด้วยโดยไม่จำเป็น
  • DAO interface เป็นคนละอย่างกับ service interface อย่าเอางานในนั้นมาปน เช่นการแปะ annotation ว่าเมธอดหรือคลาสนี้เป็น web service ตัว DAO interface ควรเป็นสิ่งที่ละเอียดระดับล่างที่สุด แต่ Service interface จะมีเลเยอร์ทางธุรกรรมสูงกว่านั้นและหยาบกว่า

ในส่วนของคอมเมนต์ Kevin Greer ช่วยเสริมกรณี “DAO ควรมี business logic ให้น้อยที่สุด” เค้านำเสนอว่าให้ลองผสม Decorator Pattern เข้าไปใน DAO สิ เพื่อ delegate งานเก่ากลับไปที่ DAO ตัวเดิมที่สะอาดๆ โดยใช้ DAO ตัวใหม่ตกแต่งห่อหุ้ม DAO ตัวเก่าด้วย business logic ตามที่ต้องการเสริมเข้าไป ในเอนทรีถัดมา Erik Bruke ก็นำเสนอตัวอย่างการใช้งานให้ดู

Advertisements

4 ความเห็น »

  1. DAO ไม่ใช่ที่ที่ต้องมาใส่ใจเกี่ยวกับ connection pool, การจัดการ session หรือ transaction

    ตรงข้อนี้นะครับ ผมขอแย้งนิดนึง

    ผมมองว่า DAO อาจจะมี transaction ได้

    เป็น transaction ที่ถูก propogation มาจาก layer อื่น

    service (Business Layer) –> DAO transaction อาจจะถูกส่งต่อมาหรือไม่ส่งต่อก็ได้ครับ

    พี่ dean คิดว่าไงครับ ?

    idome

    ความเห็น โดย idome — พฤษภาคม 29, 2007 @ 3:49 pm

  2. มีอีกประเด็นครับ

    ว่า DAO ที่เรา design เนี่ย ต้องการให้รองรับอะไรบ้าง (ใช้ JDBC หรือ ORM) อะไรที่เป็น commons ควรอยู่ที่เดียวกัน หรือว่าแยกกัน และ ควรแยก DAO ต่อหนึ่ง Domain Model หรือเปล่า

    พวกนี้ก็เป็นสิ่งน่าคิดนะครับ

    ความเห็น โดย idome — พฤษภาคม 29, 2007 @ 4:03 pm

  3. ถ้า transaction scope อยู่ที่ระดับ business layer dao ก็คงไม่ต้องพ่วงหรือมี transaction ให้เรียกใช้ก็ได้ครับ

    ความเห็น โดย วี — พฤษภาคม 30, 2007 @ 1:10 am

  4. โทษทีตอบช้าไปหน่อย

    @idome : มีหรือไม่มี transaction เราไม่ใส่ใจไง
    วิธีการแยก DAO ก็แล้วแต่คน ลองดูความสัมพันธ์ละกัน DAO ส่วนใหญ่ก็มี CRUD นั่นแหละครับ จะ JDBC, ORM ผสมกับ stored procedured ก็แล้วแต่ ถ้าระบบ enterprise อาจจะได้เห็น JDBC ผสม ORM ได้ เป็นเรื่องปกติ แต่ถ้างานเล็ก ขี้เกียจไม่สร้าง DAO แล้วเอาไปผูกตรงๆ กับ service layer ก็ได้

    ความเห็น โดย deans4j — มิถุนายน 3, 2007 @ 5:46 am


RSS feed for comments on this post. TrackBack URI

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s

บลอกที่ WordPress.com .

%d bloggers like this: