Tour de France #3: Object-Oriented #2

Heuristics

   

มุมมอง

    ทุกวันนี้โฆษณามีบทบาทในชีวิตประจำวันของเรามาก แทบจะไม่มีโฆษณาไหนเลยที่เป็นจริง 100% แต่ในเวลาเดียวกันมันก็ไม่ใช่เป็นเท็จไปเสียทั้งหมด บางทีเวลาบริโภคสื่อคงต้องพิจารณากันมากหน่อย

    Object Oriented ก็เช่นเดียวกัน มีคนอยู่ไม่น้อยที่พยายามชี้ชวนให้เข้าใจว่ามันเป็นวิธีที่ดีที่สุด เป็นยาครอบจักรวาล โดยเฉพาะอย่างยิ่งพวกนัก Methodologists ทั้งหลาย ที่ปากท้องนั้นผูกอยู่กับความนิยมของ Object Oriented ในความเห็นของผมเอง Object Oriented เป็นวิธีที่ดีวิธีหนึ่งในการแก้ปัญหา แต่มันก็ไม่ได้เหมาะสมกับทุกปัญหานะครับ บางครั้งมันก็อาจจะสู้วิธีอื่นๆ ไม่ได้ แต่โดยภาพรวมแล้ว มันดูดีที่สุดในยุคปัจจุบัน

 

จุดด้อยของ Object Oriented : ยาก

    แนวคิดของ Object Oriented นั้น วันนี้มันยังไม่เป็นศาสตร์เสียเลยทั้งหมด มันยังส่วนของศิลป์ผสมอยู่ค่อนข้างมาก ปัญหาบางปัญหาถ้าไปให้ปรมาจารย์ด้าน Object Oriented หลายๆ ท่านมาแก้ปัญหา วิธีที่ได้อาจจะไปคนละแบบ ซึ่งบางทีอาจจะตรงข้ามกันเลยด้วยซ้ำ ลองดูใน USENET สิครับ ผมเจอปรมาจารย์ในวงการนี้เถียงกันบ่อยมากครับ ใช่แล้วครับ Object Oriented มันยังไม่โตเต็มที่นัก ในความเห็นของผม ถ้าเทียบกับ Relational Database ผมว่าแนวคิดของ Relational Database สมบูรณ์กว่า Object Oriented มากครับ เรื่องนี้คงต้องใช้เวลาอีกมากสำหรับ OO

    การเรียนรู้ OO กับระยะเวลา บางทีมันก็ไม่ค่อยสัมพันธ์กัน บางคนอาจจะบอกว่า เขาใช้ OO มาเป็น 10 ปีแล้ว ก็ไม่ได้หมายความว่าเขาจะเก่ง OO เขาอาจจะไม่รู้จัก OO เบื้องต้นเลยด้วยซ้ำไป OO ไม่ใช่การใช้ class , Inheritance หรือ Polymorphism นะครับ แต่หากมันเป็นหลักการที่ดึงเอาสิ่งเหล่านี้ไปใช้

    ผมเองก็เช่นเดียวกัน เมื่อประมาณ 10 ปีที่แล้ว ผมก็เรียนรู้ภาษา C++ ผมรู้หมดนั่นแหละครับ การใช้ class, inheritance, polymorphism อีกสารพัดเลยครับที่ C++ มี แต่มีสิ่งหนึ่งที่ผมตอบไม่ได้ในเวลานั้นก็คือ มันเอาไปใช้งานจริงๆ ได้อย่างไร ในเวลานั้น ผมสร้าง class ขึ้นมา ภายในมีตัวแปร ทำไมหนังสือทุกเล่มถึงต้องสร้าง Method Set/Get มาเพื่อเป็นนายหน้าในการจัดการตัวแปรตัวนั้น ทำไมถึงไม่ให้เรียกใช้งานตัวแปรโดยตรงซึ่งสะดวกกว่ามากครับ เวลานั้นผมคิดว่า หนังสือต่างๆ ไม่ได้เรื่อง ที่สร้าง Set/Get ก็เพียงแค่ต้องการแสดงให้ถึงการเรียกใช้งาน Method ก็เท่านั้น แต่นั่นเป็นสิ่งที่ผิดครับ

    ดังนั้นผมว่าผมเสียเวลาหลายปีกับ OO โดยไม่ได้อะไรเป็นชิ้นเป็นอัน ผมจึงไม่กล้าจะพูดว่าตัวเองมีประสบการณ์ 10 ปี สำหรับ OO ครับ พูดไป มันก็กระดากปากตัวเอง

    มีสถิติตัวหนึ่งน่าสนใจครับ Alistair Cockburn เขียนในหนังสือ Surviving Object Oriented Project ของเขาว่า เขาใช้เวลาในการไปคุยกับผู้ดูแล Project ต่างๆ ที่พยายามเปลี่ยนแนวคิดในการพัฒนา Software จากเดิม Data Flow Approch มาเป็น Object Oriented เขาพบว่าอุปสรรคหลักก็คือ ความไม่รู้ Object Oriented นั่นเอง ส่วนมากแล้วที่ตกม้าตายก็คือ พวกที่ใช้ภาษา C เดิมนั่นแหละครับ ที่คิดเอาว่าการเปลี่ยนมาใช้ C++ เป็นเรื่องง่าย เพราะรู้ภาษา C ดีอยู่แล้ว เพียงแค่เรียนรู้ Keyword เพิ่มไม่กี่ตัว ส่วนมากก็ไปไม่รอดครับ เพราะแนวคิดของ OO มีมากกว่า Syntax ถ้าไปฝืนใช้ OO โดยไม่มีความรู้พอ ยุ่งมากกว่าดีครับ

    ในทางกลับกันทีมที่ใช้ภาษา COBOL มาก่อน มักจะไปรอด ผมอนุมานเองว่าน่าจะเป็นเพราะเขารู้ว่าสิ่งที่เขาใช้อยู่ มันล่าสมัยมาก เขาจึงเปิดกว้างยอมรับแนวคิดใหม่ได้ง่าย

    แล้วการอบรมทีมโปรแกรมเมอร์ควรใช้เวลาเท่าไหร่ ทุกวันนี้สำหรับ VB6+SQL ผมใช้เวลาประมาณ 1 เดือน ก็สามารถทำงานพอใช้ได้แล้ว แต่สำหรับ OO เต็มรูปแบบ เวลาเท่านี้ไม่เพียงพอแน่นอนครับ ตัวเลขจาก Cockburn คือ 9 เดือนครับ จริงๆ ครับไม่ได้ล้อเล่น 9 เดือนนี้หมายถึงเวลาที่ใช้อบรมแนวคิดของ OO (อาจจะไม่ใช่ full time) แต่เน้นนะครับ ต้องเป็น OO ที่ถูกต้อง ไม่ใช่ OO ที่มาเรียนกันแค่ Syntax จำพวก class, Inheritance, Polymorphism หรือ OO แบบให้งมกันเองนะครับ (เนื้อหาที่ผมเขียนบน Web นี้เกี่ยวกับ OO ส่วนมากแล้ว เป็น OO แบบ Syntax ครับ ซึ่งถือว่าเป็น OO บทที่ 1 หรือขั้นอนุบาลเท่านั้น)

ระดับของ Object Oriented

    ในวงการ OO มีการแบ่งระดับความรู้ของ Object Oriented ของแต่ละบุคคลอยู่นะครับ ตรงนี้อาจจะเป็นมาตราวัดความรู้ของ Object Oriented อย่างคร่าวๆ ได้ครับ เรามาลองดูทีละลำดับกัน

Underdog

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

Novice

    กลุ่มนี้เป็นกลุ่มที่เริ่มเรียนรู้ OO ที่ถูกทาง กลุ่มนี้เริ่มเข้าใจถึงปรัชญาของ OO ทำให้เห็นว่าแท้ที่จริงแล้ว OO นั้นมีอะไรให้ศึกษามาก มากจนน่าท้อใจ กลุ่มนี้เริ่มพยายาม เปลี่ยนแปลงแนวคิดแบบเดิมๆ มาใช้ class แต่ตัวเองก็รู้ตัวว่า มันก็ยังไม่ดูไม่ค่อยดี โดยปกติแล้ว ถ้าได้รับการศึกษา OO อย่างต่อเนื่อง เพียงแค่ 3 เดือนก็น่าจะพ้นระดับนี้ไปได้ แต่ถ้าหัวช้าหน่อยก็ไม่น่าเกินครึ่งปีครับ

Apprentice

    Apprentice ก็คือพวกฝึกหัดครับ ถ้าเป็นหนังจีนก็ทำนองว่า ฝากตัวเป็นลูกศิษย์กับอาจารย์ชื่อดัง โดยที่ทำงานบ้านแลกกับวิชา คนกลุ่มนี้เริ่มรู้จักแล้วครับว่า OO ที่แท้เป็นอย่างไร การออกแบบต่างๆ เริ่มใช้ได้ แต่ผู้ที่รู้มากกว่ามักจะ comment ได้ สรุปก็คืออยู่ในช่วงเรียนรู้ครับ โดยปกติแล้วจะใช้เวลาประมาณครึ่งปีครับ ถ้าศึกษาอย่างต่อเนื่อง

Journeyman

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

Guru

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

 

แล้ว ผู้เขียนเองหละอยู่ในระดับไหน

    ถึงแม้ว่า WebSite นี้จะชื่อว่า Twoguru ก็ตาม แต่เราทั้งสองก็ไม่ได้แม้แต่เฉียดความเป็น Guru ที่ตั้งชื่อ WebSite แบบนี้ก็เพราะอยากเป็น แต่ชั่วชีวิตนี้คงไปไม่ถึง แล้วถ้าถามผมว่าประเมินตัวเองอยู่ในขั้นไหน ผมพูดจริงๆ เลย ไม่ได้ถ่อมตัวแต่อย่างใด ผมยังไม่ถึงขั้น Journeyman ด้วยซ้ำไป คงต้องพยายามเรียนรู้ให้มากขึ้นครับ

 

Heuristics

    การเรียน OO นั้นมี 2 แนวทางครับ ทางแรกคือการเรียนแบบตามผู้ใหญ่ นั่นก็คือการเรียนรู้จากประสบการณ์ของคนอื่นที่สร้างเป็นสูตร เช่น Methodology หรือ Design Pattern เป็นต้น กับอีกวิธีหนึ่งคือการลองผิดลองถูกด้วยตัวเอง ซึ่งเราเรียกการเรียนแบบนี้ว่า Heuristics ซึ่งคำว่า Heuristics คือการเรียนโดยใช้ประสบการณ์นั่นเอง

    ในบทความนี้ผมคงเน้นแบบ Heuristics เป็นหลัก ส่วน Design Pattern คงเป็นอีกบทหนึ่งต่างหากครับ

    โดยส่วนตัวของผมแล้ว ผมให้น้ำหนักการศึกษาจาก Heuristics ของผู้อื่นหรือของตัวเอง มากกว่าสูตรที่ทำสำเร็จแล้ว ประสบการณ์เกิดจากการเจ็บมาก่อน เจ็บแล้วจำ เจ็บแล้วแก้ไขปรับปรุง การเรียนจาก Heuristics นั้นจะทำให้เราเข้าใช้ OO อย่างแท้จริงครับ

    เนื่องจากนี่คือบทความ ไม่ใช่การสอนเขียนโปรแกรม ผมเลยไม่ลงรายละเอียดเนื้อหาของ Heuristics แต่เอาอย่างนี้ ผมขอยกตัวอย่างปัญหาให้ไปคิดกันเล่นๆ ว่าถ้าเป็นคุณคุณจะแก้ปัญหาเหล่านี้อย่างไร

 

โจทย์ข้อที่ 1 ของ Riel:

    ถ้าเรามี class นักศึกษา, Class ลำดับชั้นของวิชา pre  ถ้านักศึกษาต้องลงทะเบียนเทอมนี้ ต้องออกแบบอย่างไร?

จทย์ข้อที่ 2 ของ PageJone:

    มี class วัว กับ class นม  classวัวควรส่ง Method เรียก class นม หรือ class นม ควรส่ง method เรียก class วัว?

    มี โจทย์คล้ายๆ กัน

    มี class หนังสือ กับ class ชั้นหนังสือ หนังสือควรจะบอกชั้นหนังสือให้จัดตัวเองเข้าชั้น หรือ ชั้นหนังสือควรบอกหนังสือให้มาที่ชั้นนี้

โจทย์ข้อ 3 ของ Booch:

    มีเตาให้ความร้อนกับห้อง  ในห้องมี Sensor ตรวจจับ อุณหภูมิ  และ ตรวจจับว่ามีคนอยู่หรือไม่ ถามว่าควรออกแบบความสัมพันธ์อย่างไร

    โจทย์พวกนี้ ให้ดีอย่าคิดคนเดียวนะครับ คิดกันหลายๆ คน รับรองทะเลาะกันวุ่นแน่ มันมีทางเลือกในการออกแบบอยู่หลายทาง ซึ่งยากที่จะบอกว่าแนวทางไหนดีกว่ากัน มันต้องให้คนที่เคยลองทำมาก่อน อธิบายให้ฟังครับ ถึงจะรู้ว่าอะไรไม่ดี นั่นแหละครับ Heuristics

 

คำถาม ถ้าออกแบบ Class ผิดจะทำให้ Project ล้มไปเลยหรือไม่?

    มีคน email มาถามผมหลายข้อ ถ้าเห็นว่าตรงกับส่วนไหน ผมจะตอบให้ครับ อย่างคำถามข้างบนนี้ ก็เป็นคำถามที่น่าสนใจครับ ใครลองออกแบบ Software แบบ OO คงจะกลัวครับว่า กำหนด Class ผิดจะส่งผลร้ายแรง ผมคงอธิบายอย่างนี้ก็แล้วกัน

    ในเชิงของ Heuristics แล้ว เราจะเน้นที่สุดก็คือ Abstraction ครับ คือการนิยามให้ถูก หลักการของการทำ Abstraction นั้นคือ มันต้องเก็บรายละเอียดที่เกี่ยวข้องกับมันมาทั้งหมด ไม่ให้หลุดรอดไปที่อื่น ส่วนที่ไม่เกี่ยวข้องกับตัวมันจะต้องไปอยู่ข้างนอก เมื่อทำเช่นนี้จะทำให้ class แต่ละตัวอิสระต่อกัน ไม่เกิดสภาวะที่เรียกว่า God Class เมื่อมันอิสระต่อกันแล้ว ผลกระทบเมื่อออกแบบผิดพลาดจะน้อย ดังนั้นถึงจะออกแบบไม่ค่อยถูก แต่ถ้ายึดหลักนี้ ถ้ามีการแก้ไขมันจะไม่กระทบมากนักครับ

    แต่มันดูเหมือนง่ายนะครับ ที่ทำให้ class แต่ละ class อิสระต่อกัน ในทางปฏิบัติแล้ว มันไม่ง่ายครับ ต้องเรียนรู้มาก ผมเลยขอแนะนำหนังสือให้อ่านเพิ่มเติมครับ ท้ายบทครับ

 

หัวใจข้อที่ 2 ของ การออกแบบ เลข 7

    นอกจาก การทำให้ class อิสระต่อกันแล้ว ซึ่งถือว่าเป็นหัวใจหนึ่งของการออกแบบแล้ว ยังมีหัวใจข้อที่ 2 ครับที่น่าสนใจ นั้นคือ 7 เลขมหัศจรรย์ นั่นเอง

    เลข 7 มาในที่นี้มาจากไหน มันมาจากงานวิจัยครับ ที่เชื่อกันว่ามนุษย์เรานี้สามารถจดจำหรือเข้าใจสิ่งต่างๆ ในเวลาเดียวกันได้ 5 - 9 อย่าง หรือ 7 +-2 นั่นเอง เนื่องด้วยสมองมนุษย์มีข้อจำกัดเพียงเท่านี้ แต่สิ่งที่ชดเชยมา คือความสามารถในการทำ Abstraction ครับ นั่นคือแทนที่เราจะมอง ล้อ พวงมาลัย เกียร์ เบาะ และอื่นๆ แต่มนุษย์สามารถรวบยอดความคิดออกมาเป็นสิ่งเดียวคือ รถ ได้ ทำให้ใช้หน่วยความจำเพียงหนึ่งหน่วย ทำให้สามารถลดความซับซ้อนของมนุษย์ได้ ดังนั้น หลักการการออกแบบ Class หรือ ตัวแปร ต่างๆ นั้น นิยม ไม่ให้เกิน 7 อย่าง ถ้าเกินต้องสร้าง Abstraction ใหม่ แนวคิดนี้จึงเป็นที่มาของ Refactoring ครับ

Refactoring

    ในบทความที่แล้วที่กล่าวถึง Spiral Model (Iteration / Increment) ทำนองว่าถ้ามีการวนรอบใหม่ ถ้าผิดทาง เราต้องรื้อโปรแกรมใหม่หมด ซึ่งที่จริงแล้ว เรามีวิธี Refactoring มาใช่ ผู้คิดค้น Refactoring คือ Kent Beck เจ้าเก่าผู้คิดค้น Extreme Programming นั่นเอง

    หลักการทำ Refactoring ก็ใช้หลักการเลข 7 นั่นเอง กล่าวคือ เมื่อเราเขียนโปรแกรมเสร็จแล้ว ทำงานได้แล้ว เราไม่ยอมจบนะครับ ถึงแม้ว่ามันจะทำงานได้ แต่เชื่อว่าการเขียนมันคงอีรุงตุงนังเพราะแก้หลายรอบ ดังนั้นเมื่อเอามาอ่านใหม่วันหลัง คงจะมึนน่าดู ดังนั้น จึงมีวิธีการที่เรียกว่า Refactoring เพื่อทำการปรับปรุงให้ Code ดูดีขึ้น อ่านง่ายขึ้น ตรงไหนที่ซับซ้อนก่อนไป ก็ทำการปรับปรุง ชื่อตัวแปรหรือฟังก์ชันก็ต้องปรับให้อ่านง่าย โดยการกระทำทั้งหมดนั้น ต้องไม่กระทบถึง Interface ของ Function ต่างๆ ของโปรแกรม และอยู่บนพื้นฐานของเลข 7 ครับ

    ถ้าสนใจเรื่อง Refactoring หาอ่านได้จาก

    Refactoring :Improving the Design of Existing Code  - Martin Fowler
 

 

แนะนำหนังสือ OO เชิง Heuristics

    ภาษาไทยไม่มีครับ มีแต่หนังสือภาษาฝรั่ง

    หนังสือ 2 เล่มแรก ถือได้ว่าเป็นหนังสือ Classic ในวงการ ส่วนเล่มที่ 3 ถึงไม่ว่าจะไม่ดัง แต่ผมว่ามันก็มีเนื้อหาที่น่าสนใจครับ

 

Hit Counter