Tuesday, September 06, 2005

Ruby กับ Design by Concern

ผมได้ทดลองเขียน program เพื่อทำการ plot graph แสดงการใช้งานของ user
โดยใช้ Ruby language เขียน

ตัวโปรแกรมมี Requirement ดังนี้
  • R1 สามารถอ่านข้อมูลจาก file wtmp ใน aix ได้โดยตรง
  • R2 สามารถสรุปข้อมูลนำมา plot เป็น graph แสดงเวลาการทำงานของ user
    ในช่วงวันที่กำหนดได้
  • R3 แสดงช่วงเวลาที่มีจำนวน concurrent user เกินกว่าค่าที่กำหนด


output หน้าตาประมาณนี้



ออกแบบ class diagram ดังนี้



ใน class diagram จะแสดงว่า Requirement ข้อไหน implement
ใน class อะไรบ้าง

ปัญหาที่เรามักเจอในการ design โปรแกรม ก็คือ Requirement หนึ่งๆ
มักจะกระจายตัวอยู่ใน class (เผอิญตัวอย่างนี้เป็นโปรแกรมเล็กๆ ก็เลยไม่ค่อยเห็นประเด็นนี้เท่าไร)
ทำให้เมื่อมีการเปลี่ยนแปลง requirement เกิดขึ้นต้องกระทบกับหลายๆ class
หรือไม่ก็ ถ้ามีการเพิ่ม requirement ใหม่ๆ เข้ามา Requirement
นั้นก็มักจะทำให้เกิดการเปลี่ยนแปลง class หลายๆ class

ตัว Ruby เอง เปิดโอกาสให้เรา implement class แยกกระจายหลายๆ
ที่ได้ ทำให้เราสามารถจัดกลุ่ม file ตาม concern (requirement)
แทนที่จะแยก 1 file 1 class

ในโปรแกรมที่ผมลองทำ ผมทดลองแยก Requirement R3
ออกเป็นเป็นอีก file
ภายใน file นี้ผมก็ extend class Plotter กับ class UserTimeLine
เฉพาะส่วนที่เกี่ย่วข้องกับ Requirement ที่ 3 นี้เท่านั้น



ซ้ายบนเป็น class UserTimeLine ส่วนซ้ายล่างเป็น class Plotter
ทางขวาเป็น file ที่ implement Requirement R3
เส้นสีแดง แสดงว่ามีการ extend class
ส่วนสีน้ำเงิน แสดง dependency ภายในของ Requirement R3


ข้อดีของวิธีนี้ อืมม์ ไม่ค่อยแน่ใจนัก
มันทำให้เรา concentrate บน Requirement มากขึ้น
เห็น class ที่ต้อง implement feature นั้นๆ อยู่เป็นกลุ่มก้อนเดียวกัน
(อาจจะทำให้ง่ายต่อการจัดการ)
เวลาอ่าน class ต่าง ก็อาจจะอ่านง่ายขึ้น เพราะจะเห็นแต่ส่วนที่ตัวเองเกี่ยวข้องเท่านั้น
(อันนี้อาจเป็นข้อเสียก็ได้ เห็นแต่ส่วนตัวเอง ทำให้ลืมนึกไปว่า
อาจจะมีคนอื่นใช้อยู่ก็ได้ ทำให้แก้ไขไม่ระวัง)

Note: extend ในที่นี้ไม่ได้หมายถึง extends แบบที่เราทำใน Java
แต่มีความหมายเป็นการ Merge เสียมากกว่า

Related link from Roti

No comments: