6/07/2552

การเขียนโปรแกรมแบบ OOP

ความหมายของ OOP
OOP (ย่อจาก Object Oriented Programming การเขียนโปรแกรมแบบวัตถุวิธี) เป็นรูปแบบ (Paradigm) หรือแนวคิดอย่างหนึ่ง อันมีจุดมุ่งหมายเพื่อการสร้างซอฟท์แวร์ คำว่า Object ในที่นี้หมายถึงวัตถุ หรือสิ่งของที่จับต้องได้ ไม่ได้หมายถึงวัตถุประสงค์ จุดมุ่งหมาย หรือกรรม (ผู้ถูกกระทำ อย่างประธาน กริยา และกรรม ในรูปประโยค)
มีผู้ตีความว่าแนวคิดนี้คือ “การเขียนโปรแกรมโดยมุ่งที่เป้าหมาย (มิได้เน้นที่กระบวนการ)” ผู้เขียนเห็นว่าการตีความดังกล่าวไม่สู้จะถูกต้อง เพราะการเขียนโปรแกรมตามลัทธินี้มีการสร้าง object ขึ้นจริง แม้จะเป็น object อันจับต้องไม่ได้ เพราะอยู่ในสภาพซอฟท์แวร์ แต่ก็มีเจตนาจะเลียนแบบ object ที่เป็นรูปธรรมอย่างเต็มที่
เรื่อง OOP เป็นเรื่องของ object ดังนั้นสิ่งแรกที่ต้องรู้คือความหมายของคำว่า object นิยามของ object คือ “หน่วยหนึ่งของโปรแกรมซึ่งมีหน้าที่การทำงานอันเฉพาะเจาะจง และถูกกำหนดปฏิสัมพันธ์กับโปรแกรมหน่วยอื่นๆ ไว้อย่างแน่ชัด” ในภาษา C# เราสร้าง object จากคลาส

คลาสกับ object
คลาสกับ object เป็นสองสิ่งที่มีความเกี่ยวข้องกันโดยตรง คลาสคือโค้ดที่เราเขียนขึ้นเพื่อทำหน้าที่เป็นพิมพ์เขียวของ object การสร้าง object จากคลาสเรียกว่าการทำ instantiation การสร้าง object จากคลาส เทียบได้กับการทำขนมครกสิงคโปร์ เตาขนมจะมีหลุมหลายหลุม แต่ละหลุมมีลวดลายไม่เหมือนกัน ขนมครกที่ได้จากแต่ละหลุมจึงมีรูปร่างต่างๆ กัน คลาสคือหลุมหนึ่งหลุม ขนมครกที่ได้คือ instance ของคลาส หรือ object
เราเรียก object หนึ่ง object ว่าหนึ่ง instance เราสามารถสร้าง object ได้หลายๆ instance จากคลาสเพียงคลาสเดียว จากตัวอย่างขนมครกสิงคโปร์ ในวันหนึ่งๆ แม่ค้าจะทำขนมครกได้เป็นจำนวนมากจากหลุมแต่ละหลุม ส่วนในภาษา C# หากเราสร้างคลาสหนึ่งคลาส ยกตัวอย่างเช่น เป็นคลาสเพื่อนิยาม node หลังจากนั้นเราอาจเขียนโปรแกรมสร้าง binary tree ซึ่งขณะทำงานมันอาจจะสร้าง object จากคลาส node ได้หลายล้าน instance ภายในหนึ่งวินาที

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

object กับ type
เรื่องของ type เป็นเรื่องสำคัญในวิชา OOP ในหนังสือนี้ท่านจึงจะพบคำว่า type อยู่เสมอ จึงมีความจำเป็นที่ท่านจะต้องทำความเข้าใจความหมายของคำว่า type ให้ตรงกับความหมายใน OOP และภาษา C# ก่อน
ในภาษาที่ไม่ใช่ภาษา OOP อย่างภาษา C มี type ต่างๆ เตรียมไว้ล่วงหน้า เช่น int (จำนวนเต็ม) float (จำนวนมีทศนิยม) char (ตัวอักษร) เป็นต้น type เหล่านี้คือชนิดของข้อมูล ยกตัวอย่างเช่นเมื่อเราเขียนโค้ดว่า
int foo;
ซึ่งทำหน้าที่นิยามตัวแปรชนิดจำนวนเต็ม compiler (ตัวแปลภาษา) จะรู้ทันทีว่าควรทำเช่นใดกับตัวแปรชนิดนี้ เพราะ int เป็น type ที่ถูกกำหนดไว้ล่วงหน้าแล้ว (ภายในตัว compiler ภาษา C) เรียกว่า build-in type (หรือ primitive type หรือ abstract data type ก็ว่า)
ภาษา C รับรู้ type อยู่จำนวนหนึ่ง หากเราพบว่า type ที่มีมาให้ไม่สามารถตอบสนองต่อความต้องการของเราได้ เราสามารถนิยาม type ขึ้นเองได้ เรียกว่า user defined data type (ต่อไปจะเรียกย่อว่า UDT) โดยใช้ structure
ยกตัวอย่างการสร้าง structure ชื่อ record เพื่อเก็บข้อมูลนักเรียนเป็นดังนี้
public struct record
{
public char cname;
public char sname;
public char exam;
public char grade;
}

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


การนิยามคลาสใหม่ทำให้เราได้ type ใหม่ object ที่ถูกสร้างจากคลาสต่างกันจะมี type แตกต่างกัน ยกตัวอย่างเช่น object ที่สร้างจากคลาส Star จะมี type เป็น Star ขณะที่ object ที่ถูกสร้างจากคลาส Hexagon จะมี type เป็น Hexagon

ภาษา C# สนับสนุนการสร้าง type ใหม่อย่างพิสดาร เมื่อนิยามแล้ว UDT กับ build-in type จะมีศักดิ์ศรีเสมอกัน (คือ compiler จะปฏิบัติต่อ type ที่เราสร้างในลักษณะ first class เช่นเดียวกับ build-in type).NET Framework library เองก็เป็นแหล่งรวม type หลายพัน type ที่เราสามารถนำมาประกอบเป็น type ใหม่ที่มีการทำงานซับซ้อนได้อย่างสะดวกรวดเร็ว
การเขียนโปรแกรมแบบ OOP เราจะใช้เวลาส่วนมากไปกับการออกแบบและนิยาม type ขึ้นใหม่เพื่อนำไปใช้สร้าง object ต่างๆ เมื่อนำ object ทั้งหมดมาประกอบเข้าด้วยกัน เพื่อให้ทำงานร่วมกัน จะทำให้โปรแกรมของเราสร้างผลลัพธ์ได้ตามความประสงค์

การใช้งาน object
การใช้งาน object ต้องทำได้ง่าย เราอาจมองว่า object เป็น “กล่องดำ” ในทางวิทยาศาสตร์เราจะเรียกอุปกรณ์ที่เราสามารถนำมาใช้ประโยชน์ได้ โดยไม่จำเป็นต้องรู้รายละเอียดการทำงานภายในของมันว่า กล่องดำ ยกตัวอย่างเช่นโทรศัพท์ เรานำมันมาใช้ประโยชน์เพื่อการสื่อสารได้ โดยไม่จำเป็นต้องรู้ว่ามันทำงานได้อย่างไร เช่นเดียวกัน ในภาษา C# เราสามารถนำ object มาใช้งานได้โดยไม่จำเป็นต้องรู้ว่ามันมี source code ภายในเป็นอย่างไร
เมื่อเราต้องกาเรียกให้ object ทำงานบางอย่างเราจะเรียก method ของมัน ยกตัวอย่างเช่นโทรศัพท์มี method คือการโทรฯ ออก การวางสาย การพักสาย การบันทึกเลขหมายฯ ในภาษา C# เราจะนิยาม method เหล่านี้โดยการเขียนโค้ดหนึ่งชุด คล้ายการนิยามฟังก์ชันในภาษา C
object จะผนวกกระบวนการ (method) และข้อมูล (information) ไว้ภายในตัวของมันเอง จากตัวอย่างโทรศัพท์เก็บเลขหมายที่เราบันทึกไว้ โดยเราไม่จำเป็นต้องรู้ว่ามันเก็บไว้ที่ไหนอย่างไร เรารู้เพียงวิธีดึงเลขหมายที่บันทึกไว้ออกมาใช้งานก็พอ ในภาษา C# object จะเก็บข้อมูลภายในไว้ใน field (คือตัวแปรท้องถิ่นของคลาส) โปรแกรมที่เรียกใช้ object ไม่จำเป็น (และไม่สามารถ) เข้าถึงหรือเปลี่ยนแปลงข้อมูลใน field ได้โดยตรง แต่สามารถเข้าถึงทางอ้อมได้ผ่านส่วนเชื่อมต่อที่เรียกว่า property
ภาษา C# สนับสนุนหลักการทุกรูปแบบในลัทธิ OOP โดยหลักการนี้ มีเรื่องหลัก 3 หัวข้อที่ท่านจำเป็นต้องเข้าใจ คือ• Encapsulation: การห่อหุ้มวิธีการและข้อมูลไว้ภายในหน่วยหนึ่งๆ• Inheritance: การสืบทอดคุณสมบัติ• Polymorphic: การแปรคุณสมบัติ
ผู้เขียนจะอธิบายหลักการแต่ละหัวข้อต่อไปในบทนี้

ความเป็นมาของ OOP
แนวคิด OOP ไม่ใช่ของใหม่ แต่มีมาพร้อมๆ กับการเริ่มต้นของวิทยาการคอมพิวเตอร์ ในปี ค.ศ. 1960 นักเขียนโปรแกรม คิดค้นภาษา Simula (อ่านว่าซิมูลา) สำหรับเครื่อง UNIVAC ซึ่งเป็นภาษาแรกที่มีคุณสมบัติในการทำ OOP และอีกสามปีต่อมา นักศึกษาที่สถาบัน MIT อีวาน ซัทเธอร์แลนด์ (Ivan Sutherland) สร้างซอฟท์แวร์ชื่อ Sketcpad เป็นโปรแกรมประยุกต์ทำหน้าที่ช่วยการออกแบบ (CAD) มันเป็นโปรแกรมแรกที่นำ “การปฏิสัมพันธ์กับผู้ใช้ด้วยภาพ” (Graphic User Interface หรือ GUI) มาใช้อย่างสมบูรณ์ และการออกแบบสร้างก็ทำโดยใช้หลักการ OOP อย่างเต็มรูปแบบ

การพัฒนาภาษา Simula สำหรับเครื่อง UNIVAC ในปี ค.ศ. 1960
ดูเหมือนว่าวิวัฒน์ของ OOP และ GUI จะเกี่ยวพันกันอยู่เสมอเพราะต่อมาในปี ค.ศ. 1970 เมื่อศูนย์วิจัยของซีร็อกซ์ ที่ พาโล-อัลโต ต้องการสร้างระบบปฏิบัติการแบบ GUI (ที่ต่อไปจะเป็นบรรพบุรุษของ Mac OS และ Microsoft Windows) ทีมนักวิจัยได้สร้างภาษาใหม่ชื่อ Smalltalk (สมอลทอล์ค) เพื่อให้เหมาะกับการเขียนโปรแกรมแบบ GUI ภาษานี้ได้รับอิทธิพลจากภาษา Simula อย่างมาก

ภาษา Smalltalk บนเครื่อง Alto ในปี ค.ศ. 1970
แนวคิด OOP เริ่มเบ่งบานเต็มที่ในช่วงกลางทศวรรษ 1980 เมื่อบริษัทแอปเปิลและบริษัทไมโครซอฟท์ต่างผลิตระบบปฏิบัติการที่เป็น GUI ออกสู่ท้องตลาด และมีภาษาแบบ OOP เกิดขึ้นใหม่จำนวนมาก เช่น ภาษา Objective C, Modula-2 และ Eiffel แนวคิด OOP ขึ้นถึงจุดสุดยอดใน ค.ศ. 1983 เมื่อ Bjarne Stroustrup นักวิทยาศาสตร์แห่งห้องทดลอง เบลล์ ได้สร้างภาษา C++ ซึ่ง Bjarne ให้นิยามว่าเป็น “ภาษาซีที่มีคลาส”

1 ความคิดเห็น: