Training

Object-Oriented Programming (OOP) คืออะไรกันแน่?

06 Jun 2012

ทุกวันนี้เราอยู่ในยุคของการเขียนโปรแกรมแบบ Object-Oriented ภาษาไหนๆก็เป็นภาษาแบบออบเจกต์แทบทั้งนั้น ไม่ว่าจะเป็น Java, Ruby, Python, PHP, JavaScript หรืออื่นๆล้วนแล้วแต่เขียนเป็นออบเจกต์ได้ทั้งนั้น (บางภาษาอาจเป็นได้มากกว่า Object-Oriented) แต่แล้วการเขียนโปรแกรมแบบ Object-Oriented มันคืออะไรกันแน่? หลายคนยังคงหาคำตอบไม่ได้ อ่านหนังสือก็แล้ว เรียนในห้องมาก็แล้ว หรือแม้แต่ทำงานเขียนโปรแกรมอยู่แล้ว ก็ยังไม่รู้ว่าจริงๆแล้วมันคืออะไร เราได้อะไรจากมัน แล้วที่เราเขียนอยู่นี้หล่ะ ใช่เขียนเป็นออบเจกต์รึเปล่า!!! ในบทความนี้ผมจะอธิบายให้คุณเห็นว่าแท้จริงแล้วมันคืออะไร มันอาจไม่ใช่ที่เราเคยเข้าใจกันมาหรือมันอาจง่ายกว่าที่เราคิดไว้ก็ได้

Spaghetti-Oriented Programming!!!

ก่อนเราจะไปหาคำตอบกันว่า OOP คืออะไร ผมอยากจะเริ่มต้นที่การเขียนแบบที่ไม่ใช่ OOP ก่อน ถึงแม้ว่าเราจะใช้ภาษาออบเจกต์อย่างเช่น Java เขียนโปรแกรม แต่นั่นก็ไม่ได้การันตีว่าเราได้เขียนมันเป็นออบเจกต์ บ่อยครั้งที่เราเขียนโปรแกรมโดยสนใจแต่ผลลัพธ์เป็นหลัก เราจะเขียนโค้ดอะไรก็ตามที่ทำให้มันรันได้และออกมาเป็นผลลัพธ์ที่ต้องการ สิ่งนี้มักเกิดขึ้นบ่อยโดยเฉพาะถ้าเราใช้ Tool/IDE ดีๆอาทิเช่น Netbeans, Visual Studio เป็นต้น IDE เหล่านี้มักช่วยให้เราทำงานได้ง่ายเสียเหลือเกิน มันสร้างโค้ดให้เราบางส่วน เราเติมเองเพิ่มบางส่วน มันก็ออกมาเป็นโปรแกรมใช้งานได้แล้ว เอาหล่ะผมจะลองยกตัวอย่างขั้นตอนการเขียนแบบที่ว่านี้ให้ดูนะครับดังนี้:

  • เราเริ่มต้นที่การออกแบบ User Interface (UI) ก่อน โดยใช้ Visual Disigner ฟีเจอร์ของ IDE รูปที่ 1 แสดงตัวอย่างของ Netbeans IDE เราลากวาง Controls/Components ต่างๆตามแต่ที่เราต้องการ เดี๋ยว IDE มันก็สร้างโค้ดให้เราเอง
    รูปที่ 1: Netbeans Visual Designer
  • จากนั้นเราก็ให้ IDE มันสร้างเมธอดสำหรับ Event-Handling ให้ เราเพียงดับเบิ้ลคลิกที่ปุ่มเช่น ปุ่ม "Save" มันก็สร้างเมธอดให้เราไว้สำหรับเขียนโค้ดเพื่อจัดการกับเหตุการณ์ที่ปุ่มโดนกดดังแสดงในรูปที่ 2
    รูปที่ 2: Event-Handling Method
  • ถึงตรงนี้เราก็แค่เติมโค้ดอะไรก็ได้ลงไปให้มันใช้งานได้ก็จบ

แล้วจริงๆเราได้อะไรมา? คำตอบก็คือเราได้โปรแกรมแบบ Spaghetti-oriented มา เพราะเราผสมรวมมันทุกอย่างลงไปในไฟล์ๆเดียวดังแสดงในรูปที่ 3 เห็นไหมครับว่า ไม่ว่าจะเป็นโค้ดที่สร้าง UI ขึ้นมาก็อยู่ที่ไฟล์นี้, โค้ดที่ใช้จัดการกับการกดปุ่มก็ไฟล์นี้, โค้ดที่ใช้ติดต่อฐานข้อมูลก็ไฟล์นี้, . . . มันผสมปนเปยุ่งเหยิงอยู่ในไฟล์เดียวกันหรือแย่กว่านั้นคือมีข้ามไฟล์ให้มันสะเปะสะปะเข้าไปอีก แล้วถ้าเราจะแก้ไขมันในอนาคตจะทำอย่างไร คงจะปวดหัวน่าดู และถ้าเราจะ Re-use มันหล่ะจะได้มั๊ย เช่นว่าปุ่มปิดมันน่าจะมีในทุกๆหน้าจอ UI เราจะ Re-use มันยังไง? ก๊อปปี้แปะมันเลยละกันถ้างั้น ถ้าคุณทำเช่นนั้นคุณกำลังใช้แนวคิดแบบ Ctrl-c และ Ctrl-v Oriented อยู่ :p ทั้งหมดนี้แน่นอนว่าไม่ใช่การเขียนแบบ OOP เลยแม้ว่าเราจะใช้ภาษาออบเจกต์

รูปที่ 3: Spaghetti-Code

ตกลง OOP คืออะไร อยากรู้แล้ว

แล้วตกลง OOP คืออะไรกันแน่? บางคนก็ว่ามันคือการเขียนโปรแกรมเชิงวัตถุ ก็แน่หล่ะก็นี่คือคำแปลตรงตามตัวเลยนิครับ บ้างก็ว่ามันคือ Encapsulation, Inheritance, Polymorphism . . . เออ . . .อันนี้ยิ่งไปกันใหญ่ ถามว่าถูกมั๊ย มันก็ไม่ผิดอะไร เพราะเรียน OOP ทีไรก็มีชื่อเท่ๆเหล่านี้เสมอ แต่แล้วเจ้าชื่อเรียกเท่ๆยาวๆเหล่านั้นมันคืออะไร? เราได้อะไรจากมัน? ตอบได้มั๊ยครับ? ลืมมันไปก่อนเถอะครับ มันเป็นแค่ฟีเจอร์ทางภาษาเท่านั้น เพราะถึงแม้คุณจะเขียนโค้ด Abstract, Polymorphism หรืออื่นๆ คุณก็ไม่ได้ประโยชน์อะไรจากมันถ้าคุณยังไม่เข้าใจหัวใจหลัก (BASIC PRINCIPLE) ของ OOP ยกตัวอย่างเช่น คุณใส่ฟีเจอร์ทางภาษาเข้าไป แต่โค้ดมันยังเป็นสปาเก็ตตี้อยู่ก็เท่านั้น ถูกมั๊ยครับ เจ้าฟีเจอร์ทางภาษามันแค่ช่วยเสริมหัวใจหลักให้ดียิ่งขึ้น

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

รูปที่ 4: OOP Application

แต่ละโมดูลจะมีหน้าที่หลักหรือบทบาท (Role) หลักเพียงอย่างเดียวเท่านั้น เช่น:

  • โมดูล GUI จะมีแต่โค้ดที่เกี่ยวข้องกับการแสดงผล (Presentation Logic) เท่านั้น จะไม่มีอย่างอื่นเลย แต่แล้วข้อมูลที่จะนำมาแสดงผลจะมาจากไหนหล่ะ ผมก็ให้มันเป็นหน้าที่ของโมดูล Service
  • โมดูล Service มีหน้าที่ในการประมวลผล มันประกอบไปด้วย Business Logic ต่างๆ เช่นการคำนวณราคา, การคิดภาษี เป็นต้น เพื่อเอาผลลัพธ์ไปใช้ในโมดูล GUI แต่การจะประมวลผลได้นั้นมันต้องมีข้อมูลดิบป้อนเข้ามา ซึ่งข้อมูลดิบมักถูกเก็บอยู่ในระบบฐานข้อมูล อย่างไรก็ตามนี่ไม่ใช่หน้าที่หรือบทบาทของโมดูล Service แต่เป็นหน้าที่ของโมดูลต่อไปโมดูล DAO
  • โมดูล DAO (Data Access Object) ชื่อก็บอกอยู่แล้วว่าเป็นโมดูลที่ใช้เข้าถึงข้อมูล มีหน้าที่ในการนำข้อมูลเข้าออกจากระบบฐานข้อมูลหรือประกอบไปด้วยโค้ด Data Access Logic เท่านั้น ส่วนจะประมวลผลข้อมูลอย่างไรก็เป็นหน้าที่ของ Service
  • โมดูล Report คงเดาได้ไม่ยากว่า มีหน้าที่ออกรายงานอย่างเดียว ก็เผอิญว่าแอพพลิเคชันนี้มีการออกรายงานด้วย
  • สุดท้ายโมดูล Main มีหน้าที่ในการโหลดหรือประกอบร่างโมดูลต่างๆเข้าด้วยกันเพื่อให้ได้ออกมาเป็นแอพพลิเคชันที่ใช้งานได้

เห็นไหมครับว่าแต่ละส่วนไม่มีการก้าวก่ายงานกัน แล้วเราได้อะไรจากการออกแบบเช่นนี้? คำตอบคือเราสามารถเปลี่ยนแปลง, แก้ไข, เพิ่มเติมได้อย่างอิสระ ยกตัวอย่างเช่น

  • หากเรามีการเปลี่ยนแปลงระบบฐานข้อมูล เช่นจะเปลี่ยนโครงสร้างตารางหากใช้ Relational Database หรือแม้แต่จะเปลี่ยนจาก Relational ไปเป็น Object Database เราก็มั่นใจได้ว่าโค้ดที่ต้องเปลี่ยนแปลงอยู่ในโมดูล DAO เท่านั้น ก็การแสดงผลก็เหมือนเดิม, Business Logic ก็เหมือนเดิม, ออกรายงานก็อย่างเดิมจะไปแก้อย่างอื่นมันทำไม
  • หากเราอยากปรับปรุงหน้าตาการแสดงผล (GUI) ให้มันดูดีกว่าที่เป็นอยู่ เราก็แก้ไขที่โมดูล GUI เท่านั้น ก็ฐานข้อมูลมันอย่างเดิม, อย่างอื่นก็เหมือนเดิม จะแก้อย่างอื่นไปทำไม
  • เอาหล่ะวันนี้มันยังเป็น Desktop App (Window App) พรุ่งนี้จะทำให้มันเป็น Web App เราต้องรื้อทำใหม่หมดรึเปล่า? เปล่าเลย ก็ฐานข้อมูลมันก็ชุดเดิมไม่ใช่หรือ, Business Logic ก็ไม่ได้เปลี่ยนไป แค่อยากไปแสดงผลบนเว็บ ถ้างั้นก็เพิ่มโมดูลเว็บเข้าไปสิ อย่างอื่นที่เหลือก็ Re-use :)
  • วันนี้เราเขียนด้วย Java พรุ่งนี้แอพพลิคชันมันต้องทำงานร่วมกับแอพพลิเคชันอื่นที่ดันเขียนด้วย .Net เราจะทำอย่างไรดี? เราก็เพิ่มโมดูล Web Service เข้าไปสิ เพราะเทคโนโลยี Web Services มันเกิดมาเพื่อการนี้คือทำให้ต่างภาษาต่างแพลทฟอร์มทำงานร่วมกันได้

พอจะเห็นภาพหรือยังครับว่าถ้าเราแบ่งแอพพลิเคชันได้ดีคือแบ่งออกเป็นสัดเป็นส่วน เราก็สามารถเปลี่ยนแปลง, แก้ไข, เพิ่มเติมได้ง่ายขึ้น ได้ประโยชน์แม้ไม่มีโค้ดไฮไซอย่าง Abstract, Polymorphism, Overriding ใดๆทั้งสิ้น แค่นี้แหละครับหัวใจหลักของ OOP ส่วนจะแบ่งอย่างไรให้มันดีหรือเหมาะสม อันนี้ก็ต้องไปว่ากันที่เรื่องของการออกแบบกันต่อไป

กลับมาต่อกันที่หลักการของ OOP กัน ในทางปฏิบัติแล้วแต่ละโมดูลก็คือออบเจกต์นั่นเอง ดังนั้นการเขียนโปรแกรมแบบ Object-Oriented ก็คือ การแบ่งโปรแกรมหรือแอพพลิเคชันออกเป็นออบเจกต์ย่อยๆ แต่ละออบเจกต์ทำหน้าที่หลักเพียงอย่างเดียวหรือมีเพียงบทบาทเดียว สุดท้ายทุกๆออบเจกต์ทำงานร่วมกันออกมาเป็นแอพพลิเคชันที่สมบูรณ์ ในความเป็นจริงแต่ละบทบาทอาจประกอบไปด้วยออบเจกต์มากกว่าหนึ่งตัวก็ได้เช่น บทบาทการแสดงผล (GUI) อาจต้องใช้ออบเจกต์มากกว่าหนึ่งตัว เพราะหนึ่งออบเจกต์ก็หนึ่งหน้าจอ เป็นต้น ดังนั้นออบเจกต์ต่างๆที่อยู่ในบทบาทเดียวกัน ก็น่าจะถูกจัดให้อยู่ในกลุ่มเดียวกันดังแสดงในรูปที่ 5 กลุ่มของออบเจกต์ก็คือ Package หรือ Namespace หรือ Library หรือ Component สุดแท้แล้วแต่จะเรียกนั่นเอง เพราะฉะนั้นหากผมอยากจะเปลี่ยนหน้าการแสดงผลใหม่ ผมก็โละมันทั้ง GUI Package ได้เลย จะเห็นได้ว่าหัวใจหลักของ OOP คือการจัดแบ่งโค้ดอย่างมีระเบียบ พูดง่ายๆคืออย่าเขียนเป็นสปาเก็ตตี้ก็แล้วกัน

รูปที่ 5: Packages

แล้วที่เราร่ำเรียนกันมาเกี่ยวกับ Inheritance, Polymorphism ทั้งหลายทั้งปวงมันคืออะไร นั่นเป็นฟีเจอร์ทางภาษาของ Object-Oriented ครับ ในเมื่อแอพพลิเคชันถูกแบ่งออกเป็นออบเจกต์ย่อยๆมากมาย (ในระบบใหญ่ๆมีได้เป็นหลักร้อยหลักพัน) และมันจะต้องทำงานร่วมกัน ฟีเจอร์ทางภาษาเหล่านั้นจะทำให้มันทำงานร่วมกันได้ดียิ่งขึ้น เพราะฉะนั้นจุดเริ่มต้นคือต้องแบ่งออบเจกต์ให้ดีเสียก่อน แล้วจึงใส่ฟีเจอร์ทางภาษาเข้าไป

What's Next?

น่าจะพอเห็นภาพแล้วนะครับว่าแนวคิดแบบ OOP เป็นอย่างไร ต่อจากนี้ไปคุณก็ไปศึกษาว่าในภาษานั้นๆมีวิธีการสร้างออบเจกต์อย่างไรใช้ Syntax แบบไหน แล้วจึงศึกษาฟีเจอร์ทางภาษา Object-Oriented ที่ทำให้ออบเจกต์ทำงานร่วมกันอย่างมีประสิทธิภาพอาทิเช่น Polymorphism เป็นต้น ในโอกาสถัดไปผมจะเขียนถึงออบเจกต์ใน Java หน้าตาเป็นอย่างไร? Hello World แบบ OOP มันควรเป็นเช่นไรกัน? และชื่อเท่ๆอย่าง Encapsulation, Information Hiding, และ Polymorphism แท้จริงแล้วมันคืออะไรกันแน่ ขอให้สนุกกับการเขียนโปรแกรมแบบ OOP นะครับ :)

Update - บทที่ความต่อเนื่อง:

Books By Me

JavaScript Programming Guide book cover

JavaScript Programming Guide
Thai language
Kontentblue Publishing

About This Site

I use this site to share my knowledge in form of articles. I also use it as an experimental space, trying and testing things. If you have any problems viewing this site, please tell me.

→ More about me

→ Contact me

→ Me on facebook

Creative Commons Attribution License

creative commons logo

This license lets you distribute, remix, tweak my articles, even commercially, as long as you credit me for the original creation.

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