9.3 การปรับปรุงประสิทธิภาพและความสามารถในการขยายโค้ดด้วย OOP
9.3 การปรับปรุงประสิทธิภาพและความสามารถในการขยายโค้ดด้วย OOP
การปรับปรุงประสิทธิภาพและความสามารถในการขยายโค้ดด้วย Object-Oriented Programming (OOP) เป็นวิธีการที่ช่วยทำให้โค้ดมีความยืดหยุ่นในการปรับปรุงและขยายไปในอนาคต ทั้งในด้านของการพัฒนาและการบำรุงรักษาระบบ โดย OOP ใช้หลักการหลาย ๆ ประการที่ช่วยให้โค้ดที่เขียนขึ้นสามารถขยายตัวได้ง่ายขึ้น เช่น การใช้การสืบทอด (Inheritance), การใช้การซ่อนรายละเอียด (Encapsulation), และการออกแบบที่รองรับการเปลี่ยนแปลง (Polymorphism) ซึ่งทั้งหมดนี้จะช่วยให้โปรแกรมมีความยืดหยุ่นและสามารถรองรับการเพิ่มฟีเจอร์ใหม่ ๆ ได้อย่างราบรื่น
การใช้การสืบทอด (Inheritance) เพื่อการขยายและปรับปรุงโค้ด การสืบทอด (Inheritance) เป็นหนึ่งในคุณสมบัติที่สำคัญที่สุดของ OOP เพราะช่วยให้เราสามารถสร้างคลาสใหม่ที่สืบทอดคุณสมบัติจากคลาสเดิมได้ โดยไม่ต้องเขียนโค้ดซ้ำซ้อน หากคลาสหลักมีฟังก์ชันหรือคุณสมบัติที่ใช้ร่วมกันได้ในหลาย ๆ คลาส การสืบทอดจะช่วยให้โค้ดมีการใช้ซ้ำและลดการทำงานซ้ำซ้อน
ตัวอย่างการใช้ Inheritance :
#include <iostream>
using namespace std;
class Animal {
public:
virtual void sound() = 0; // ฟังก์ชันที่ต้องถูก override ในคลาสย่อย
};
class Dog : public Animal {
public:
void sound() override {
cout << "Bark!" << endl;
}
};
class Cat : public Animal {
public:
void sound() override {
cout << "Meow!" << endl;
}
};
int main() {
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->sound(); // Output: Bark!
animal2->sound(); // Output: Meow!
delete animal1;
delete animal2;
return 0;
}
ในตัวอย่างนี้:
คลาส Animal เป็นคลาสพื้นฐานที่มีฟังก์ชัน sound()
คลาส Dog และ Cat สืบทอดมาจาก Animal และสามารถ override ฟังก์ชัน sound() ของคลาสหลักได้
การใช้การสืบทอดช่วยให้เราเพิ่มประเภทของสัตว์ใหม่ ๆ ได้โดยไม่ต้องแก้ไขโค้ดในคลาสหลัก
ข้อดีของ Inheritance:
ช่วยลดการซ้ำซ้อนของโค้ด
ทำให้โค้ดยืดหยุ่นและสามารถขยายได้ง่าย
เพิ่มความสามารถในการใช้งานร่วมกันระหว่างคลาสต่าง ๆ
การใช้การซ่อนรายละเอียด (Encapsulation) เพื่อป้องกันข้อผิดพลาด การซ่อนรายละเอียด (Encapsulation) เป็นการห่อหุ้มข้อมูลภายในคลาสและควบคุมการเข้าถึงข้อมูลภายนอก โดยใช้วิธีการเข้าถึงข้อมูลผ่านเมธอด (Getter/Setter) เท่านั้น การทำเช่นนี้ช่วยลดความเสี่ยงที่ข้อมูลภายในคลาสจะถูกแก้ไขโดยตรงจากภายนอก และทำให้การตรวจสอบหรือเปลี่ยนแปลงการทำงานของระบบง่ายขึ้น
ตัวอย่างการใช้ Encapsulation :
#include <iostream>
using namespace std;
class BankAccount {
private:
double balance;
public:
BankAccount() : balance(0) {}
// Getter
double getBalance() const {
return balance;
}
// Setter
void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
}
}
};
int main() {
BankAccount account;
account.deposit(1000);
cout << "Balance: " << account.getBalance() << endl; // Output: Balance: 1000
account.withdraw(500);
cout << "Balance: " << account.getBalance() << endl; // Output: Balance: 500
return 0;
}
ในตัวอย่างนี้ :
ข้อมูล balance ถูกซ่อนจากการเข้าถึงโดยตรงจากภายนอก
การเข้าถึงข้อมูลจะทำได้ผ่านฟังก์ชัน deposit(), withdraw(), และ getBalance()
ทำให้สามารถควบคุมและตรวจสอบการทำงานได้ง่ายขึ้น
ข้อดีของ Encapsulation:
ลดความซับซ้อนของโค้ด
ลดโอกาสในการเกิดข้อผิดพลาดจากการเข้าถึงข้อมูลโดยตรง
ทำให้สามารถควบคุมพฤติกรรมของข้อมูลได้ดียิ่งขึ้น
การใช้ Polymorphism เพื่อการขยายที่มีความยืดหยุ่น Polymorphism หรือการทำให้สามารถใช้ฟังก์ชันเดียวกันในหลาย ๆ คลาสได้ โดยที่แต่ละคลาสสามารถมีการทำงานที่แตกต่างกันได้ตามที่ต้องการ ฟีเจอร์นี้ช่วยให้โค้ดมีความยืดหยุ่นมากขึ้น เนื่องจากสามารถเพิ่มฟังก์ชันใหม่ ๆ หรือคลาสใหม่ ๆ โดยไม่ต้องแก้ไขโค้ดที่มีอยู่เดิม
ตัวอย่างการใช้ Polymorphism :
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() = 0; // ฟังก์ชันที่ต้องถูก override
};
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing Circle" << endl;
}
};
class Rectangle : public Shape {
public:
void draw() override {
cout << "Drawing Rectangle" << endl;
}
};
int main() {
Shape* shape1 = new Circle();
Shape* shape2 = new Rectangle();
shape1->draw(); // Output: Drawing Circle
shape2->draw(); // Output: Drawing Rectangle
delete shape1;
delete shape2;
return 0;
}
ในตัวอย่างนี้ :
ฟังก์ชัน draw() ถูกประกาศในคลาส Shape เป็นฟังก์ชัน virtual ซึ่งทำให้สามารถถูก override ในคลาส Circle และ Rectangle ได้
โค้ดใน main() สามารถใช้ฟังก์ชัน draw() ได้ในลักษณะ polymorphic โดยไม่ต้องรู้ล่วงหน้าว่าคลาสใดที่ใช้งาน
ข้อดีของ Polymorphism:
เพิ่มความยืดหยุ่นในการเพิ่มฟังก์ชันใหม่ ๆ หรือคลาสใหม่ ๆ
ช่วยให้โค้ดมีความยืดหยุ่นและสามารถขยายได้โดยไม่ต้องแก้ไขโค้ดเดิม
ทำให้สามารถใช้ฟังก์ชันเดียวกันในการทำงานกับหลาย ๆ ประเภทของอ็อบเจกต์
การใช้ Interface และ Abstract Class เพื่อให้โค้ดมีความยืดหยุ่นและรองรับการขยาย การใช้ Interface และ Abstract Class ช่วยให้ระบบสามารถรองรับการเปลี่ยนแปลงและการเพิ่มฟีเจอร์ใหม่ ๆ ได้อย่างง่ายดาย โดยการกำหนดข้อกำหนดหรือข้อตกลงในการดำเนินการในรูปแบบของคลาสที่ไม่ต้องการการใช้งานโดยตรง แต่จะถูกสืบทอดไปยังคลาสที่ใช้งานจริง
ตัวอย่างการใช้ Interface และ Abstract Class :
class Shape {
public:
virtual void draw() = 0; // ฟังก์ชันที่ต้องการให้คลาสย่อย implement
};
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing Circle" << endl;
}
};
class Square : public Shape {
public:
void draw() override {
cout << "Drawing Square" << endl;
}
};
ในตัวอย่างนี้ :
Shape เป็น Abstract Class ที่กำหนด interface สำหรับฟังก์ชัน draw()
คลาส Circle และ Square สืบทอดจาก Shape และทำการ implement ฟังก์ชัน draw() ตามลักษณะของตนเอง
การใช้ Object-Oriented Programming (OOP) ช่วยให้การพัฒนาโปรแกรมมีความยืดหยุ่นและสามารถขยายได้ง่ายขึ้นโดยใช้หลักการสำคัญดังนี้:
Inheritance ช่วยให้การสร้างโค้ดที่สามารถใช้ซ้ำได้
Encapsulation ช่วยลดความซับซ้อนและเพิ่มความปลอดภัยในการจัดการข้อมูล