Nine MVP's Blog

09/07/2009

ORM Series : Start to ORM World

Filed under: ORM — Nine MVP @ 8:53 am

Agenda:

  1. ORM Series : Start to ORM World
  2. ORM Series : NHibernate

Introduce

ห่างหายไปนานครับ กับการเขียนบทความลง GF นี่เรียกว่ากลับมาในรอบปีเลยก็ว่าได้ ส่วนใหญ่จะไปเน้นงาน Offline Meeting เสียมากกว่า เรามาเข้าเรื่องกัน

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

พวกเราเป็นนักพัฒนาโดยใช้เทคโนโลยีของไมโครซอฟต์ เริ่มต้นที่ผมได้รู้จัก Library ที่ไว้ใช้เข้าถึง Database มีทั้ง DAO, RDO และ ADO ซึ่งตอนนั้นก็ยุคของ Microsoft Access และ VB6 กำลังรุ่งเรืองเลยก็ว่าได้ โดยการทำงานจะมุ่งเน้นไปที่ Database, Table, Row, Column, StoreProcedure และ Function สนใจเพียงลักษณะของโครงสร้าง column ที่จะดึงมาแสดงผลข้อมูล การคำนวนค่าใน database และส่งกลับมายังโปรแกรมเพื่อทำงานใด ๆ ต่อไป

Figure 1. Currently Microsoft Data Access Component (msdn reference)

ต่อมายุคคือยุคของ ADO.NET ซึ่งย้ายมาทำงานบน .NET Framework เป็นการเพิ่มความสามารถของ ADO โดยเสนอ Dataset Class โดยทำงานในลักษณะของ multi table, relation และอื่น ๆ อีกมากมาย ในตอนนั้นเรียกว่าฮือฮากันเลยทีเดียว เกิดการเปลี่ยนแปลงการเขียนโปรแกรมกันพอสมควร (รวมผมด้วย) ซึ่ง Dataset จะมีทั้ง Untyped และ Typed ให้เลือกใช้งานกัน จนทุกวันนี้ก็ยังมีใช้งานกันแพร่หลาย อีกทั้งมี library ตัวใหม่ๆ อย่าง TableAdapter เป็นต้น ปัจจุบันนี้ Dataset มีใช้งานทั่วไปทั้งในระบบงานเล็ก ๆ ไปจนถึงระบบงานขนาดใหญ่ก็ยังคงพบเห็น เพราะว่ามีความรวดเร็วในการพัฒนา มีความยืดหยุ่นสูงในการทำงานของ code และยังสามารถ serialize ตัวเองไปเป็น xml เพื่อส่งผ่านไปทาง Web Service Technology ซึ่งหลังจากที่ใช้งานมาตลอดยุคหนึ่ง จนมาถึงปัจจุบันในความเห็นส่วนตัว ผมมองว่า Dataset เหมาะสมกับงานที่มุ่งเน้นไปที่การออกแบบระบบทาง Functionality + Data เพราะมองเห็นไปถึง Database Schemay โดยถูกกำหนดการทำงานโดย Business Functionality สิ่งนี้เองที่ทำให้ Dataset ยังคงอยู่จนทุกวันนี้ และจะยังคงอยู่ต่อไปอีกนาน เพราะว่าบุคลากรนักพัฒนาส่วนใหญ่ยังคงใช้ Functionality Design and Programming หรือเรียกได้อีกแบบว่า Data Driven Programming (ตัวอย่าง.. หลังได้ ERD, User Screen, Requirement แล้วลุยพัฒนาเลย)

.NET Framework เป็น framework ที่พัฒนาขึ้นให้ภาษาต่าง ๆ ที่ต้องการจะเข้ากับ framework นั้นต้องตรงตามมาตรฐานที่กำหนดไว้ และกันนี้เองทำให้ภาษาเหล่านั้นต้อง support Object Oriented ไปด้วยโดยปริยาย และด้วยความสามารถนี้ทำให้การ port library, framework ต่าง ๆ จากกลุ่ม OO Language อย่าง JAVA มีความนั้นเป็นไปได้สูง และนี่ก็เป็นจุดเปลี่ยนของ Microsoft Technology เหล่านักพัฒนาเริ่มทะยอยหันกันมาศึกษาและแลกเปลี่ยนความรู้ของ .NET Framework กันแพร่หลาย จนกระทั่งได้มีการนำ open source จาก Java หลาย ๆ ตัวย้ายลงมาพัฒนาบน .NET Framework ให้เราได้เห็นกันจนทุกวันนี้ ไม่ว่าจะเป็น Unit Testing Framework, Logging Framework, MVC Framework, DI และ Object Relational Mapping Framework ก็คือที่เราจะมาคุยกัน

ที่มาของ ORM โลกปัจจุบันเราก็ทราบกันดีว่า Object Oriented Analysis Design and Programming นั้น ช่วยให้เราพัฒนาระบบงานให้มีความใกล้เคียงกับโลกในชีวิตจริง ข้อดีต่าง ๆ ทางด้านการพัฒนาระบบ การดูแลรักษา การพัฒนาต่อยอด ล้วนแล้วแต่เหนือกว่าการพัฒนาแบบ Functionality Style ค่อนข้างมาก แต่ด้วย Database Technology ในปัจจุบันนี้ RDBMS นั้นเป็นที่นิยมใช้งานในปัจจุบันและแพร่หลาย แถมยังมีทีท่าว่าจะรุ่งเรืองต่อไปอีกนาน นี่ก็เป็นปัญหาของการพัฒนาระบบงานแบบ Object Oriented อย่างมาก เนื่องจากคอนเซ็ปการทำงานนั้นแตกต่างกัน จึงกลายเป็นที่มาของ ORM

What’s Object Relational Mapping

ลักษณะของ Business Object จะมีความหลากหลายของโครงสร้าง ตลอดจนลักษณะความสัมพันธ์ระหว่างอ็อปเจ็คก็มีความซับซ้อนทั้งแบบ Hierarchy, Composite และ Association ซึ่งแตกต่างจาก Table Relation ในดาต้าเบสมาก ทำให้ผู้พัฒนาต้องเกิดปัญหาในการจัดการเก็บข้อมูลลง RDBMS

Figure 2. Table Relation Model

Figure 3. Object Relation Model

จากรูปด้านบน จะเป็นการเปรียบเทียบระหว่าง Table Relation กับ Object Relation  จะพบว่ามีลักษณะใกล้เคียง แต่ใน real world นั้นบางครั้ง Object Relation อาจจะมีความซับซ้อนกว่านี้เช่น  Register Customer Class และ Non Register Customer Class ได้ inheritance Customer Class ไป และการเข้าถึง Object อื่น ๆ ที่เกี่ยวข้องกันจาก Diagram เดิมนั้นจะเปลี่ยนไป เช่น Register Customer Class สามารถวางบิลได้ แต่ Non Register Customer Class จะไม่สามารถวางบิลได้ เพราะเงื่อนไขว่า Non Register Customer ไม่สามารถ Order สินค้าได้เป็นต้น

ความซับซ้อนของ Business Object ที่ได้กล่าวไปข้างต้นนั้นเป็นจุดที่สร้างปัญหาในการเก็บข้อมูลลง Table ใน Database เป็นอย่างมาก จนได้เกิดหลักการ Map Object เข้ากับ Table ใน Database ออกมาเป็นหลาย Pattern ซึ่งจะเป็นลักษณะของ Best Practice แต่ไม่ใช่ Standard  และจาก Pattern ต่าง ๆ เหล่านี้ก็ไม่ได้ช่วยลดปัญหาในการพัฒนาตัว ORM Library ให้กับชาว OOP ลงเท่าไหร่ เพราะต้องเสียเวลาในการพัฒนา DAL ที่ทำหน้าที่เป็น ORM อีกชั้นนึง คอยไปดึง Column จาก Table ต่าง ๆ มาสร้างเป็น Object ในระบบ และต้องนำ Property ของ Object ในระบบไป insert ลงยัง Column ใน Table ต่าง ๆ และระดับของ Object ที่มี Ralation กันลึก ๆ หลายระดับ แค่นี้ก็แสบสมองแล้วครับ 

หลายคนก็พยายามเขียน DAL Method ขึ้นเองเพื่อใช้ตอบสนอง Business Method ที่ต้องการใช้งาน Object แต่จากที่กล่าวไว้เบื้องต้นด้านบน นอกจะจะเสียเวลาในการพัฒนาแล้ว ยังเสี่ยงต่อ Bug ที่จะเกิดขึ้นในอนาคต และดูแล้วยากต่อการแก้ไขเปลี่ยนแปลงในตอนหลังด้วย  แต่ไม่ต้องกังวลครับ ปัญหาเหล่านี้ได้มีนักพัฒนาแก้ปัญหาให้ท่านแล้ว ซึ่งมีผู้พัฒนา ORM Framework ออกมาหลายรายทั้งในรูป Open Source และ Commercial แต่จะใช้พูดถึงในบทความ จะขอยกตัวอย่างแค่ ADO.NET Entity Framework และ NHibernate เท่านั้น เพื่อไม่ให้เกิดความสับสนในการศึกษาครับ (จริง ๆ ตัวเดียวก็ปวดหัวแล้ว)

เกรงว่าหากบรรยายไปจะยืดเยื้อ อ่านต่อเกี่ยวกับ ORM ที่นี่ http://www.agiledata.org/essays/mappingObjects.html อ่านจบแล้วจะเข้าใจโลกของ ORM ขึ้นอีกครับ

Object Relational Mapping Framework

ORM Framework จะช่วยลดงานพัฒนาส่วนของการติดต่อกับ Database ให้ครับ โดยคุณจะสามารถ Find/Add/Update/Delete Object ผ่านลงไปยัง Database ได้โดยไม่ต้องเขียน Code จัดการเอง รวมไปถึงข้อดีต่าง ๆ จาก ORM Framework แต่ละตัวเช่น Caching, Validation, etc. ซึ่ง Functionality ที่ ORM Framework จะต้องมีและควรจะมีนั้นมีประมาณนี้ครับ

    • รองรับการทำ Inheritance ระหว่าง Entities, และจะต้องเรียกใช้งานในลักษณะของ Polymorphism
    • สามารถรองรับ relations แบบ 1-1, 1-n, n-n
    • รองรับการทำ transactions
    • Aggregates สำหรับ จัดการดึง object (equivalent to SQL’s SUM, AVG, MIN, MAX, COUNT)
    • รองรับการทำ grouping (SQL’s GROUP BY)
    • Support Database อย่างน้อย 1 ชนิด (เอ… งง)
    • มี OQL, OPath ใช้ในการดึง object
    • รองรับการทำ Databinding (ส่วนใหญ่ IList ก็เป็น standard ของ .NET Data Control แล้ว)
    • ทำ Join (inner, outer)
    • Concurrency Management
    • Database specify type พวก column type แปลก ๆ อย่าง uniqueidentify, sequence ประมาณนั้น
    • สามารถ Map 1 object มาจากหลาย ๆ Table ได้
    • สามารถดึงข้อมุลจาก Table เดียวไปเป็น หลาย ๆ object ได้
    • ควรจะมี GUI ช่วยในการทำ Mapping
    • ควรจะมี Code Gen
    • ควรจะสร้าง Table Schema ได้จาก MAP
    • ระบบควรจะมีประสิทธิภาพในการทำงานสูงโดยรวม
    • สามารถทำ Lazy Loading Object ได้
    • สามารถสร้าง dynamic sql จาก code ได้เอง
    • มี Cache สำหรับ Data ที่จำเป็น
    • สามารถ optimized queries ให้เหมาะสมได้
    • จัดการลักษณะ Circular References
    • ทำ Cascade updates. Bulk updates or deletions
    • …. อีกมากมาย

สาเหตุที่ต้องทำให้คุณควรจะเลือกใช้ ORM Framework ที่มีอยู่แล้วในปัจจุบัน นั้นมีดังนี้

  1. ORM ช่วยลดเวลาในการพัฒนางานของคุณลง 20-50% รวมกรณีต่าง ๆ ในระบบเล็ก ๆ ที่มีประมาณ 10 tables ใน Database และมี Domain Object ราว ๆ 20 objects คุณต้องเขียนโค้ดในการจัดการหลายหมื่นบรรทัด แต่ถ้าคุณใช้ ORM คุณจะใช้เวลาเพียงแค่ไม่เกิน 2 วันครับ
  2. ORM ส่วนใหญ่ที่มีมักเป็น Better of Design และ Code Quality ยิ่งตัวที่มีอายุการพัฒนายาวนาน มี community และมี developer ใช้งานเยอะ ๆ แล้ว ล้วนแต่ไว้วางใจได้ครับ 
  3. ลดคนที่ต้องมาพัฒนาส่วนจัดการ Database
  4. ORM ช่วยลดเวลาในการทำ Test แน่นอนหละครับ มี Community มี User นำไปใช้งานจริง มี bug/issue อะไรก็แจ้งให้แก้ไข ยิ่งพวก Commercial ด้วยแล้ว QC เชื่อถือได้แน่นอนครับ
  5. ORM ช่วยให้คุณลดความยุ่งยากในการเรียนรู้และการทำงานกับ Database ให้เหลือเพียง คุณจะ Get/Update/Add/Delete object ยังไงเท่านั้น

เป็นไงครับ ฟังแล้วพอจะรู้ทางเลือกแล้วใช่มั้ยครับ ว่าเราจะเลือกพัฒนา Custom ORM เองหรือจะใช้ ORM Framework ที่มีอยู่มากมายในปัจจุบัน ผมมีรายชื่อ ORM มาฝากครับ

Name

Open Source

Commercial

Current Version

Multiple Database

LINQ support
ADO.NET Entity Framework Microsoft 1.0 Yes / with 3rd Party Yes
LINQ To SQL Microsoft 1.0 SP1 MSSQL only Yes
NHibernate
(port from Hibernate JAVA)
Fabio Maulo 2.0.1 GA Yes with LINQ to NH
Castle Active Record Castle Project 2.0 Alpha 1 Yes N/A
SubSonic Rob Conery 2.2 Yes Yes
LLBLGen Pro LLBLGen 2.6 Yes Yes
Genome Genome 4.1 Yes Yes
           

Table 1. ORM tool List

ซึ่งบทความนี้ผมจะขอพูดถึง ORM 2 ตัวคือ NHibernate และ ADO.NET Entity Framework ครับ ซึ่งในตอนหน้าจะลงรายละเอียดของ NHibernate

เจอกันตอนหน้าเร็ว ๆ นี้ สวัสดีครับ

 

Nine (นาย)

GF Community Lead

Microsoft MVP Thailand

2 Comments »

  1. แว๊บมาให้กำลังใจคร้าบจะรออ่านภาคต่ออย่างใจจดใจจ่อเลยครับคุณนาย

    Comment by Narin — 21/06/2009 @ 9:09 pm

  2. กำคุณริน มาอ่านซะแระ 555 ผม publish มาไว้นี่ก่อนไปลงใน GF เพราะ format เครื่องลงโปรแกรมใหม่ หนะครับ หุหุหุยังไม่จบเลยนะต้องเกลาคำ + ทำ image อีกเยอะเลย

    Comment by Nine — 28/06/2009 @ 8:51 pm


RSS feed for comments on this post. TrackBack URI

Leave a reply to Nine Cancel reply

Blog at WordPress.com.