การพัฒนาระบบด้วยแนวคิดเชิงวัตถุตามแพลตฟอร์ม Microsoft.NET
การพัฒนาระบบด้วยแนวคิดเชิงวัตถุตามแพลตฟอร์ม Microsoft.NET
1. การออกแบบโปรแกรมเชิงวัตถุ
เนื่องจากปัจจุบันแพลตฟอร์ม Microsoft.NET
ได้รับความนิยมอย่างสูงในการนำมาสร้างโปรแกรมประยุกต์เนื่องจากผู้เขียนโปรแกรมสามารถเลือกเขียนโปรแกรมได้หลากหลายภาษาเช่นภาษา
VB.NET ภาษา C# ภาษา JavaScript.NET
และอื่นๆ เพื่อสร้างโปรแกรมสำเร็จรูปที่สามารถนำไปใช้งานข้ามภาษาได้
(Cross-Language) ซึ่งจะทำให้ทีมงานพัฒนาระบบที่หลากหลายสามารถสร้างสรรค์ผลงานได้ด้วยภาษาโปรแกรมที่ตนเองถนัดและนำมารวมเข้าด้วยกันให้กลายเป็นระบบขนาดใหญ่ได้
อย่างไรก็ตามไม่ว่าจะใช้ภาษาโปรแกรมภาษาใดก็ตาม
โปรแกรมที่พัฒนาขึ้นจาก Microsoft.NET จะยังคงทำงานร่วมกันได้เสมอเนื่องจากทำงานอยู่บนตัวรันไทม์ที่เรียกว่า
CLR (Common-Language Runtime) และไม่ว่าผู้เขียนโปรแกรมจะใช้ภาษาใดก็ตามที่
.NET จัดเตรียมไว้ให้
ผู้เขียนจะต้องมีความรู้เกี่ยวกับการโปรแกรมเชิงวัตถุด้วยเสมอ
เนื่องจากภาษาทุกภาษาใน .NET จะมีคุณลักษณะเชิงวัตถุเป็นพื้นฐานองค์ประกอบในการสร้างโปรแกรม
การออกแบบโปรแกรมเชิงวัตถุเป็นพื้นฐานของการสร้างระบบโปรแกรมประยุกต์ขนาดใหญ่ให้มีความยืดหยุ่นสูง
ระบบสารสนเทศที่เกิดขึ้นจะมีลักษณะแบบองค์ประกอบโดยจะประกอบขึ้นจากส่วนประกอบย่อยเช่นเดียวกับการสร้างผลิตภัณฑ์ในทางอุตสาหกรรม
ดังนั้นแม้ว่าโปรแกรมจะมีขนาดใหญ่และซับซ้อนแต่หากเป็นโปรแกรมเชิงวัตถุแล้วก็จะทำให้เราสามารถปรับเปลี่ยนแก้ไขคุณสมบัติของระบบได้โดยเลือกต่อเติมหรือถอดถอนองค์ประกอบย่อยๆในโปรแกรมได้โดยแทบไม่มีผลกระทบกับโปรแกรมส่วนอื่น
ซึ่งก็คือทำให้ระบบที่เกิดขึ้นง่ายต่อการบำรุงรักษาและปรับเปลี่ยนให้ตรงกับความต้องการของผู้ใช้ที่อาจจะแปรเปลี่ยนไปในอนาคตได้
2. องค์ประกอบของวัตถุ
การออกแบบโปรแกรมเชิงวัตถุ
ให้ผู้ออกแบบสมมุติวัตถุขึ้นเองได้โดยเลียนแบบเอาจากสิ่งที่จับต้องได้และที่จับต้องไม่ได้แต่เป็นสิ่งของเรื่องราวที่อยู่ในระบบที่กำลังออกแบบ
ตัวอย่างของวัตถุจึงอาจจะเป็นได้ทั้งวัตถุที่เลียนแบบมาจากสิ่ที่จับต้องได้เช่น คน
สถานที่ รถยนต์ สินค้า หรือเลียนแบบมาจากวัตถุที่จับต้องไม่ได้เช่น การพยากรณ์
การคำนวณ การตัดสินใจ การดำเนินงาน เป็นต้น ทั้งนี้ผู้ออกแบบวัตถุจะต้องพิจารณาเอาเฉพาะสิ่งที่มีแก่นสารและเป็นไปเพื่อวัตถุประสงค์การใช้งานของผู้ใช้เท่านั้น
หากพิจารณาแล้วว่าวัตถุบางตัวไม่เกี่ยวข้องกับระบบที่ผู้ใช้ต้องการใช้งาน
วัตถุเหล่านั้นจะถูกโยนทิ้งไปและไม่นำมาใส่ไว้ในโครงสร้างโปรแกรม
วัตถุในความหมายของโปรแกรมเชิงวัตถุประกอบด้วย 2
ส่วนคือ ส่วนข้อมูล (Data) และ
ส่วนการดำเนินการ (Operation)
โดยส่วนข้อมูลเปรียบเสมือนกับสมองและความจำ
ซึ่งจะจดจำสถานะการทำงานที่เกิดขึ้นในขณะที่มันกำลังทำงานอยู่
ส่วนการดำเนินการเปรียบเสมือนกับปุ่มกดที่มีไว้ให้ผู้ใช้เลือกกดปุ่มสั่งงานว่าจะให้วัตถุทำอะไรให้บ้าง
ตัวอย่างเช่น หากเรากำลังออกแบบระบบประเมินผลงานพนักงาน
วัตถุที่เราอาจจะสมมุติขึ้นมาเช่น พนักงาน ผลการทำงาน และ ผลตอบแทน
โดยพนักงานอาจจะมีส่วนข้อมูลคือ ชื่อ นามสกุล รหัสประจำตัว และข้อมูลบุคคลอื่นๆ
ส่วนส่วนที่เป็นการดำเนินการของพนักงานอาจจะได้แก่ มาทำงาน เลิกงาน ลาป่วย ลากิจ
ลาพักร้อน รับงาน ส่งงาน และอื่นๆ เป็นต้น
จากภาพข้างต้นจะเห็นว่าหากเราไม่จำกัดขอบเขตโดเมนให้กับวัตถุชนิดใดชนิดหนึ่ง
วัตถุหนึ่งชนิดจะสามารถมีข้อมูลและการดำเนินการได้ไม่จำกัด
แต่ในทางปฏิบัติแล้วเราจำเป็นต้องออกแบบวัตถุโดยยึดตามความต้องการของผู้ใช้ระบบและวัตถุจะมีข้อมูลและการดำเนินการที่เป็นไปเพื่อวัตถุประสงค์ของระบบนั้นเท่านั้น
เช่นในภาพข้างต้นจะเห็นว่าวัตถุที่เป็นบุคคลเหมือนกันแต่เมื่อไปอยู่ในโดเมนต่างกันจะมีส่วนข้อมูลและการดำเนินการแตกต่างกันไปตามการใช้งานของผู้ใช้ในระบบนั้น
3. การสร้างคลาสเพื่อใช้เป็นแม่แบบของวัตถุ
การเขียนโปรแกรมเชิงวัตถุจะเริ่มจากการสร้างคลาส
(Class) ซึ่งคลาสจะทำหน้าที่เป็นประเภทหรือแม่แบบให้กับวัตถุ
ดังนั้นเมื่อผู้ออกแบบระบบพิจารณาแล้วว่าในระบบควรจะมีวัตถุชนิดใดบ้างก็จะนำมาเขียนเป็นคลาสโปรแกรม
โดยในคลาสจะจำลองส่วนข้อมูลและส่วนดำเนินงานไว้ในรูปแบบตัวแปรและฟังก์ชัน
เราเรียกตัวแปรที่ใช้เก็บข้อมูลประจำตัวของวัตถุนี้ว่าตัวแปรอินสแตนซ์ (Instance
Variable) หรือตัวแปรสมาชิก (Member Variable) และเรียกฟังก์ชันที่วัตถุใช้ดำเนินงานว่าเมธอด (Method) หรือฟังก์ชันสมาชิก (Member Function)
ตัวอย่างโปรแกรมต่อไปนี้แสดงการสร้างคลาสโดยใช้ภาษา
C# เพื่อจำลองวัตถุประเภทพนักงาน
ซอร์สโค้ด 1 ตัวอย่างการสร้างคลาสในภาษา
C#
class Employee
public String firstName;
public String surname;
public String code;
public String status;
public void checkIn()
{
status = "working";
}
public void checkOut()
{
status = "leave";
}
}
คลาสที่ถูกสร้างขึ้นจะนำมาใช้ประโยชน์สองอย่างคือ
นำมาใช้เป็นชนิดของตัวแปรสำหรับอ้างอิงวัตถุ หรือนำมาใช้สร้างชิ้นวัตถุ โดยคลาสหนึ่งคลาสสามารถนำมาสร้างวัตถุขึ้นได้หลายชิ้น
การนำคลาสมาสร้างเป็นวัตถุปกติจะใช้คำสั่ง new และตามด้วยชื่อคลาส
เช่นหากเรามีคลาส Employee เหมือนกับในตัวอย่างข้างต้น
เราสามารถนำมาสร้างเป็นวัตถุได้ดังนี้
ซอร์สโค้ด 2 ตัวอย่างการสร้างวัตถุด้วยภาษา
C#
Employee emp1;
emp1 = new Employee();
Employee emp2 = new Employee();
ตัวอย่างข้างต้นเป็นการเขียนโปรแกรมโดยใช้คำสั่ง
new เพื่อสร้างวัตถุ Employee ขึ้นมา 2 ชิ้น สังเกตได้จากมีการใช้คำสั่ง new ปรากฏให้เห็น 2
จุดคือที่บรรทัดที่ 2 และที่บรรทัดที่ 3
ในทางปฏิบัติการใช้คำสั่ง new สร้างวัตถุจะเป็นการจัดสรรหน่วยความจำขึ้นเพื่อใช้สำหรับเก็บข้อมูลให้กับวัตถุแต่ละตัว
หน่วยความจำที่ใช้วางวัตถุเราเรียกว่าหน่วยความจำฮีป (Heap Memory) เช่นในตัวอย่างนี้ เมื่อทำงานโปรแกรมจนจบ 3 บรรทัด
จะได้วัตถุ Employee 2 ชิ้นอยู่ในหน่วยความจำฮีปดังนี้
จะสังเกตเห็นว่าวัตถุทุกตัวที่ถูกสร้างขึ้นด้วยคำสั่ง
new จะอาศัยอยู่ในหน่วยความจำฮีปเสมอ
แต่การเข้าถึงวัตถุเหล่านี้จะต้องสั่งงานผ่านทางตัวแปรอ้างอิง (Reference
Variable) เช่นในภาพข้างต้นนี้เรามีตัวแปร emp1 และ emp2 เป็นตัวแปรอ้างอิง วัตถุที่ไม่มีตัวแปรอ้างอิงแม้แต่ตัวเดียว
จะเป็นวัตถุที่ไม่สามารถเข้าถึงและสิ้นเปลืองหน่วยความจำฮีปไปโดยเปล่าประโยชน์
ซึ่งวัตถุพวกนั้นเราเรียกว่าขยะ (Garbage) และหากปล่อยทิ้งไว้สักครู่ระบบจัดเก็บขยะ
(Garbage Collection) ก็จะมาทำลายวัตถุและนำหน่วยความจำฮีปกลับคืนมาใช้งานดังเดิม
เราสามารถนำข้อมูลไปเก็บไว้ในวัตถุแต่ละชิ้นได้
โดยอาศัยการเขียนโปรแกรมสั่งงานผ่านทางตัวแปรอ้างอิง เช่นหากเราต้องการให้วัตถุ emp1
ในภาพข้างต้นเก็บชื่อ “Somchai” และให้วัตถุ emp2
เก็บชื่อ “Somying” ก็สามารถเขียนโปรแกรมได้ดังนี้
ซอร์สโค้ด 3 การเก็บข้อมูลไว้ในวัตถุ
emp1.firstName = "Somchai";
emp1.surname = "Rukdee";
emp1.code = "1234";
emp2.firstName = "Somying";
emp2.surname = "Rukchart";
emp2.code = "2431";
หากโปรแกรมทำงานจนครบทั้ง 6 บรรทัดนี้ จะทำให้ข้อมูลในวัตถุ emp1 และ emp2
มีค่าแตกต่างกันดังนี้
ในการเขียนโปรแกรมเชิงวัตถุจริง
โปรแกรมหนึ่งโปรแกรมอาจจะประกอบด้วยวัตถุมากกว่า 1 ชนิดที่มีความสัมพันธ์กัน
เพื่อให้เกิดเป็นแบบจำลอง (Model) ที่ใกล้เคียงกับความต้องการของผู้ใช้มากที่สุด
เช่นในตัวอย่างข้างต้นนี้ หากผู้ออกแบบระบบพบว่าพนักงานทุกคนจะต้องทำงานภายใต้แผนกใดแผนกหนึ่ง
ดังนั้นแบบจำลองเชิงวัตถุที่เกิดขึ้นอาจจะกำหนดให้พนักงานสัมพันธ์กับแผนก
โดยมีคลาสชื่อว่า Department เป็นตัวแทนของวัตถุแผนกดังนี้
ซอร์สโค้ด 4 คลาส Department
เป็นตัวแทนของแผนก
class Department
{
public String name;
public String code;
}
หากแก้ไขคลาส Employee โดยเพิ่มตัวแปรอ้างอิงชื่อว่า
department ให้มีชนิดเป็น Department จะทำให้เราสามารถเก็บความสัมพันธ์ระหว่างพนักงานกับแผนกไว้ได้ดังนี้
ซอร์สโค้ด 5 คลาส Employee
ที่เพิ่มตัวแปรสมาชิก
department สำหรับเก็บความสัมพันธ์ระหว่างพนักงานกับแผนก
class Employee
{
public String firstName;
public String surname;
public String code;
public String status;
public Department
department;
public void checkIn()
{
status = "working";
}
public void checkOut()
{
status = "leave";
}
}
หากเราจำลองให้มีแผนกหนึ่งชื่อว่า Accouting
และต้องการให้พนักงาน Somchai และ Somying
อยู่ในแผนก Accounting ก็สามารถเขียนโปรแกรมเพื่อเชื่อมโยงตัวแปรอ้างอิงที่อยู่ในวัตถุได้ดังนี้
ซอร์สโค้ด 6
ตัวอย่างการเขียนโปรแกรมเพื่อสร้างความสัมพันธ์ระหว่างวัตถุ
Department dept1 = new Department();
dept1.name = "Accounting";
dept1.code = "AC";
emp1.department = dept1;
emp2.department = dept1;
เมื่อโปรแกรมทำงานผ่านคำสั่ง 5 บรรทัดข้างต้นนี้จะทำให้เกิดวัตถุชนิด Department ขึ้นมาใหม่
1 ชิ้น และวัตถุ emp1 และ emp2 จะมีตัวแปรสมาชิกชื่อว่า department อ้างอิงไปที่แผนกของตนเองดังภาพต่อไปนี้
ในการเขียนโปรแกรมจริงผู้ออกแบบโปรแกรมสามารถสร้างวัตถุขึ้นได้หลากหลายชนิด
และจัดวางให้วัตถุแต่ละชนิดมีความสัมพันธ์กันในรูปแบบที่ใกล้เคียงกับระบบจริง เช่น
วัตถุบริษัทประกอบด้วยวัตถุแผนก และ วัตถุแผนกประกอบด้วยวัตถุพนักงาน
เมื่ออาศัยการประกอบวัตถุจากวัตถุใหญ่ไล่ระดับลงไปหาวัตถุเล็กจนกระทั่งได้รายละเอียดครบถ้วนตามโครงสร้างระบบ
ก็จะได้แบบจำลองเชิงวัตถุที่ตรงตามความต้องการใช้งานของผู้ใช้ระบบ
4. การเข้าถึงและสั่งงานวัตถุ
วัตถุที่สร้างขึ้นด้วยคำสั่ง new จะถูกเข้าถึงผ่านทางตัวแปรอ้างอิงที่เรียกว่า Reference Variable หน้าที่ของตัวแปรอ้างอิงคือใช้กำกับและชี้ตัววัตถุ
เพื่อให้โปรแกรมสามารถเลือกได้ว่าจะควบคุมวัตถุตัวไหน
ผู้เขียนโปรแกรมจำเป็นต้องแยกความแตกต่างระหว่างตัวแปรอ้างอิง
กับชิ้นวัตถุที่เกิดขึ้น
เนื่องจากบางครั้งในโปรแกรมอาจจะมีแต่ตัวแปรอ้างอิงแต่ยังไม่ได้กำกับชี้ไว้ที่วัตถุชิ้นใดเลยก็ได้
เช่นการเขียนโปรแกรมเช่นนี้
Employee emp1;
Employee emp2 = new Employee();
ตัวแปร emp1 เป็นเพียงตัวแปรอ้างอิงที่ไม่ได้ชี้ไว้ที่วัตถุ
Employee ตัวใดเลย ซึ่งตัวแปรอ้างอิงแบบนี้เราเรียกว่า Null
Pointer และเป็นตัวแปรที่ไม่มีวัตถุให้เข้าถึง
เราจึงไม่สามารถเขียนโปรแกรม emp1.firstName = “Somchai” ได้
เพราะระบบจะไม่รู้ว่า firstName นั้นเป็นของวัตถุไหน
เพราะตัวแปร emp1 ไม่ได้ชี้วัตถุใดเลย
แต่ตัวแปร emp2 เป็นตัวแปรที่อ้างอิงและชี้ไว้ที่วัตถุที่สร้างขึ้นมาด้วยคำสั่ง
new ดังนั้นเราสามารถนำข้อมูลไปเก็บในวัตถุได้ด้วยคำสั่ง
emp2.firstName = “Somying” ภาพต่อไปนี้แสดงความแตกต่างระหว่างตัวแปรอ้างอิงที่ไม่ชี้วัตถุ
กับตัวแปรอ้างอิงที่ชี้วัตถุ
หากเปรียบเทียบกับในโลกความจริงของเรา
ตัวแปรอ้างอิงอาจจะเปรียบเหมือนกับแผ่นป้ายทะเบียนรถยนต์ แต่ไม่ใช่ตัวรถยนต์
ดังนั้นการมีแต่ตัวแปรอ้างอิงจึงเปรียบเหมือนกับเรามีเพียงป้ายทะเบียน
แต่แน่นอนว่าเพียงแค่ป้ายทะเบียนซึ่งไม่ใช่รถยนต์จริงๆ เราย่อมไม่สามารถใช้ป้ายทะเบียนเป็นยานพาหนะขับบนถนนได้เพราะนั่นไม่ใช่ตัวรถยนต์จริง
เราจำเป็นต้องนำป้ายทะเบียนไปติดกับตัวรถเสียก่อนจึงจะครบถ้วนสมบูรณ์และขับออกถนนได้
เช่นเดียวกันกับการเขียนโปรแกรมเชิงวัตถุ โปรแกรมจำเป็นต้องมีครบทั้งตัวแปรอ้างอิงและชิ้นวัตถุที่ตัวแปรอ้างอิงกำกับอยู่
จึงจะสามารถทำงานได้อย่างถูกต้อง
ตัวแปรอ้างอิง 1 ตัวสามารถใช้ชี้วัตถุได้เพียง
1 ชิ้นเท่านั้น แต่วัตถุ 1
ชิ้นสามารถมีตัวแปรอ้างอิงชี้ได้มากกว่าหนึ่งตัว เช่นหากเราเขียนโปรแกรมเช่นนี้
Employee emp1;
Employee emp2 = new Employee();
emp1 = emp2;
บรรทัดที่เขียนว่า emp1 = emp2 หมายถึงให้ตัวแปรอ้างอิง emp1 อ้างอิงไปที่วัตถุตัวที่
emp2 กำลังชี้อยู่ ดังนั้นวัตถุ Employee ที่สร้างขึ้นจะมีตัวแปรอ้างอิงกำกับไว้ 2 ตัวคือทั้ง
emp1 และ emp2 ดังภาพต่อไปนี้
ตัวแปรอ้างอิงเป็นเพียงทางเข้าไปที่วัตถุเท่านั้น
ดังนั้นหากในภาพข้างต้น ไม่ว่าเราจะเข้าถึงวัตถุผ่านทางตัวแปร emp1 หรือตัวแปร emp2 ย่อมจะได้ผลลัพธ์เทียบเท่ากัน
เนื่องจากวัตถุที่ตัวแปรทั้งคู่ชี้อยู่เป็นวัตถุตัวเดียวกัน
Employee emp1;
Employee emp2 = new Employee();
emp1 = emp2;
emp1.code = "4455";
Console.WriteLine(emp2.code);
// ย่อมได้ค่ามาเป็น 4455 เพราะเป็นวัตถุตัวเดียวกันกับที่ emp1 ชี้อยู่
5. เมธอด
เมธอด (Method) ใช้เก็บชุดคำสั่งโปรแกรม
(Code) ที่เป็นการทำงานของวัตถุ วัตถุสามารถทำงานอะไรก็ได้
เพื่อให้เกิดผลลัพธ์ตรงตามวัตถุประสงค์การใช้งานของผู้ใช้
แต่การออกแบบเชิงวัตถุที่ดีเมธอดควรจะทำงานกับข้อมูลที่อยู่ภายในวัตถุของตัวมันเองเท่านั้น
เพราะจะทำให้เกิดเอกภาพและความเป็นเนื้อเดียวกัน (Cohesion) เมื่อเมธอดทำงานจนจบผลลัพธ์ที่เกิดขึ้นอาจจะยังคงเก็บค้างอยู่ในวัตถุ
หรือส่งกลับออกมาให้ภายนอกวัตถุนำไปใช้งานต่อก็ได้
ตัวอย่างต่อไปนี้เป็นเมธอดชื่อว่า compute
ที่อยู่ในคลาส Rectangle เพื่อใช้ดำเนินการคำนวณพื้นที่รูปสี่เหลี่ยม
ซอร์สโค้ด 7 คลาส Rectangle
และเมธอด compute()
class Rectangle
{
public double width;
public double height;
public double area;
public void compute()
{
area = width * height;
}
}
หากเรานำเอาคลาส Rectangle มาสร้างเป็นวัตถุเพื่อเป็นตัวแทนรูปสี่เหลี่ยมขนาด 100 x 50 และต้องการหาพื้นที่รูปสี่เหลี่ยมจะสามารถเขียนโปรแกรมฝั่งผู้ใช้งาน (Client
Code) ได้ดังนี้
Rectangle rect = new Rectangle();
rect.width = 100;
rect.height = 50;
rect.compute();
Console.WriteLine(rect.area);
สังเกตว่าเมธอด compute() ไม่จำเป็นต้องรับอาร์กิวเมนต์
(Argument) เข้าเป็นอินพุตให้กับการคำนวณ
เนื่องจากอินพุตที่จำเป็นสำหรับการคำนวณคือ width และ height
ได้ถูกเก็บและจดจำไว้ในตัววัตถุเรียบร้อยแล้ว และเมธอด compute()
จะคำนวณพื้นที่โดยอาศัยค่าที่เก็บอยู่ในตัวแปรสมาชิกของวัตถุเป็นอินพุต
6. ความแตกต่างระหว่างเชิงฟังก์ชันและเชิงวัตถุ
การออกแบบโปรแกรมเชิงฟังก์ชัน (Functional
Programming) และการออกแบบโปรแกรมเชิงวัตถุ (Object-Oriented
Programming) มีข้อแตกต่างกันอย่างเห็นได้ชัด หากผู้ออกแบบโปรแกรมยังคงมีแนวคิดแบบฟังก์ชัน
ลักษณะของเมธอดที่ได้จะรับอินพุตจากภายนอกวัตถุและส่งผลลัพธ์กลับออกไปภายนอกวัตถุโดยตัววัตถุเองจะไม่จดจำค่าใดๆไว้ทั้งสิ้น
เช่นในตัวอย่างการคำนวณพื้นที่รูปสี่เหลี่ยม หากออกแบบตามแนวคิดเชิงฟังก์ชันและแนวคิดเชิงวัตถุจะทำให้ได้โปรแกรมที่แตกต่างกันดังภาพต่อไปนี้
จากภาพข้างต้น (ที่หมายเลข 1 และ 2) จะเห็นว่าเมธอดที่ออกแบบมาในลักษณะโปรแกรมเชิงวัตถุจะไม่จำเป็นต้องรับอาร์กิวเมนต์ใดมาเป็นข้อมูลเข้าสำหรับการคำนวณอีก
เนื่องจากข้อมูลที่จำเป็นถูกจดจำไว้ภายในตัววัตถุเรียบร้อยแล้ว
นอกจากนี้เมื่อคำนวณเสร็จผลลัพธ์ที่เกิดขึ้นก็จะเก็บไว้ในตัววัตถุด้วยเช่นกัน
ในทางตรงข้ามหากโปรแกรมถูกออกแบบโดยใช้แนวคิดเชิงฟังก์ชัน
โปรแกรมจะออกมาคล้ายกับในภาพหมายเลข 3 และ 4 ซึ่งเมธอดจะรับอาร์กิวเมนต์จำนวนมากมาเป็นอินพุต
เมื่อคำนวณเสร็จก็จะส่งผลลัพธ์กลับออกไปทางค่าส่งกลับ (Return Value) โดยวัตถุไม่มีความสำคัญและไม่ได้จดจำข้อมูลใดๆไว้ในตัววัตถุ
การสร้างระบบขนาดใหญ่จำเป็นต้องผสมผสานระหว่างแนวคิดเชิงฟังก์ชันและแนวคิดเชิงวัตถุเนื่องจากจะเห็นว่าการออกแบบโปรแกรมทั้ง
2 แบบมีมุมมองแตกต่างกันขึ้นอยู่กับว่าผู้ใช้คลาส (Client
Code) เป็นใคร
หากผู้ใช้คลาสเป็นโปรแกรมเมอร์ที่นำเอาคลาสไปรวบรวมและสร้างเป็นระบบสารสนเทศมักต้องการรูปแบบเชิงวัตถุเนื่องจากสามารถปรับแต่งค่าก่อนการคำนวณได้ง่ายและมีลักษณะโปรแกรมเป็นแบบละเอียด
(Fine-Grain) ที่สามารถอ่านไล่ดูขั้นตอนได้ทีละบรรทัด
แต่หากผู้ใช้คลาสไม่ได้เป็นโปรแกรมเมอร์ แต่เป็นเพียงผู้เชื่อมต่อระบบ (Integrator)
ซึ่งไม่ต้องการรู้รายละเอียดภายในระบบแต่ต้องการเพียงส่งข้อมูลรับและรับผลลัพธ์กลับไปเท่านั้น
มักจะนิยมการออกแบบแนวฟังก์ชัน เพราะเห็นได้ชัดเจนว่าเป็นการดำเนินการอะไร มีข้อมูลอะไรเป็นอินพุตและมีข้อมูลอะไรเป็นเอาท์พุต
7. การปิดซ่อน (Encapsulation)
จากตัวอย่างที่ผ่านมาจะเห็นว่า
ตัวแปรสมาชิกในคลาส Employee หรือ Rectangle ถูกกำหนดระดับการเข้าถึงไว้เป็น public ซึ่งระดับการเข้าถึง
public นี้หมายความว่าโปรแกรมภายนอกสามารถมองเห็นตัวแปรสมาชิก
และเปลี่ยนแปลงค่าในตัวแปรสมาชิกได้โดยตรง ตัวอย่างเช่น การกำหนดค่าโดยเครื่องหมายเท่ากับ
= (Assignment Operator)
Rectangle rect = new Rectangle();
rect.width = 100;
rect.height = 50;
rect.area = 300;
คลาส Rectangle มีตัวแปรสมาชิก
width, height และ area เป็น public
ทำให้ไคลเอ็นต์โค้ดสามารถเข้าถึงตัวแปรเหล่านี้ได้โดยตรงผ่านทางเครื่องหมาย
= การเปลี่ยนแปลงค่าตัวแปรสมาชิกโดยตรงเช่นนี้อาจจะดูเหมือนไคลเอ็นต์โค้ดได้รับความสะดวก
แต่ในความเป็นจริงแล้วถือว่าเป็นการออกแบบเชิงวัตถุที่ไม่ดี
เนื่องจากหากวัตถุยินยอมให้โปรแกรมภายนอกมาเปลี่ยนค่าในตัววัตถุได้โดยตรงโดยไม่มีการควบคุม
อาจจะมีค่าที่ผิดเพี้ยนใส่เข้าไปในวัตถุ และทำให้วัตถุอยู่ในสถานะที่ไม่ถูกต้อง
ส่งผลให้โปรแกรมมีข้อผิดพลาดตามมา เช่น ในตัวอย่างข้างต้นจะเห็นว่า rect.area
= 300 ไม่สอดคล้องกับความกว้างและความสูง เนื่องจากความกว้าง 100
และความสูง 50 ควรจะมีพื้นที่เป็น 5000
เป็นต้น
ในความเป็นจริงเราไม่ควรจะให้โปรแกรมภายนอกเข้าถึงข้อมูล
area ของคลาส Rectangle เพราะ area
เป็นค่าที่เกิดจากการคำนวณด้วย width และ height
ดังนั้นเราจำเป็นต้องปิดซ่อนตัวแปร area ไม่ให้ไคลเอ็นต์โค้ดมองเห็นและกำหนดค่าผ่านทางเครื่องหมายเท่ากับได้
ซอร์สโค้ด 8
การปิดซ่อนตัวแปรสมาชิกด้วย private และการสร้างพร็อพเพอตี (Property) get สำหรับดึงค่าออกจากวัตถุ
{
public double width;
public double height;
private double area;
public double Area
{
get { return area; }
public void compute()
{
area = width * height;
}
}
หากกำหนดระดับการเข้าถึงให้เป็น private จะเป็นการซ่อนไม่ให้ภายนอกมองเห็นสมาชิกเหล่านี้
ทำให้ไม่สามารถกำหนดค่าใส่เข้าไปในตัวแปร area ได้ด้วยเครื่องหมายเท่ากับอีกต่อไป
ดังนั้นต่อไปนี้ไคลเอ็นต์โค้ดจะไม่สามารถเขียนโปรแกรมเอาค่าใส่ให้กับตัวแปร
area เช่นนี้ได้
Rectangle rect = new Rectangle();
rect.area = 300;
เพราะจะทำให้เกิดคอมไพล์โปรแกรมไม่ผ่าน (Compile
Error) วิธีการเช่นนี้ช่วยให้ผู้ออกแบบคลาสสามารถมั่นใจได้ว่าข้อมูลที่ใช้ดำเนินงานอยู่ภายในตัววัตถุจะคงอยู่ในสถานะที่ถูกต้องเสมอ
อย่างไรก็ตามในบางครั้งเราต้องการเก็บผลลัพธ์ที่วัตถุดำเนินการไว้กลับออกมาใช้งานต่อ
แต่หากผลลัพธ์นั้นเป็นตัวแปร private ย่อมทำให้ไม่สามารถเข้าถึงได้จากภายนอก
ดังนั้นผู้ออกแบบคลาสจำเป็นต้องเตรียม Property get เอาไว้เพื่อให้โปรแกรมภายนอกสามารถดึงค่าที่วัตถุเก็บไว้ในตัวแปร
private กลับออกไปใช้งานได้ด้วย เช่นในตัวอย่างข้างต้นจะเห็นว่า
คลาส Rectangle ได้เตรียม Property get ไว้ชื่อว่า Area และส่งค่าตัวแปรสมาชิก area ที่ได้จากการคำนวณกลับออกไปให้ซึ่งจะทำให้โปรแกรมภายนอกสามารถใช้งานคลาส Rectangle
ได้ดังนี้
Rectangle rect = new Rectangle();
rect.width = 100;
rect.height = 50;
double a = rect.Area;
เนื่องจากคลาส Rectangle ได้จัดเตรียมไว้ให้แต่
Property get ดังนั้นผู้ใช้งานคลาสจะไม่สามารถกำหนดค่า (set)
ใส่เข้าไปในพร็อพเพอตี Area ได้
และหากพยายามเขียนโปรแกรมกำหนดค่าด้วยเครื่องหมายเท่ากับก็จะทำให้เกิด
Compile Error
rect.Area = 300;
หากพยายามกำหนดค่า 300 ใส่เข้าไปในวัตถุ
Rectangle เช่นนี้ จะทำให้เกิด Compile Error เนื่องจากคลาส Rectangle ไม่ได้จัดเตรียม
Property set สำหรับ Area ไว้ให้
จากตัวอย่างการใช้ private และ Property get ข้างต้นเราจะได้แนวคิดของการปิดซ่อน
(Encapsulation) ที่เป็นหลักสำคัญในการออกแบบเชิงวัตถุ
โดยแนวคิดนี้จะพยายามปิดบังซ่อนความซับซ้อนภายในตัววัตถุไว้
และเปิดให้โปรแกรมภายนอกเห็นเฉพาะสิ่งที่จำเป็นเท่านั้น การออกแบบตามแนวคิด Encapsulation
นี้เป็นเช่นเดียวกันกับการออกแบบผลิตภัณฑ์ที่จะปิดซ่อนความซับซ้อนไว้ภายใต้ตัวถังหรือกรอบ
และเปิดให้เห็นเฉพาะปุ่มกดที่ใช้เปิดปิดหรือสั่งงานเท่าที่จำเป็นเท่านั้น
8. การสืบทอด (Inheritance)
แม้ว่าวัตถุจะมีหลากหลายชนิดแต่ในความจริงเรามักจะพบวัตถุที่มีลักษณะใกล้เคียงกัน
เช่น รถยนต์ กับ รถกระบะ ต่างก็เป็นรถเหมือนกัน หรือ พนักงานประจำ กับ
พนักงานชั่วคราว ต่างก็เป็นพนักงานเหมือนกัน เป็นต้น
วัตถุที่มีลักษณะส่วนใหญ่คล้ายคลึงกันเช่นนั้นเราเรียกว่ามันมีคุณสมบัติพื้นฐานเหมือนกัน
(Common Characteristic) การออกแบบเชิงวัตถุจะพยายามจัดกลุ่มคลาสที่มีคุณสมบัติพื้นฐานเหมือนกัน
ให้เป็นคลาสแม่ (Superclass) และคลาสที่มีลักษณะพิเศษ (Specialize)
ให้เป็นคลาสลูก (Subclass) เมื่อเราสามารถแยกประเภทได้แล้วว่าคลาสใดเป็นคลาสแม่
ซึ่งก็คือประเภทใหญ่ หรือ คลาสใดเป็นคลาสลูก ซึ่งก็คือประเภทย่อย
ก็จะทำให้เราได้โครงสร้างการสืบทอด (Inheritance Hierarchy) ที่แบ่งประเภทของวัตถุออกตามความคล้ายคลึง
และทำให้เราสามารถออกแบบระบบขนาดใหญ่ได้
ตัวอย่างของการออกแบบโดยอาศัยโครงสร้างการสืบทอด
เช่น หากเรากำลังออกแบบระบบพนักงาน และพบว่าพนักงานทั้ง 2 ประเภทคือ
พนักงานประจำ และ พนักงานชั่วคราว ต่างก็เป็นพนักงานของบริษัท
จะทำให้เราสามารถออกแบบคลาสได้ดังนี้
คลาสลูกที่สืบทอดมาจากคลาสแม่จะได้รับคุณสมบัติทุกอย่างมาจากคลาสแม่
และสามารถต่อเติมคุณสมบัติพิเศษของตนเองเข้าไปได้อีก เช่นในที่นี้กล่าวได้ว่าคลาส PermanentEmployee
มีคุณสมบัติทุกอย่างเทียบเท่า Employee แต่มีคุณสมบัติพิเศษบางอย่างเป็นของตนเองเพิ่มขึ้นมาด้วย
การเขียนโปรแกรมโดยอาศัยการสืบทอดจะช่วยให้โปรแกรมเมอร์ที่โปรแกรมคลาสลูกประหยัดเวลาในการเขียนโปรแกรมเนื่องจากหากโปรแกรมส่วนใหญ่คลาสแม่ได้เขียนไว้สมบูรณ์ดีแล้ว
เพียงแต่ขาดฟังก์ชันเสริมพิเศษบางอย่าง
โปรแกรมเมอร์สามารถสร้างคลาสของตนเองสืบทอดเอาจากคลาสแม่และเพิ่มเมธอดหรือตัวแปรสมาชิกเข้าไปเพื่อให้เกิดฟังก์ชันพิเศษที่เพิ่มเข้ามาได้อีก
โดยยังคงเอาคุณสมบัติส่วนใหญ่ตามคลาสแม่เดิมที่มีอยู่
ด้วยวิธีการสืบทอดและเพิ่มเติมคุณสมบัติเช่นนี้จะทำให้เราเห็นว่าในปัจจุบันโปรแกรมระบบขนาดใหญ่ที่ขึ้นรูปแล้ว
สามารถพัฒนาและออกเป็นโปรแกรมเวอร์ชันใหม่ได้อย่างรวดเร็วเนื่องจากไม่จำเป็นต้องย้อนกลับไปเขียนส่วนคลาสแม่ใหม่
แต่จะเขียนโปรแกรมเฉพาะบริเวณคลาสลูกที่เป็นความสามารถของเวอร์ชันใหม่เท่านั้น
ในทางปฏิบัติผู้เขียนโปรแกรมด้วย Microsof.NET
C# สามารถสร้างคลาสแม่และคลาสลูกได้ด้วยเครื่องหมายโคลอน : (รับเอามาจากเดิมของภาษา C++) เช่นหากต้องการสร้างโครงสร้างคลาสที่มีการสืบทอดเหมือนกับในภาพข้างต้นจะเขียนโปรแกรมได้ดังนี้
จากภาพข้างต้นทำให้เราทราบว่าคลาส
PermanentEmployee สามารถเก็บข้อมูลได้ 6 อย่างคือ
firstName, surname, code และส่วนในคลาสตัวเองคือ taxRate,
socialTax และ salary จะเห็นว่าผู้สร้างคลาส PermanentEmployee
จะได้รับตัวแปรสมาชิกที่เป็นคุณสมบัติดั้งเดิมมาจากคลาส Employee
ที่เป็นคลาสแม่ ทำให้ไม่ต้องสร้างตัวแปรสมาชิก firstName,
surname และ code ใหม่
ในมุมมองของโปรแกรมเมอร์ผู้ใช้งานคลาสจะยังคงใช้งานคลาสตามปกติ
เช่นในที่นี้ก็สามารถนำคลาส PermantentEmployee มาสร้างวัตถุและเก็บข้อมูลไว้ในวัตถุได้
PermanentEmployee emp = new PermanentEmployee();
emp.firstName = "Somchai";
emp.surname = "Rukdee";
emp.code = "1234";
emp.taxRate = 0.3;
emp.socialTax = 1000;
emp.salary = 30000;
9. การเลือกทำตามประเภทวัตถุ (Polymorphism)
การเลือกทำตามประเภทวัตถุเป็นแนวคิดชั้นสูงของการออกแบบเชิงวัตถุ
ซึ่งจะช่วยลดความซับซ้อนของโปรแกรมโดยแยกการดำเนินการที่แตกต่างไปตามประเภทของวัตถุ
แต่อาศัยชื่อกระบวนการที่เป็นชื่อเดียวกัน การใช้ Polymorphism จะช่วยให้ผู้ออกแบบโปรแกรมไม่จำเป็นต้องแยกการดำเนินการด้วยคำสั่ง if
… else … เนื่องจากเส้นทางของโปรแกรมจะแตกแขนงไปตามประเภทของวัตถุในขณะรันไทม์โดยอัตโนมัติ
ตัวอย่างต่อไปนี้แสดงให้เห็นว่าหากเราออกแบบระบบเพื่อคำนวณค่าแรงของพนักงาน
2 ประเภทคือพนักงานประจำ และ พนักงานชั่วคราว
โดยวิธีการคำนวณค่าแรงแตกต่างกัน โดยพนักงานประจำจะคำนวณจากอัตราเงินเดือน ส่วนพนักงานชั่วคราวจะคำนวณจากจำนวนชั่วโมงทำงานคูณด้วยอัตราผลตอบแทนรายชั่วโมง
หากเราไม่ใช้แนวคิดของ Polymorphism โปรแกรมการคำนวณผลตอบแทนของพนักงาน
อาจจะถูกเขียนออกมาดังนี้
ซอร์สโค้ด 9 ตัวอย่างการเขียนโปรแกรมที่ไม่ใช้คุณสมบัติ
Polymorphism
private double
computeWage(Employee emp)
{
if (emp is PermanentEmployee)
{
PermanentEmployee
e = (PermanentEmployee)emp;
return
e.salary;
}
else if(emp is FreelanceEmployee)
{
FreelanceEmployee
e = (FreelanceEmployee)emp;
return
e.wagePerHour * e.hour;
}
return 0;
}
สังเกตว่าโปรแกรม computeWage ข้างต้นจำเป็นต้องตรวจสอบก่อนว่า emp มีชนิดเป็น PermanentEmployee
หรือ FreelanceEmployee แล้วจึงสามารถเลือกคำนวณได้ถูกต้องตามสูตร
วิธีการเขียนโปรแกรมเช่นนี้ ถือว่าผิดหลักการเชิงวัตถุ 2 อย่างคือ
อย่างแรกการดำเนินการคำนวณใดๆก็ตามทำกับข้อมูลในวัตถุควรจะเป็นเมธอดที่อยู่ในตัววัตถุ
ดังนั้นแทนที่เรียกใช้เมธอด computeWage(employee) ในความเป็นจริงควรจะเรียกใช้เป็น
employee.computeWage() อย่างที่สองก็คือโปรแกรมมีการใช้งาน if
… else และ is เพื่อแยกดำเนินการตามประเภทของวัตถุนั่นแสดงให้เห็นว่าโปรแกรมไม่ยืดหยุ่น
หากในอนาคตมีประเภทวัตถุเพิ่มขึ้นอีกโปรแกรมเมอร์จำเป็นต้องแก้ไขบริเวณ if
… else นี้เพื่อให้รองรับวัตถุประเภทอื่นๆที่มีการคำนวณแตกต่างกันไป
ในความเป็นจริงเราสามารถเปลี่ยนโปรแกรมข้างต้นให้ไปอยู่ในตัวคลาส
Employee และทำให้เกิด Polymorphism ได้โดยเขียนโปรแกรมใหม่ดังนี้
เมื่อเราจัดโครงสร้างคลาสให้สืบทอดและให้คลาสลูกโอเวอร์ไรด์
(Override) เมธอดที่คลาสแม่เตรียมไว้
ย่อมทำให้ในขณะรันโปรแกรม
โปรแกรมจะไหลเข้าไปที่เมธอดตามชนิดของวัตถุที่กำลังดำเนินการอยู่
โดยที่เราไม่จำเป็นต้องเขียนโปรแกรม if … else
เพื่อตรวจสอบว่าเป็นวัตถุชนิดใด และเมื่อไหลเข้าสู่เมธอดของคลาสลูก
การดำเนินการย่อมเป็นลักษณะเฉพาะของคลาสลูกตัวนั้น
ก็จะทำให้โปรแกรมแปรเปลี่ยนไปเองได้ตามประเภทของวัตถุ
PermanentEmployee emp1 = new PermanentEmployee();
emp1.firstName = "Somchai";
emp1.surname = "Rukdee";
emp1.code = "1234";
emp1.taxRate = 0.3;
emp1.socialTax = 1000;
emp1.salary = 30000;
FreelanceEmployee emp2 = new FreelanceEmployee();
emp2.firstName = "Somying";
emp2.surname = "Rukchart";
emp2.code = "4231";
emp2.hour = 30;
emp2.wagePerHour = 300;
// คำนวณค่าแรงของพนักงานทั้ง 2 คน (เรียกใช้เมธอดชื่อเดียวกัน แต่การดำเนินการต่างกัน)
Console.WriteLine("Somchai's wage = " +
emp1.computeWage());
Console.WriteLine("Somying's wage = " +
emp2.computeWage());
ข้อดีของการ Polymorphism ก็คือ
นอกจากช่วยลด if … else ที่ไม่จำเป็นแล้ว
โปรแกรมที่เรียกใช้งานยังอยู่ในรูปแบบง่าย
เนื่องจากผู้ใช้สามารถจดจำชื่อเมธอดเพียงชื่อเดียว เช่นในที่นี้ใช้เมธอดชื่อว่า computeWage()
แต่โปรแกรมจะทำงานแตกต่างกันไปเองขึ้นอยู่กับว่าเป็น computeWage()
ของวัตถุประเภท PermanentEmployee หรือประเภท FreelanceEmployee
แนวคิด Polymorphism เป็นหัวใจสำคัญของการโปรแกรมเชิงวัตถุเนื่องจากในโครงสร้างของระบบขนาดใหญ่
ที่มีวัตถุหลากหลายประเภทรวมกันอยู่และทำงานร่วมกัน
ระบบย่อมไม่สามารถรวมกันได้หากวัตถุแต่ละชนิดมีชื่อเมธอดที่แตกต่างกันไป วิธีการ Polymorphism
เป็นการจัดมาตรฐานให้วัตถุที่เป็นประเภทเดียวกันต้องมีชื่อเมธอดเหมือนกัน
แม้ว่าภายในจะมีการทำงานที่แตกต่างกันก็ตาม ซึ่งจะช่วยให้ระบบที่รวบรวมวัตถุเหล่านั้นไว้สามารถควบคุมวัตถุย่อยๆได้ด้วยแนวทางเดียวกันตลอดทั่วทั้งระบบ
10. รายการวัตถุ (Collection)
เราสามารถนำวัตถุหลายชิ้นมารวมกันไว้เป็นรายการและประมวลผลครั้งเดียวทั้งรายการได้
ซึ่งจะช่วยให้โปรแกรมกระชับและง่ายต่อการแก้ไข
วิธีการเก็บวัตถุหลายๆชิ้นไว้ในรายการ เราสามารถใช้อะเรย์ (Array) หรือคอลเลคชัน (Collection) ก็ได้
ใน Microsoft.NET ใช้คลาส
List เพื่อเก็บรวบรวมวัตถุไว้
เช่นเราสามารถนำวัตถุพนักงานหลายๆชิ้นมารวมไว้ใน List เพื่อคำนวณผลรวมค่าแรงของทุกคนได้ดังนี้
PermanentEmployee emp1 = new PermanentEmployee();
emp1.firstName = "Somchai";
emp1.surname = "Rukdee";
emp1.code = "1234";
emp1.taxRate = 0.3;
emp1.socialTax = 1000;
emp1.salary = 30000;
FreelanceEmployee emp2 = new FreelanceEmployee();
emp2.firstName = "Somying";
emp2.surname = "Rukchart";
emp2.code = "4231";
emp2.hour = 30;
emp2.wagePerHour = 300;
List<Employee>
empList = new List<Employee>();
empList.Add(emp1);
// คำนวณผลรวมค่าแรงของพนักงานทุกคน
foreach(Employee emp in empList)
{
sum +=
emp.computeWage();
}
Console.WriteLine("Total wage : " + sum);
นอกจากการใช้ List เพื่อรวบรวมและนำมาคำนวณเช่นในตัวอย่างข้างต้นนี้
เรายังสามารถใช้ List เพื่อสร้างความสัมพันธ์แบบ หนึ่งต่อหลาย
(one-to-many) ในกรณีที่วัตถุใหญ่ประกอบด้วยวัตถุย่อยๆ เช่น
ในที่นี้หากเราต้องการออกแบบให้วัตถุ Department เป็นแผนกงาน
และต้องการคำนวณค่าแรงแยกตามแผนก เราจะให้วัตถุ Department สัมพันธ์กับวัตถุ
Employee แบบหนึ่งต่อหลาย โดยวัตถุ Department หนึ่งชิ้นสามารถประกอบด้วยวัตถุ Employee ได้หลายชิ้น
เช่นเดียวกับที่แผนกหนึ่งมีพนักงานเข้าไปทำงานได้หลายคน
เพื่อให้เกิดความสัมพันธ์แบบหนึ่งต่อหลาย
เราจำเป็นต้องใช้ List เพื่อเก็บวัตถุตัวย่อยเอาไว้ในตัวใหญ่
เช่นในที่นี้เราจะนำ List ไปใช้ในคลาส Department เพื่อเก็บวัตถุ Employee ได้ดังนี้
class Department
{
public String
name;
public String
code;
private List<Employee> member = new
List<Employee>();
public void Add(Employee e)
{
member.Add(e);
}
public double
computeWage()
{
// คำนวณผลรวมค่าแรงของพนักงานทุกคนในแผนกนี้
double sum = 0.0;
foreach (Employee
emp in member)
{
sum += emp.computeWage();
}
return sum;
}
}
โปรแกรมที่ใช้งานคลาส Department และ Employee จะนำวัตถุ Employee ใส่เข้าไปใน Department ก่อนที่จะสั่งคำนวณผลรวมของค่าแรงทั้งหมดในแผนกนั้น
โดยเขียนเป็นโปรแกรมได้ดังนี้
PermanentEmployee emp1 = new PermanentEmployee();
emp1.firstName = "Somchai";
...
FreelanceEmployee emp2 = new FreelanceEmployee();
emp2.firstName = "Somying";
...
Department dept = new Department();
dept.name = "Accounting";
dept.code = "AC";
dept.Add(emp1);
dept.Add(emp2);
// คำนวณผลรวมค่าแรงของพนักงานทุกคนในแผนก AC
double sum = dept.computeWage();
Console.WriteLine("Total wage : " + sum);
ในระบบขนาดใหญ่เราสามารถออกแบบให้มีความสัมพันธ์แบบ
one-to-many ซ้อนกันได้หลายชั้น แล้วแต่ขนาดของระบบ ยิ่งระบบมีขนาดใหญ่และซับซ้อนสูงยิ่งประกอบด้วยวัตถุหลายหลายประเภทที่ซ้อนอยู่ภายใต้วัตถุตัวที่ใหญ่กว่า
ในรอบนอกสุดของระบบจะเป็นวัตถุที่มีความซับซ้อนต่ำสุดและมีการทำงานได้ตรงตามความต้องการของผู้ใช้
ส่วนในชั้นที่ลึกเข้าไปข้างในจะประกอบด้วยวัตถุที่มีความสามารถเฉพาะตัวและทำงานเฉพาะด้านใดด้านหนึ่ง
การออกแบบเช่นนี้จะทำให้เกิดสถาปัตยกรรมระบบ (System Architecture) ที่เป็นองค์รวมได้ในที่สุด
11. บทสรุป
การออกแบบและพัฒนาโปรแกรมเชิงวัตถุเป็นแนวทางการเขียนโปรแกรมขนาดใหญ่ที่มีความซับซ้อนให้มีความยืดหยุ่นสูง
เนื่องจากสามารถแยกส่วนได้ทั้งแนวตั้งและแนวขวาง
เพื่อมอบหมายงานย่อยให้กับวัตถุแต่ละประเภทได้
ซึ่งจะส่งผลให้สามารถแยกความซับซ้อนของระบบขนาดใหญ่ออกมาเป็นส่วนย่อยได้
ทีมงานพัฒนาระบบที่มีลักษณะเชิงวัตถุจะเติมเต็มความสามารถให้กับส่วนประกอบย่อยจนกระทั่งสามารถทำงานได้ครบตามความต้องการของผู้ใช้และจับวัตถุย่อยมารวมเข้าด้วยกันตามสถาปัตยกรรมที่ได้วางแนวทางไว้แล้วตั้งแต่ตอนออกแบบ
ผลก็คือจะได้ระบบที่มีความยืดหยุ่นสูงปรับตัวได้ตามสภาวะแวดล้อมและสามารถแก้ไขดัดแปลงส่วนประกอบย่อยได้ง่ายโดยไม่ส่งผลกระทบกับระบบทั้งระบบ
ความคิดเห็น
แสดงความคิดเห็น