Patterns of Enterprise Application and Architecture
การอบรม Patterns of Enterprise Application and Architecture วันที่ 27-29 มิถุนายน ชั้น 3 อาคาร Software Park
Patterns คืออะไร
รูปแบบในการแก้ปัญหาทางการเขียนโปรแกรม หรือการพัฒนาระบบ ที่ถูกรวบรวม และจัดกลุ่มไว้ให้ใช้งาน สิ่งที่เกิดขึ้นได้มีผู้ที่คิดค้น และหาวิธีการแก้ไขไว้นานแล้ว สิ่งต่างๆ เหล่านี้ถูกทดสอบจากผู้รู้ทั้งหลาย และใช้เวลานานในการปรับปรุงแก้ไข เพื่อเป็นการแก้ปัญหาอย่างมีประสิทธิภาพในระยะเวลาอันสั้น คล้ายกับสถาปนิกที่มองว่าจะออกแบบแต่ละส่วนของบ้าน มีแพทเทิรน์อะไรให้เลือกบ้าง สถาปนิกก็จะเลือกเอาแพทเทิรน์ของแต่ละส่วนมารวมกันเป็น blueprint ของบ้านทั้งหลัง หรือสูตรคณิตคิดลัด ต้องจำและนำไปใช้ให้ตรงกับปัญหาที่พบ
หลักการจำอย่างง่าย
1. จำชื่อ Pattern ทุกตัวให้ได้
2. จำคำจำกัดความสั้น ๆ ของแต่ละ Pattern ให้ได้ ปกติยาวประมาณ 1-2 บรรทัดเท่านั้น
3. จำให้ได้ว่า Pattern นั้นมักใช้กับงานลักษณะใด
หลักการจำสำหรับผู้ที่คิดจริงจังกับ Pattern
1. จำให้ได้ว่า Pattern นั้นมีรากเหง้ามาจาก Pattern ใดบ้าง เช่น Front Controller มาจาก Facade เป็นต้น
2. จำให้ได้ว่า Pattern นั้นเป็นของใคร อยู่ในหนังสืออะไร ใครแต่ง หรือใครคิด เพราะเวลาใช้ Pattern อะไรควรมี [...] ต่อท้าย เช่น Adapter [GoF], Gateway [Fowler], Pipe and Filter [POSA] เป็นต้น
แนวทางการใช้ Pattern
1. ต้องเข้าใจ Context ของปัญหาก่อน เช่น เข้าใจสาเหตุ ปัจจัยที่เกี่ยวข้อง side effect หรือ impact ที่เกี่ยวข้อง
ถ้าไม่เข้าใจ Context ของปัญหาที่เจอ ก็ไปต่อไม่ได้ล่ะครับ อย่าฝืน อย่าใจร้อน
2. นึกให้ออกว่าปัญหาลักษณะนี้ควรใช้ Pattern ใด นึกแค่ชื่อพอ แต่ถ้านึกไม่ออกให้เปิดหนังสือไล่หาไปเรื่อย ๆ
3. เมื่อนึกชื่อ Pattern หรือหาได้แล้วว่าจะใช้ Pattern อะไร ให้นึกให้ออกต่อว่า Pattern นั้นปกติมักใช้ร่วมกับ Pattern อะไร
หรือเปิดหนังสืออ่านหัวข้อสุดท้ายของแต่ละบทของแต่ละ Pattern
4. ดูว่าจะใช้ Pattern ใดร่วมกับ Pattern ใดบ้าง โดยพิจารณาถึงแนวทาง ข้อดี ข้อเสีย การนำไปใช้
แล้วเลือกกลุ่ม Pattern ที่เหมาะสมกับปัญหาที่สุดออกมา ถ้านึกไม่ออกมีอะไรบ้างให้เปิดหนังสือ
5. นำไปใช้ วาด UML อย่างไร ซอร์สโค้ดหน้าตาอย่างไร solution เป็นอย่างไร ถ้านึกไม่ออกก็เปิดหนังสืออีก
สิ่งสำคัญคือ ทักษะการวิเคราะห์ปัญหาและพื้นฐาน Object-Orientation ถ้าสองอย่างนี้ไม่มี หรือไม่แม่น Pattern จะกลายเป็นเรื่องยากและน่าเบื่อ
คติเตือนใจ
1. เมื่อเจอปัญหาต้องตั้งสติ อย่ารีบหาทางแก้ปัญหาด้วยตัวเอง
2. ค้นคว้าให้ทั่วทั้งจากตำราและในอินเทอร์เน็ต ว่าปัญหาที่ตัวเองเจอมีใครเคยเจอแล้วบ้าง แล้วเขาแก้ไขอย่างไร
หรือใช้ Pattern อะไร เพราะ Pattern คือ 'A solution for common problem' ปัญหาส่วนใหญ่ในโลกหากมองแก่นให้ออก
ล้วนมีคนเคยเจอและได้รับการแก้ไขแล้วทั้งนั้น ดังนั้นเมื่อเจอปัญหาต้องหา Pattern ของปัญหาก่อน แต่ไม่มีปัญหาใดเลยที่เหมือนกันจริงๆ อาจจะต้องมีการประยุกต์หรือดัดแปลงตามความเหมาะสม
3. ถ้าไม่มีจริง ๆ ค่อยแก้ปัญหาด้วยตัวเอง หรือสร้าง Pattern ของตัวเองเองเสียเลย
ต่อไปจะเป็นการแนะนำ patterns แต่ละประเภท และแนวทางการนำไปใช้
Domain Logic Patterns
- Domain
- คือสิ่งที่กำหนดขอบเขต ระบบงาน
- Logic
- แนวคิด วิธีการทำงาน แบ่งเป็น
- Business Logic กฎเกณฑ์ กลยุทธ์ทางธุรกิจ
- Data(Persistant) Logic รายละเอียด โครงสร้างของข้อมูล(Schema), Trigger, View
- Transaction Script
- นิยาม เป็น pattern ของการออกแบบ business logic โดยอ้างอิงตาม process ของงานเป็นหลัก โดยแต่ละ procedure จะเริ่มจาก request จุดเดียว/สาเหตุเดียว สิ้นสุดเหตุการณ์ได้หลายแบบ โดยที่การจบแบบ success จะมีได้กรณีเดียว ใช้ Activity Diagram ในการออกแบบ
- ปัญหา แอปพลิเคชั่นทางธุรกิจประกอบด้วยชุดของ transaction หลายชุด ซึ่งแต่ละ transaction ทำหน้าที่ต่างกันไป
- การแก้ไข domain logic จะที่ใช้ในแต่ละ transaction จะเก็บไว้ใน Transaction Script ในลักษณะของprocedure ซึ่งสามารถเรียกตรงไปยังฐานข้อมูลได้ แต่ละ transaction จะมี Transaction Script ของตัวเองและประมวลผลงานเพียงงานเดียว
- วิธีใช้ วิธีที่นิยมใช้กันมากที่สุดคือการนำTransaction Script ที่ทำงานสอดคล้องกันใส่ไว้ในคลาสเดียวกัน ดังนั้นจะมีจำนวนคลาสน้อยแต่ทำงานหลายอย่าง อีกวิธีคือแต่ละ Transaction Script จะมีคลาสของตัวเองดังนั้นจะมีจำนวนคลาสมากแต่ทำงานเฉพาะอย่าง เรียกวิธีการนี้ว่า Command pattern[GoF] ซึ่งในการทำงานเราสามารถจัดการคลาสเสมือนกับเป็นวัตถุได้ บริหารจัดการง่าย แต่ถ้าคลาสมากเกินไป performance ก็จะลดลง
- Logic พื้นฐานที่มีการใช้งานบ่อยควรสร้างเป็น Super class ให้คลาสอื่นมา extend หรือ เรียกใช้
- ข้อดี ทำได้ง่าย
- ข้อเสีย ถ้า business logic มีความซับซ้อนมากจะออกแบบยาก
- Domain Model
- นิยาม โมเดลที่ใช้อธิบายองค์ความรู้และกระบวนการทั้งหมดของระบบงาน เป็นสิ่งแรกที่ต้องสร้างขึ้นเพื่อให้ทีมพัฒนาเข้าใจขอบเขตและขั้นตอนการทำงานตรงกันก่อนดำเนินการเก็บ Requirement ปกติเมื่อเขียนแล้วจะไม่มีการแก้อีก การเขียน domain model ต้องเกิดจากความรู้ ไม่ใช่คิดขึ้นเอง ซึ่งมาจากแหล่งอ้างอิงเดียวกัน
- ปัญหา ในหลายกรณี business logic มีความซับซ้อนและเกี่ยวข้องกับการคำนวณ การตรวจสอบความถูกต้อง
- การแก้ไข Domain Model เป็นกลุ่มของวัตถุที่เป็นโมเดลทางธุรกิจ โดยเชื่อมโยงแต่ละวัตถุเข้าด้วยกันและมีการทำงานที่แตกต่างกันเป็นเอกเทศ โดเมนสามารถมีได้หลายมิติ ขึ้นกับว่าจะใช้อธิบายอะไร
- วิธีใช้ แบ่งเป็น 2 ประเภท
- Simple Domain Model คล้ายกับการออกแบบฐานข้อมูล แต่ละวัตถุในโดเมนเสมือนกับ table 1 table
- Rich Domain Model ร่วมกับ inheritance [GoF] patten และเชื่อมโยงแต่ละกลุ่มของวัตถุเข้าด้วยกัน เหมาะกับ logic ที่ซับซ้อน แต่ยากสำหรับการ map กับฐานข้อมูล
- เพื่อให้ง่ายในการสร้าง ปรับปรุงเปลี่ยนแปลงและทดสอบ ควรออกแบบให้จบสมบูรณ์ในตัวและพึ่งพากันให้น้อยที่สุดในแต่ละโมเดลและเลเยอร์
- ข้อควรระวัง คือ domain logic อาจจะใหญ่เทอะทะเนื่องจากโดเมนคลาสที่ใหญ่เกินไปเพราะเต็มไปด้วย domain object แม้จะมาจาก use case แค่ชิ้นเดียว
- Table Module
- นิยาม เป็นแนวคิดในการสร้าง instance เพื่อเก็บ Business logic สำหรับทุกแถวใน table หรือ view ของฐานข้อมูล
- ปัญหา เกิดจาก domain model ไม่สามารถเชื่อมกับฐานข้อมูล
- วิธีแก้ไข Table Module จะดูแล Business logic 1 คลาสต่อ 1 table และในคลาสจะมีเมธอดที่เกี่ยวข้องกับข้อมูลนั้น ส่วนที่ต่างจาก domain model คือเมื่อมีการเรียกใช้ domain model จะสร้าง 1 object/request แต่ Table Module จะใช้ object เดียวจัดการทั้งหมด ซึ่งการอ้างอิงข้อมูลแต่ละ row จะใช้ primary key เป็น input ของเมธอด
- ข้อเสีย ไม่เหมาะกับงานที่มี logic ซับซ้อน เชื่อมโยงกันหลาย table และการใช้คุณสมบัติ polymorphism ไม่ดีนัก
- Service Layer
- นิยาม เป็นการกำหนดขอบเขตของแอปพลิเคชั่นด้วยเลเยอร์ของบริการ ซึ่งแต่ละเลเยอร์จะประกอบด้วยกลุ่มของบริการและผลตอบสนองของแอปพลิเคชั่นในแต่ละบริการ
- ปัญหา แอปพลิเคชั่นระดับองค์กรจำเป็นต้องใช้ interface หลายประเภท เพื่อให้เหมาะกับข้อมูลและ logic ที่ใช้ และ interface เหล่านี้ต้องการ interaction ในการเข้าถึงและจัดการข้อมูลและเรียกใช้ business logic ซึ่งมักจะซับซ้อนและเกี่ยวข้องกับ transaction ข้ามทรัพยากรหลายประเภท การเก็บ logic ของ interaction แยกกันแต่ละ interface ทำให้เกิดความซ้ำซ้อน
- วิธีแก้ไข Service Layer ทำการ encapsulate ส่วน business logic ส่วนควบคุม transaction และส่วนจัดการการตอบสนองการทำงาน และแยก application logic และ domain logic ออกจากกันคนละเลเยอร์
- วิธีการใช้ ระบุ operation ที่จำเป็นบน Service Layer โดยพิจารณาจากความจำเป็นของ Service Layer ของ client ซึ่งก็คือ user interface นั่นเอง การออกแบบกระทำได้ 2 วิธี คือ
- Domain Façade Service Layer จะสร้างขึ้นเป็นกลุ่มของ Façade บน domain layer โดยคลาสที่ใช้สร้าง Façade ห้ามมี business logic เด้ดขาด
- Operation Script Service Layer จะสร้างขึ้นเป็นกลุ่มของคลาสที่สร้าง application logic โดยตรงแต่ทำการ encapsulate คลาส domain object สำหรับ domain logic
Data Source Architectural Patterns
- Table Data Gateway
- นิยาม เป็น object ที่ทำหน้าที่คล้าย gateway ไปยัง table ของฐานข้อมูล แต่ละ instance จะประกอบด้วยทุก row ใน table
- ปัญหา การใส่ SQL เข้าไปใน application logic ทำให้เกิดปัญหา ผู้ดูแลฐานข้อมูลจำเป็นต้องเข้าถึง SQL ได้ง่าย เพื่อสะดวกในการปรับแต่งและปรับปรุงฐานข้อมูล
- วิธีการแก้ไข
- TDG จะดูแล SQL สำหรับการเข้าถึง table เดี่ยวหรือ view ทั้งหมด เช่น select insert update และ delete ส่วนของโปรแกรมอื่นจะเรียกเมธอดนี้เพื่อติดต่อกับฐาน
- TDG เป็น interface ประกอบด้วยหลายเมธอดที่ใช้ในการดึงข้อมูลจากฐานและเมธอดในการ update insert delete แต่ละเมธอดแมปเข้ากับพารามิเตอร์เข้ากับ SQL และรัน SQL นั้น
- TDG มักเป็น stateless (instance ที่ไม่เก็บสถานะ ออปเจคเรียกใช้คืนค่าแล้วจบ)
- วิธีใช้งาน
- การคืนค่าจากการสืบค้นใช้ Data Transfer Object หรือ Record Set
- เมื่อเสร็จสิ้นการทำงานผ่าน TDG ค่าที่คืนกลับมาควรอยู่ในรูปของ view มากกว่า table จริง เพื่อลด dependency ระหว่างโค้ดและฐานข้อมูล
- ในกรณีที่ไม่ซับซ้อน คุณสามารถใช้ TDG ตัวเดียวในการควบคุมทุกเมธอดสำหรับทุก table
- ควรใช้เมื่อไหร่ TDG ทำงานได้ดีกับ Table Module ซึ่งจะสร้างโครงสร้างข้อมูล record set สำหรับ Table Module และเข้ากันได้ดีมากกับ Transaction Script แต่ไม่ควรใช้ร่วมกับ Domain Model (เพราะสนใจพฤติกรรมของระบบมากกว่าฐานข้อมูล)
- ข้อดี ใช้งานง่ายและ interface เดียวกันสามารถเรียกใช้ได้ทั้ง SQL และ Store procedure
- Row Data Gateway
- นิยาม เป็น object ที่ทำหน้าที่คล้าย gateway ไปยังแหล่งข้อมูล แต่ละ instance จะประกอบด้วย row เพียง row เดียว
- ปัญหา การรวมโค้ดที่เชื่อมกับฐานข้อมูลไว้ใน Object ที่อยู่ในหน่วยความจำทำให้เกิดความซับซ้อนมากขึ้น การทดสอบจะใช้เวลาและทำได้ยากขึ้น เพราะ object ผูกกับทั้งฐานข้อมูล
- วิธีการแก้ไข RDG จะช่วยแปลงจาก Datasource ไปอยู่ในหน่วยความจำที่ละ row ซึ่งง่ายมาก
- การใช้งาน มีสองแบบ เลือกใช้ gateway เดียวทั้งหมด หรือแบบผสมระหว่าง TDG หรือ RDG RDG สามารถทำงานได้ดีกับ Data Mapper ซึ่งจะมีประสิทธิภาพมากหาก RDG สามารถสร้างอัตโนมัติจาก metadata ในขณะที่ Data Mapper ต้องทำเอง มักใช้กับ Transaction Script เพราะสามารถ reuse กับ Transaction Script อื่นได้แต่ไม่ควรใช้ร่วมกับ Domain Model
- Active Record
- นิยาม เป็น object ที่เก็บ row เดียวใน table ของฐานข้อมูลหรือ view รวมเข้ากับการเชื่อมสู่ฐานข้อมูล และ domain logic
- ปัญหา object ที่มีทั้งข้อมูลและเมธอด โดยมากข้อมูลเหล่านี้เป็น persistent และจำเป็นต้องเก็บในฐานข้อมูล
- วิธีการแก้ไข วิธีการแก้ไข Active Record ใช้มากในการเก็บ data access logic ใน domain object ทำให้ง่ายในการรู้วิธีการอ่านและเขียนข้อมูลกับฐานข้อมูล AR เป็น domain model ซึ่งคลาส match กับโครงสร้างของฐานข้อมูล แต่ละ AR รับผิดชอบในการบันทึกและโหลดฐานข้อมูลสำหรับ domain logic ใดๆ AR จะคล้ายกับ RDG แตกต่างกันที่ AR มีทั้งแหล่งข้อมูลและ domain logic แต่ RDG มีแต่การเข้าถึงฐานข้อมูลอย่างเดียว
- การใช้งาน คลาส AR มีเมธอดที่ทำสิ่งต่อไปนี้
- สร้าง instance ของ AR จากผลของ SQL
- สร้าง instance ใหม่หลังจากใส่ข้อมูลลงใน table
- ค้นหาข้อมูลโดยใช้ SQL และคืนค่าเป็น AR object
- Update ฐานข้อมูลและ insert ข้อมูลใน AR ลงฐานข้อมูล
- Get และ set ข้อมูล
- ส่วนของ business logic
- สามารถใช้ AR กับ view หรือ query เช่นเดียวกับ table
- ควรใช้เมื่อไหร่ AR เป็นตัวเลือกที่ดีสำหรับ domain logic ที่ไม่ซับซ้อนนัก เช่น create, read, update และ delete ซึ่งกระทำบน record เดียว อีกทั้งยังเข้ากันได้ดีกับ Transaction Script ซึ่งจะช่วยลดปัญหาเรื่องโค้ดมีความซ้ำซ้อนและยุ่งยากในการ update script และ table ที่การออกแบบโดยใช้ Transaction Script มักจะประสบเป็นประจำ ถ้า business logic มีความซับซ้อนแล้วคุณต้องการให้ object มีความสัมพันธ์โดยตรง หรือมีการถ่ายทอดคุณสมบัติ ไม่เหมาะจะใช้ AR ควรใช้ Data Mapper
- ข้อดี สร้างและทำความเข้าใจได้ง่าย ใช้งานสะดวก
- Data Mapper
- นิยาม เลเยอร์ของ Mapper ย้ายข้อมูลระหว่าง object และฐานข้อมูล ทำให้ object และตัวของ mapper เองเป็นอิสระต่อกัน
- ปัญหา object และฐานข้อมูลมีกลไกในการจัดโครงสร้างข้อมูลแตกต่างกัน หลายส่วนของ object อาทิ collection, inheritance ไม่มีในฐานข้อมูล เมื่อสร้าง object model ที่มี business logic จำนวนมาก ควรใช้กลไกในการจัดการข้อมูลที่ดีขึ้นและเมธอดที่มากับข้อมูลจาก schema ที่ต่างกัน object schema กับ database schema ไม่ matchเข้าด้วยกัน เมื่อจำเป็นต้องย้ายข้อมูลระหว่างสอง schema แล้วข้อมูลที่ส่งมาเริ่มซับซ้อน ถ้า object ในหน่วยความจำรู้โครงสร้างของฐานข้อมูล การเปลี่ยนแปลงใน จะกระทบถึงตัวอื่นด้วย
- วิธีการแก้ไข Data mapper เป็นเลเยอร์ของซอฟท์แวร์ที่แยก object ในหน่วยความจำออกจากฐานข้อมูล และทำหน้าที่เคลื่อนย้ายข้อมูลระหว่าง object กับ ฐานข้อมูล ซึ่ง object ในหน่วยความจำไม่จำเป็นต้องรู้ว่าฐานข้อมูลมีหรือไม่ เป็นอย่างไร ไม่ต้องใช้ SQL ไม่ต้องรู้โครงสร้าง เลเยอร์ของ Data mapper สามารถแทนที่ได้ เพื่อการทดสอบ หรือให้ domain layer ทำงานร่วมกับฐานข้อมูลอื่น
- การใช้งาน แอปพลิเคชั่นสามารถมี Data Mapper ได้หลายตัว เพื่อใช้ในแต่ละ domain class หรือสร้างเป็น domain hierarchy หากใช้ Metadata Mapping จะใช้ได้เพียงคลาสเดียว Data Mapper จะมองเห็นโดยใช้ Identity Map ถ้าโหลด domain object แล้ว เมื่อมีการ insert, update เลเยอร์ที่ map ฐานข้อมูลจำเป็นต้องรู้ว่า object นั้นได้เปลี่ยนแปลงแก้ไขอะไรบ้าง Unit of Work ถูกนำมาใช้ร่วมกับ Data Mapper เพื่อการนี้ เมื่อ object มีการเชื่อมต่อกันมากๆ จำเป็นต้องหยุดเปลี่ยนแปลงข้อมูลเมื่อมีการดึงข้อมูลจากฐาน เทคนิค Lazy load ถูกนำมาใช้เพื่อแก้ปัญหานี้
- ควรใช้เมื่อไหร่ โอกาสที่ควรใช้งาน Data Mapper หลักๆคือเมื่อต้องการให้ schema ฐานข้อมูลและ object model เป็นอิสระต่อกันและมักใช้ร่วมกับ Domain Model
Object-Relational Behavioral Patterns
- Unit of Work
- นิยาม การจัดการรายการของ object ที่ได้รับผลกระทบจาก business transaction และบันทึกการเปลี่ยนแปลงและเก็บรายละเอียดของปัญหา เช่นการทำ undo, redo, rollback
- ปัญหา เมื่อทำการปรับเปลี่ยนข้อมูลจากฐานข้อมูล มีความจำเป็นต้องติดตามสิ่งที่เปลี่ยนแปลงไป นอกจากข้อมูลนั้นไม่เคยเขียนกลับลงในฐาน คุณสามารถเปลี่ยนแปลงฐานข้อมูลด้วยการเปลี่ยน object model แต่จะทำให้เกิดการเรียกฐานข้อมูลจำนวนมาก ซึ่งทำให้การทำงานช้าลง ยิ่งกว่านั้นทำให้ต้องเปิด transaction จนกว่ากระบวนการจะเสร็จสิ้นซึ่งไม่มีประสิทธิภาพเมื่อนำมาใช้งานจริง ถ้าคุณมี business transaction ที่ประกอบด้วยหลาย request
- วิธีแก้ไข Unit of Work เป็น object ที่เก็บบันทึกทุกอย่างที่คุณทำระหว่างที่ business transaction ทำงานกับฐานข้อมูล เมื่อทำงานเสร็จ object นี้จะอธิบายทุกอย่างที่จำเป็นต้องทำในการเปลี่ยนฐานข้อมูลให้เป็นตามผลลัพธ์ของงานนั้น เมื่อคุณเริ่มทำอะไรก็ตามที่กระทบต่อฐาน คุณควรสร้าง Unit of Work เพื่อติดตามการเปลี่ยนแปลง เมื่อถึงเวลาที่ต้อง commit Unit of Work จะดำเนินการเปิด transaction ตรวจสอบ concurrency และบันทึกการเปลี่ยนแปลงลงในฐานข้อมูล โดยที่โปรแกรมเมอร์ไม่ต้องเรียกเมธอดเพื่อ update ฐานข้อมูล
- การใช้งาน แนวทางในการให้ Unit of Work รู้ว่าจะต้องติดตาม object ใดมี 2 แนวทาง
- Caller registration ผู้ใช้ของ object ลงทะเบียน object ด้วย Unit of Work สำหรับการเปลี่ยนแปลง object ใดๆที่ไม่ลงทะเบียนจะไม่สามารถ commit ได้ ซึ่งอาจจะเกิดปัญหาได้ถ้าลืมลงทะเบียน
- Object registration งานลงทะเบียนถูกดึงออกจากส่วน caller เมธอดในการลงทะเบียนใส่ไว้แทนที่เมธอดของ object การโหลด object จะลงทะเบียนว่า clean เมธอดเซตค่าจะลงทะเบียนว่า dirty
- Unit of Work เป็นวิธีการที่ดีที่สุดในการติดตามการทำงานของ object และต้องการ Undo/Redo transaction
- Identity Map
- นิยาม เป็นวิธีการควบคุมให้ object ถูกโหลดเพียงครั้งเดียวโดยการเก็บทุกๆ object ที่โหลดไว้ใน map เมื่อต้องการใช้ object จะทำการเรียก key ของ object นั้น คล้ายกับ array ที่ใช้เก็บ object
- ปัญหา ถ้าคุณไม่ระวังคุณจะโหลดข้อมูลชุดเดียวกันจากฐานข้อมูลในสอง object ที่ต่างกัน และเมื่อมีการ update ในทั้งสอง object จะเกิดปัญหาในการบันทึกการเปลี่ยนแปลงลงในฐานข้อมูล(data consistency) และการโหลดข้อมูลเดียวกันมากกว่าหนึ่งครั้งเป็นการสูญเปล่า โดยเฉพาะเมื่อเรียกแบบ remote
- วิธีการแก้ไข Identity Map เก็บ record ของทุก object ที่อ่านจากฐานข้อมูลใน business transaction เดียวกัน เมื่อคุณต้องการ object ควรจะดูที่ IM ก่อนอาจจะมี object นั้นอยู่แล้ว เมื่อใช้เสร็จส่งคืน map ไป ถ้าไม่มีค่อยสร้าง object ขึ้นมาใหม่แล้วเก็บไว้ใน map แนวคิดพื้นฐานคือการเก็บซีรีย์ของ map ที่บรรจุ object ที่ดึงข้อมูลจากฐานข้อมูล ในกรณีง่ายๆคุณอาจจะมี 1 map/table
- วิธีใช้ ปกติ key ของ map จะใช้ primary key ของ table ในฐานข้อมูล ซึ่งจะใช้ได้ดีถ้า primary key เป็นคอลัมน์ๆเดียวที่ไม่มีการแก้ไข คุณสามารถมี 1 map ต่อ class หรือ 1 map สำหรับทั้ง session สำหรับ 1 map สำหรับทั้ง sessionจะไม่มีปัญหากับ inheritance เพราะจะมีเพียง map เดียวเท่านั้น Identity Map สามารถเรียกได้ทั้งแบบเฉพาะเจาะจงและแบบทั่วไป การเรียกแบบเฉพาะเจาะจงจะมีเมธอดที่เรียกโดยเฉพาะโดยใช้ primary key เป็น input ของเมธอด ส่วนการเรียกแบบทั่วไปจะเป็นเมธอดมาตรฐาน เวลาเรียกต้องใส่สองพารามิเตอร์คือชื่อ table และ primary key ถ้าคุณใช้ Unit of Work สามารถทำงานร่วมกับ Identity Map ได้ดีหรือถ้าไม่ได้ใช้ก็ควรใช้ร่วมกับ Registry ที่ควบคุม session
- การใช้งาน โดยทั่วไป Identity Map ถูกใช้ในการจัดการ object ใดๆที่ดึงจากฐานข้อมูลและมีการเปลี่ยนแปลง Identity Mapสามารถเป็น cache ในการอ่านฐานข้อมูล ไม่ควรใช้ Identity Map ใน Dependent Mapping เพราะ dependent object ถูกควบคุมโดย parent Identity Map ช่วยให้หลีกเลี่ยงความขัดแย้งในการ update ภายใน session เดียวกัน แต่ไม่สามารถแก้ปัญหาความขัดแย้งระหว่าง session ได้
- Lazy Load
- นิยาม object ที่ไม่มีข้อมูลอยู่ในตัวแต่รู้ว่าจะดึงข้อมูลได้จากที่ไหน นั่นคือการ load data จาก data source เข้ามาใน object ต่อเมื่อต้องการเท่านั้น เพื่อลดการ load ข้อมูลที่ไม่จำเป็นเข้ามา
- ปัญหา ในการโหลดข้อมูลจากฐานเข้าสู่หน่วยความจำ เป็นการง่ายที่จะออกแบบให้โหลด object ที่สนใจและ object ที่มีความเกี่ยวข้องทั้งหมด ซึ่งอาจจะมีจำนวนมหาศาล ทำให้ประสิทธิภาพการทำงานลดลงไปอย่างมาก ทั้งที่ต้องการใช้ object จริงๆไม่กี่ตัว
- วิธีการแก้ไข Lazy Load ทำการขัดจังหวะการโหลดชั่วระยะเวลาสั้นๆ เพื่อใส่ marker ในโครงสร้าง object เมื่อต้องการข้อมูลจะสามารถโหลดเฉพาะส่วนที่ต้องการใช้จริงๆ การใช้งาน Lazy load สามารถสร้างได้ 4 ลักษณะ
- Lazy Initialization ทุกครั้งที่มีการเข้าถึง field จะถูกตรวจสอบว่าเป็น null หรือไม่ ถ้าเป็น null จึงจะดึงข้อมูลมา ซึ่งจำเป็นจะต้องกระทำผ่านเมธอด get วิธีนี้ใช้ได้ดีกับ Active Record, Table Data Gateway และ Row Data Gateway
- Virtual Proxy เป็น object ที่ดูคล้ายกับอยู่ใน field แต่ไม่มีข้อมูลอะไรอยู่ภายใน แต่สามารถโหลด object จากฐานข้อมูลได้ถูกต้อง วิธีนี้ใช้ได้ดีกับ Data Mapper
- Value Holder เป็น object ที่ใช้หุ้ม object อื่น การดึงค่าจาก object ที่อยู่ภายในต้องกระทำผ่าน Value Holder แต่การเรียกข้อมูลครั้งแรกจะดึงข้อมูลจากฐานข้อมูล
- Ghost เป็น object ที่อยู่ใน partial state เมื่อคุณโหลด object ออกจากฐานข้อมูลจะมีแต่ ID เท่านั้น ซึ่งสามารถนำ ID มาเรียกข้อมูลมาเรียก field ในฐานข้อมูลได้ เรียกว่า full state
- หมายเหตุ Virtual Proxy/ghost ไม่จำเป็นที่จะต้องไม่มีข้อมูล
- การเลือกใช้ การตัดสินใจใช้ Lazy Load หรือไม่ มาจากจำนวนข้อมูลที่ต้องดึงจากฐานข้อมูลในการโหลด object และ จำนวนการเรียกใช้งานฐานข้อมูล และ Lazy Load จะมีประโยชน์มากเมื่อ field นั้นต้องใช้วิธีการเรียกที่ต่างออกไปจากปกติ Lazy Load อาจทำให้เกิดการเชื่อมต่อกับฐานข้อมูลมากขึ้น เนื่องจากการดึงข้อมูลมาทีละ table แทนที่จะดึงมาทีเดียวทั้งหมดในครั้งเดียว
Object-Relational Structural Patterns
- Identity Field
- นิยาม บันทึก field ID ของฐานข้อมูลเพื่อใช้เชื่อมโยงระหว่าง object ในหน่วยความจำและ row ในฐานข้อมูล
- ปัญหา ในฐานข้อมูลจะบอกความแตกต่างระหว่าง row โดยใช้ primary key แต่ object ในหน่วยความจำ ไม่ต้องใช้ key การอ่านข้อมูลจากฐานสามารถทำได้ปกติ แต่การเขียนข้อมูลลงไปจำเป็นต้องผูกฐานข้อมูลเข้ากับ object ในหน่วยความจำ
- วิธีแก้ไข Identity Field เป็นการเก็บ primary key ของฐานข้อมูลใน field (ตัวแปร) ของ object
- ควรใช้เมื่อ
- ใช้ Identity Field เมื่อต้องการ map ระหว่าง object ในหน่วยความจำและ row ในฐานข้อมูล มักใช้ใน Domain Model หรือ Row Data Gateway
- คุณไม่จำเป็นต้องใช้ Identity Field เมื่อใช้งาน Transaction Script, Table Module หรือ Table Data Gateway
- ในกรณีที่เป็น object เล็กๆ ที่มีตัวแปรเฉพาะไม่กี่ตัว เช่น เงิน ไม่ต้องจำเป็นต้องมี table ของตัวเอง ควรใช้ Embedded Value
- กรณีที่ object มีการเชื่อมโยงกันอย่างซับซ้อนและไม่จำเป็นต้องดึงข้อมูลจากฐาน ควรใช้ Serialized LOB จะเขียนได้ง่ายและมีประสิทธิภาพมากกว่า
- การใช้งาน การเลือก key
- ชื่อ Key ที่มีความหมายกับ ชื่อคีย์ที่ไม่มีความหมาย
- Key เดี่ยวกับ Key ผสม Key ผสมมีข้อดีตรงที่ง่ายในการใช้งาน ถ้าคุณใช้ key เดี่ยวเสมอ สามารถใช้โค้ดเดียวกันจัดการ ในขณะที่ Key ผสม จะมีความซับซ้อนในการเขียนโปรแกรมมากขึ้น
- ชนิดข้อมูลของ key เพื่อการเปรียบเทียบง่ายและรวดเร็ว ควรใช้ข้อมูลชนิด long integer หลีกเลี่ยงการใช้ string เพราะทำงานได้ช้าและการเพิ่มของ string ทำได้ยากกว่า เช่นเดียวกับ date และ time นอกจากจะไม่สื่อความหมายแล้ว ยังทำให้เกิดปัญหาเรื่อง portability และ consistency ด้วย
- Table-unique กับ database unique key Table-unique เป็นเอกลักษณ์ภายใน table ส่วน Database unique เป็นเอกลักษณ์ระหว่างทุก row ในทุก table ในฐานข้อมูล ซึ่ง Database unique ใช้งานได้ง่ายกว่า
- ถ้าคุณใช้ Concrete Table Inheritance หรือ Class Table Inheritance unique ใน hierarchy มากกว่า unique ในแต่ละ table
- การแสดง Identity Field ใน object
- กรณีง่ายที่สุดคือ field ที่ match กับชนิดของ key ในฐานข้อมูล ถ้าคุณใช้ key เป็นตัวเลข จะเข้ากับ field ที่เป็นตัวเลขเช่นกัน
- กรณีที่เป็น key ผสมจะมีความยุ่งยากมากขึ้น ควรสร้างคลาสของ key
- ถ้าคุณใช้โครงสร้างคล้ายๆกันในแต่ละ key ควรสร้าง Layer SuperType? แล้วใส่เมธอดที่คลาสนิยมใช้กันบ่อยๆลงไป แล้ว extend ในกรณีที่ต้องใช้เมธอดอื่นเพิ่มเติม
- การสร้าง key ใหม่
- ตั้งฐานข้อมูลในสร้างโดยอัตโนมัติ เมื่อใดที่คุณใส่ข้อมูลลงในฐาน ฐานจะกำหนด primary key ให้เอง
- GUID, UUID เป็นตัวเลขที่เครื่องสร้างขึ้นเพื่อให้แยกแยะเครื่องในระบบ ข้อเสียคือ key มีขนาดใหญ่
- สร้างขึ้นเอง วิธีที่ง่ายที่สุดคือหา key ที่ใหญ่ที่สุดแล้วนำมาบวกหนึ่ง วิธีนี้ขณะทำต้องล็อกทั้ง table เพื่อป้องกันความผิดพลาด หรือวิธีที่ดีกว่า คือใช้ table ใส่เฉพาะ key แยกออกมา โดยจะมี 2 คอลัมน์ คือ ชื่อ table กับค่า key ล่าสุด ซึ่งแต่ละ row คือแต่ละ table ในฐาน การใช้ key table ผู้ใช้จะเข้ามาดูว่าเลข key ล่าสุดเป็นเท่าไหร่จากนั้นไปบวกหนึ่งแล้วกลับมาแก้ไขในตาราง
- Foreign Key Mapping
- นิยาม map ความสัมพันธ์ระหว่าง object กับ foreign key
- ปัญหา object สามารถอ้างถึงกันโดยตรงผ่าน object reference ระบบที่ออกแบบโดยใช้แนวคิดเชิงวัตถุจะประกอบด้วย object จำนวนมากที่เชื่อมต่อกันในหลายๆวิธี หลายกรณี object จะเก็บกลุ่มของ reference ไว้ใน object ด้วย ซึ่งการเก็บ object ลงในฐานข้อมูล จำเป็นต้องเก็บข้อมูล reference เหล่านั้นด้วย
- วิธีแก้ไข Foreign Key Mapping จะ map object reference ในรูปของ foreign key ในฐานข้อมูล ถ้าสอง object เชื่อมต่อกัน ซึ่งการเชื่อมโยงสามารถเปลี่ยนเป็น foreign key
- ควรใช้เมื่อ
- ในฐานข้อมูล เมื่อคุณมีกลุ่มของ object คุณต้องกลับทิศทางของความสัมพันธ์ เช่น ถ้าคุณมีกลุ่มของแทรคในอัลบั้ม คุณต้องใส่ foreign key ของอัลบั้มใน record ของแทรค
- การใช้งาน Foreign Key Mapping ใช้ในการเชื่อมโยงระหว่างคลาสได้เกือบทุกกรณี ยกเว้นกรณีที่มีความสัมพันธ์แบบ many-to-many จำเป็นต้องใช้ Association Table Mapping
- ถ้า object ที่เกี่ยวข้องด้วยเป็น Value Object ต้องใช้วิธี Embedded Value แทน
- วิธีการใช้ มีวิธีการ update สามวิธี
- ลบแล้วใส่เข้าไปใหม่
- ใส่ back pointer
- Diff the collection
- Association Table Mapping
- นิยาม บันทึกความสัมพันธ์ระหว่าง table ในรูปแบบ foreign key ไว้ในอีก table หนึ่ง
- ปัญหา เมื่อคุณ map ความสัมพันธ์แบบ one-to-many คุณสามารถใช้ Foreign Key Mapping ได้แต่สำหรับ many-to-many ไม่สามารถใช้ได้ เพราะปลายข้างใดข้างหนึ่งของ foreign key ไม่ใช่ค่าๆเดียว
- วิธีแก้ไข แนวคิด Association Table Mapping คือ การใช้ table ในการเก็บความสัมพันธ์ ซึ่ง table นี้จะเก็บแต่ foreign key ID สำหรับสอง table ที่เชื่อมโยงกัน ซึ่งจะมี 1 row ต่อ 1 คู่ของ object ที่มีความสัมพันธ์กัน กรณีนี้จะใช้เฉพาะกับความสัมพันธ์ many-to-many เท่านั้น
- Dependent Mapping
- นิยาม มีคลาสๆหนึ่งทำหน้าที่ map ฐานข้อมูลสำหรับ class ลูก
- ปัญหา บาง object ย่อยที่อยู่ภายใต้ object เจ้าของแล้วต้องการติดต่อกับฐานข้อมูล เป็นการดีกว่าถ้าสร้าง mapping ใน object หลัก เพื่อให้ object ย่อยสามารถใช้งานได้ด้วย
- วิธีแก้ไข แนวคิดคือคลาสย่อยที่ใช้ต้องอยู่ภายใต้คลาสเจ้าของเพียงคลาสเดียวเท่านั้นและไม่ถูกอ้างถึงโดยคลาสอื่นใดนอกจากคลาสเจ้าของ เมื่อโหลดคลาสเจ้าของแล้วมักจะต้องโหลดคลาสย่อยด้วย เว้นแต่คลาสย่อยใช้ทรัพยากรสูงจะใช้ Lazy load ช่วยควบคุมให้โหลดคลาสย่อยเมื่อจำเป็นเท่านั้น แต่ไม่แนะนำเมื่อใช้ Unit of Work เนื่องจาก Unit of Work ไม่สามารถควบคุมคลาสย่อยได้ นอกจากนั้น คลาสย่อยสามารถเป็นเจ้าของคลาสย่อยลงไปอีกได้ แต่หน้าที่การ mapping เป็นของคลาสเจ้าของของคลาสย่อยที่ใหญ่ที่สุด
- Embedded Value
- นิยาม แมป object เข้ากับหลายๆ field ของ table
- ปัญหา ข้อมูลเล็กๆ บางอย่างเช่น อายุ ไม่จำเป็นต้องเก็บไว้ในฐานข้อมูล สามารถสร้าง object เล็กๆเพื่อเก็บข้อมูลเหล่านั้นได้
- วิธีแก้ไข Embedded Value แมปค่าของ object เข้ากับ field ในฐานข้อมูลใช้กับความสัมพันธ์แบบ 1 to 1 เท่านั้น กรณีที่โครงสร้างข้อมูลมีความซับซ้อนควรใช้ Serialized LOB เมื่อ objectเจ้าของทำการโหลดหรือบันทึกข้อมูล object ย่อยก็จะทำเช่นเดียวกัน
- Serialized LOB
- นิยาม เก็บสถานะของ object เล็กๆหลายๆ object ไว้ใน object ขนาดใหญ่ object เดียว
- ปัญหา object ประกอบด้วย state ที่สลับซับซ้อนของ object เล็กๆจำนวนมากและข้อมูลส่วนใหญ่ไม่ได้อยู่ใน object แต่อยู่ใน link ระหว่าง object ซึ่งมีความยุ่งยากในการใส่ลงในฐานข้อมูล ซึ่งต้องใช้ join จำนวนมากทำให้ทำงานช้า
- Single Table Inheritance
- Class Table Inheritance
- Concrete Table Inheritance
- Inheritance Mapper
Object-Relational Metadata Mapping Patterns
- Metadata Mapping
- นิยาม เก็บรายละเอียดของ ORM ไว้ในเมตาดาด้า ORM คือ
- ปัญหา โค๊ดในการติดต่อกับ ORM ที่อธิบายว่าฟิล์ดในฐานข้อมูลกับฟิล์ดใน object ในหน่วยความจำ มีความสัมพันธ์กันอย่างไร เป็นการเขียนโค๊ดที่ซ้ำซากจำนวนมาก
- วิธีแก้ไข การใช้ Metadata Mapping ช่วยให้ผู้พัฒนาสามารถอธิบายการ mapping ในรูปแบบตารางง่ายๆ ซึ่งสามารถจัดการข้อมูลได้โดยโค๊ดทั่วๆไป
- การใช้งานเมื่อ ใช้เมื่อต้องการ map ฐานข้อมูลกับ object ในหน่วยความจำ
- วิธีการใช้ การใช้งานกระทำได้ 2 วิธี คือ
- Code generation เป็นโปรแกรมที่ input เป็นเมตาดาต้า และ output เป็นโค๊ดของคลาสที่ใช้ในการทำ mapping ซึ่งการเปลี่ยนแปลงแก้ไขต้องแก้ที่ตัวโปรแกรม ต้องทำการ compile และ deploy ใหม่
- Reflective programming โดยจัดการกับเมธอดและฟิล์ดในลักษณะข้อมูลของโปรแกรม ซึ่งสามารถอ่านฟิล์ดและชื่อเมธอดจากไฟล์เมตาดาต้า การเปลี่ยนแปลงแก้ไขสามารถทำได้ง่าย แต่มีข้อเสียเรื่องความเร็ว
- หมายเหตุ เมตาดาต้าสามารถเก็บในรูปแบบของไฟล์ ส่วนมากเป็นฟอร์แมต XML อย่างไรก็ตามเมตาดาต้ายังสามารถเก็บไว้ในตัวโค๊ดเองหรือในฐานข้อมูลได้
- Query Object
- นิยาม object ที่ทำหน้าที่ query ฐานข้อมูล
- ปัญหา SQL เป็นภาษาที่ซับซ้อน โปรแกรมเมอร์ส่วนมากไม่ค่อยคุ้นเคยนัก อีกทั้งยังจำเป็นต้องรู้ schema ของฐานข้อมูลเพื่อทำการ query อีกด้วย
- วิธีแก้ไข Query Object เป็น interpreter [GoF] หรือโครงสร้างของ object ที่สามารถแปลงตัวเป็น SQL query ได้
- การใช้งานเมื่อ Query Object เป็น pattern ที่ค่อนข้างซับซ้อนในการประกอบเข้าด้วยกัน ดังนั้นส่วนใหญ่ไม่ค่อยมีการใช้งาน ถ้าเป็นกรณีที่สร้าง data source layer ขึ้นเอง แต่ในทางกลับกันกรณีที่ใช้ domain model และ data mapper pattern นี้จำเป็นอย่างมาก แต่ไม่เสมอไป กรณีที่โปรแกรมเมอร์มีความชำนญด้าน SQL คุณสามารถซ่อนรายละเอียดของฐานข้อมูลไว้ในเมธอดค้นหาได้
- วิธีการใช้งาน คุณสามารถสร้าง Query Object ให้น้อยที่สุดตามความจำเป็นและค่อยปรับเปลี่ยนมันเมื่อความจำเป็นเพิ่มมากขึ้น การทำงานพื้นฐานของ Query Object เป็นการ query ใน object มากกว่าในฐานข้อมูล แทนที่คุณใช้ชื่อ table และชื่อ column ก็ใช้ object และชื่อ field แทน และสามารถออกแบบให้ใช้ร่วมกับฐานข้อมูลหลายๆฐานและ schema หลาย schemaได้ด้วย
- Repository
- นิยาม ตัวกลางระหว่าง domain และ data mapping layer ใช้ interface แบบ collection ในการเข้าถึง domain object
- ปัญหา ระบบที่มี domain model ซับซ้อนมักจะได้ประโยชน์จาก layer เช่นจาก Data Mapper ซึ่งจะแยก domain object ออกจากรายละเอียดของโค๊ดที่ใช้เข้าฐานข้อมูล สำหรับระบบที่มี domain คลาสจำนวนมากๆ หรือทำการ query หนักๆ การสร้าง layer ของ abstraction เพิ่มขึ้นอีก layer หนึ่งบน mapping layer ที่มีการ query มากๆ เพื่อใช้พักข้อมูล จะช่วยลดความซ้ำซ้อนของ query logic ได้
- วิธีการแก้ไข Repository เป็นตัวกลางระหว่าง domain และ data mapping layer คล้ายกับตัวรวมรวม domain object ในหน่วยความจำ Object สามารถใส่เพิ่มหรือลบออกจาก Repository ได้ ผู้ใช้งานไม่จำเป็นต้องรู้เกี่ยวกับฐานข้อมูล
- การใช้งานเมื่อ ระบบขนาดใหญ่ประกอบด้วยหลายๆ domain object และการสืบค้นจำนวนมาก Repository ช่วยลดจำนวนโค๊ดที่จำเป็นในการสืบค้นเหล่านั้นลง และช่วยให้อ่านและทำความเข้าใจโค๊ดได้ดียิ่งขึ้น แต่ทีมพัฒนาควรจะใช้เครื่องมือ ORM ที่มีมากับ application server มากกว่าการสร้างขึ้นเอง
- หมายเหตุ วิธีการใช้งาน Repository เป็นการรวม Metadata Mapping ร่วมกับ Query Object เพื่อสร้าง SQL โดยอัตโนมัติ object source ของ Repository ไม่จำเป็นต้องเป็นฐานข้อมูล อาจจะเป็น object ด้วยกัน
Web Presentation Patterns
- Model View Controller
- นิยาม เป็น Design Pattern ที่ใช้ในการออกแบบระบบ โดยแยกส่วนการทำงานเป็น 3 ส่วน ได้แก่
- Model เป็นส่วนที่เก็บข้อมูลและดูแลเรื่อง Logic ต่างๆ ซึ่งเป็น object ใน domain model
- View เป็นส่วนที่ใช้แสดงผลข้อมูล และใช้ติดต่อผู้ใช้
- Controller เป็นส่วนที่ใช้เลือกว่า action แบบนี้ควรใช้ model ไหน view ไหน เป็นส่วนที่เก็บอินพุทและจัดการเมื่อมีการเปลี่ยนแปลงข้อมูล
- หมายเหตุ จะเห็นว่า UI เป็นองค์ประกอบของ view และ controller
- วิธีการใช้ การแยกส่วนของการแสดงผล (view) ออกจากส่วนของข้อมูล (model) เป็นส่วนที่สำคัญที่สุดของการออกแบบวิธีนี้ การที่ไม่ทำตามได้กรณีเดียวคือเป็นระบบที่ง่ายมากๆ เนื่องจากภายใน model ไม่มี behavior ส่วนการแยกระหว่าง view กับ controller มีความสำคัญน้อยกว่า การแยกจะทำเมื่อจำเป็น
- Plate Controller
- Front Controller
- Template View
- Transform View
- Two Step View
- Application Controller
Distribution Patterns
- Remote Facade
- นิยาม เป็นเมธอดใหญ่ที่ทำงานแทนเมธอดย่อยๆทั้งหมดของ object เพื่อเพิ่มประสิทธิภาพในการทำงานผ่านเครือข่าย
- ปัญหา ในการออกแบบเชิงวัตถุ ยิ่ง object เล็กและมี method น้อยๆก็ยิ่งดี ซึ่งทำให้เกิดปฏิสัมพันธ์ระหว่าง object จำนวนมาก และการติดต่อกันจำเป็นต้องมีการเรียกเมธอดจำนวนมาก ซึ่งไม่มีปัญหาอะไรถ้าเป็นการเรียกภายใน process เดียวกัน แต่ถ้าเรียกระหว่าง process หรือเรียกผ่านเครือข่าย จะทำให้ประสิทธิภาพลดลงอย่างมาก จึงจำเป็นต้องสร้าง interface หยาบๆขึ้นมาเพื่อลดการเรียกเมธอดเล็กๆจำนวนมากเหล่านั้น
- วิธีแก้ไข Remote Façade เป็น façade [GoF] แบบหยาบใช้แทนกลุ่มของ object เล็กๆ ซึ่งไม่มี domain logic และเมธอดหยาบๆเหล่านี้จะแปลงเป็นเมธอดเล็กๆใน object เหล่านั้น
- การใช้งาน ควรใช้เมื่อ Remote Façade ใช้เมื่อจำเป็นต้องการติดต่อกับ object เล็กๆ จากระยะไกล ในกรณีที่ง่าย Remote Façade จะแทนที่เมธอด get และ set ทั้งหมดของ object ธรรมดาด้วย get 1 เมธอดและ set 1 เมธอด เมื่อเรียกเมธอด set หรือ get ของ Remote Façade ก็จะไปเรียกเมธอดย่อยๆของ object อีกที ในกรณีซับซ้อน Remote Façade ทำหน้าที่เป็น gateway สำหรับ object ย่อยๆหลายตัว แต่ในกรณีที่มีความสลับซับซ้อนมากๆ ทำ serializable เป็นเรื่องยาก แนะนำให้ใช้วิธี Data Transfer Object Remote Façade สามารถเป็นได้ทั้ง stateless หรือ stateful stateless Façade สามารถทำ pool ได้ เพื่อเพิ่มประสิทธิภาพ ส่วน stateful จะเก็บข้อมูล จะเก็บสถานะไว้สามารถใช้ในการสร้าง Server Session State ได้ และRemote Façade สามารถทำ transaction control ได้ด้วย อย่างไรก็ตามไม่ควรใส่ domain logic ลงไปในนั้น
- Data Transfer Object
- นิยาม Transfer Data ระหว่าง layer/tier เป็นส่วนหนึ่งของ contract ที่ใช้ตกลงระหว่างกันก็ได้ (ว่า data ที่จะส่งไปส่งมา จะมีหน้าตาเป็นอย่างไร) ส่วนใหญ่ DTO ออกแบบมาเพื่อเป็น data wrapper (Getter/Setter) เท่านั้น เป็น object ที่ใช้ขนส่งข้อมูลระหว่าง process เพื่อลดจำนวนการเรียกเมธอดนั่นเอง
- ปัญหา เมื่อคุณทำงานร่วมกับ remote interface เช่น remote façade การเรียกแต่ละครั้งใช้ทรัพยากรระบบสูง ทำให้ต้องลดจำนวนครั้งที่เรียก โดยการส่งข้อมูลให้มากขึ้นในการเรียกแต่ละครั้ง วิธีการหนึ่งคือใช้พารามิเตอร์ให้มากขึ้น ซึ่งจะทำให้โปรแกรมยุ่งยากและประสิทธิภาพลดลง
- วิธีแก้ไข การสร้าง Data Transfer Object เพื่อรับส่งข้อมูลทั้งหมดกับ remote object สำหรับการเรียกแต่ละครั้ง ซึ่งจำเป็นต้อง serializable เพื่อให้ส่งผ่านเครือข่ายได้
เมื่อใดต้องใช้ การใช้ Data Transfer Object จำเป็นต้องขนส่งข้อมูลหลายตัวระหว่างสอง process ในการเรียกเมธอดเดียว และยังสามารถในการสื่อสารระหว่างส่วนประกอบที่ใช้
XML เพราะการใช้ DOM เป็นเรื่องยุ่งยาก การใช้ Data Transfer Object encapsulate ส่วนประกอบเหล่านั้น จะช่วยให้ง่ายขึ้น อีกทั้งยังใช้ส่งผ่านข้อมูลระหว่าง layer ต่างๆ
-
- วิธีการใช้ คุณไม่สามารถเคลื่อนย้าย object จาก domain model เพราะ object จะเชื่อมโยงกันเป็นเครือข่าย ยากในการทำ serialize และคุณไม่ต้องการให้คลาส domain object ไปอยู่ที่ client ซึ่งไม่ต่างอะไรกับสำเนา Domain model ทั้งหมดไปไว้ที่นั่น
- ฟิล์ดใน Data Transfer Object มีลักษณะง่ายๆ เช่น String Date หรือ Data Transfer Object ตัวอื่น
- โครงสร้างระหว่าง Data Transfer Object เป็นแบบกราฟอย่างง่าย(Hierarchy) ตรงข้ามกับรูปแบบที่ซับซ้อนของ Domain Model รูปแบบทั่วไปเป็น Record Set หรือ dictionary ซึ่งสามารถใช้คำที่มีความหมายเป็น key ในการค้นได้
- Serialize Data Transfer Object Data Transfer Object จะสามารถ Serialize ตัวเองให้อยู่ในรูปแบบที่ส่งผ่านเครือข่ายได้ อย่างไรก็ดี เมื่อมีการเปลี่ยน Data Transfer Object ที่ฝั่ง server ฝั่ง client จำเป็นต้องปรับตาม เพื่อไม่ให้เกิดปัญหาเวลา deserialization
- การประกอบ Data Transfer Object ใน Domain model Data Transfer Object ควรเป็นอิสระจาก domain object ดังนั้นควรแยก object ที่รับผิดชอบการสร้าง Data Transfer Object ออกมาจาก domain model และปรับเปลี่ยน model จาก object นั้น
Offline Concurrency Patterns
- Optimistic Offline Lock
- Pessimistic Offline Lock
- Coarse-Grained Lock
- Implicit Lock
Session State Patterns
- Client Session State
- Server Session State
- Database Session State
Base Patterns
- Gateway
- Mapper
- Layer Supertype
- Separated Interface
- Registry
- Value Object
- Money
- Special Case
- Plugin
- Service Stub
- Record Set
สรุปการอบรมโดย นาย ธนพล วิสุทธิกุล