Public Function vs Public Static Function ใน OOP เข้าใจความต่างและใช้ให้ถูกจุด

ใน OOP (Object-Oriented Programming) การใช้ public function และ public static function มีความแตกต่างกันในด้าน "การเข้าถึง" และ "การใช้งาน" ซึ่งส่งผลต่อการออกแบบโปรเจกต์โดยตรง มาดูรายละเอียดกันครับ
public function (Instance Method)
ลักษณะการทำงาน
- ต้องสร้าง Instance (Object) ของคลาสก่อนจึงจะเรียกใช้ได้
 - สามารถเข้าถึง Properties และ Methods อื่น ๆ ของคลาสได้ (รวมถึง 
private/protected) - มักทำงานกับข้อมูลภายในออบเจกต์ (
$this) 
class StringHelper {
  public static function truncate($text, $length = 100) {
    return substr($text, 0, $length) . '...';
  }
}
// ใช้งาน
echo StringHelper::truncate("Lorem ipsum dolor sit amet", 10);เหมาะกับ
- เมธอดที่ต้องทำงานกับ สถานะ (State) ของออบเจกต์
 - เมธอดที่ต้องการเข้าถึงข้อมูลเฉพาะของออบเจกต์ เช่น การอัปเดตข้อมูลผู้ใช้
 - เมธอดที่เป็นส่วนหนึ่งของ Business Logic ของออบเจกต์
 
public static function (Static Method)
ลักษณะการทำงาน
- เรียกใช้ได้ โดยไม่ต้องสร้าง Instance ของคลาส (เรียกผ่านชื่อคลาส)
 - ไม่สามารถใช้ 
$thisได้ เพราะไม่มีออบเจกต์ - มักใช้สำหรับฟังก์ชันที่ ไม่ขึ้นอยู่กับข้อมูลของออบเจกต์
 
class MathHelper {
  // static function (ไม่ต้องสร้าง object)
  public static function add($a, $b) {
    return $a + $b;
  }
}
// การใช้งาน
echo MathHelper::add(5, 3); // Output: 8เหมาะกับ
- Utility Functions ที่ใช้ทำงานทั่วไป ไม่ต้องการเก็บสถานะ
 - Factory Methods (สร้างออบเจกต์)
 - การเข้าถึง Singleton Instance
 - ฟังก์ชันที่เกี่ยวข้องกับคลาสโดยรวม เช่น การคำนวณ
 
ข้อแตกต่างสำคัญ
| คุณสมบัติ | public function | public static function | 
|---|---|---|
| การเรียกใช้ | ต้องสร้าง Object ก่อน | เรียกผ่านชื่อคลาสได้เลย | 
การเข้าถึง $this | 
			✔️ ใช้ได้ | ❌ ใช้ไม่ได้ | 
| การเข้าถึง Properties | ✔️ เข้าถึงได้ทั้งหมด | ❌ เข้าถึงได้เฉพาะ Static Properties | 
| Memory Usage | ใช้ Memory ตาม Object | ใช้ Memory น้อยกว่า | 
ตัวอย่างการใช้งานในโปรเจกต์จริง
ใช้ public static function เมื่อ
สร้าง Singleton Pattern
class DatabaseConnection {
  private static $instance = null;
  private function __construct() {}
  public static function getInstance() {
    if (self::$instance === null) {
      self::$instance = new self();
    }
    return self::$instance;
  }
}
// ใช้งาน
$db = DatabaseConnection::getInstance();
Utility Functions
class StringHelper {
  public static function truncate($text, $length = 100) {
    return substr($text, 0, $length) . '...';
  }
}
// ใช้งาน
echo StringHelper::truncate("Lorem ipsum dolor sit amet", 10);
ใช้ public function เมื่อ
จัดการข้อมูล Object
class User {
  private $name;
  private $email;
  public function __construct($name, $email) {
    $this->name = $name;
    $this->email = $email;
  }
  public function sendWelcomeEmail() {
    // ส่งอีเมลถึงผู้ใช้นี้
  }
}
// ใช้งาน
$user = new User("John", "john@example.com");
$user->sendWelcomeEmail();
ข้อควรระวัง
- หลีกเลี่ยงการใช้ Static มากเกินไป เพราะอาจทำให้โค้ดติดกันแน่น (Tight Coupling) และทดสอบยาก
 - Static Methods ไม่ควรมี Side Effects เช่น การแก้ไขข้อมูลภายนอก เพราะอาจทำให้เกิด Bug ลึกลับได้
 - ใช้ Static สำหรับสิ่งที่ "ไม่เปลี่ยนแปลง" เช่น ค่าคงที่ การคำนวณทางคณิตศาสตร์
 
สรุป เลือกใช้ยังไงดี?
ใช้public function (Instance Method) เมื่อ
- ต้องการทำงานกับ ข้อมูลภายในออบเจกต์
 - ฟังก์ชันนั้นเป็นส่วนหนึ่งของ พฤติกรรม (Behavior) ของออบเจกต์
 - ต้องการใช้ Dependency Injection
 
public static function เมื่อ
- ฟังก์ชันนั้น ไม่ต้องการข้อมูลจากออบเจกต์
 - ต้องการสร้าง Utility Functions
 - ใช้งานร่วมกับ Design Patterns เช่น Singleton, Factory
 
ตัวอย่างสุดท้าย การใช้งานร่วมกัน
class Order {
    private static $taxRate = 0.07;
    private $items = [];
    // Static Method: คำนวณภาษี (ไม่ขึ้นกับ Object)
    public static function calculateTax($amount) {
        return $amount * self::$taxRate;
    }
    // Instance Method: เพิ่มสินค้า (ทำงานกับ Object)
    public function addItem($item) {
        $this->items[] = $item;
    }
    // Instance Method: คำนวณยอดรวม
    public function getTotal() {
        $subtotal = array_sum($this->items);
        $tax = self::calculateTax($subtotal); // เรียกใช้ Static Method
        return $subtotal + $tax;
    }
}
// ใช้งาน
$order = new Order();
$order->addItem(100);
$order->addItem(200);
echo $order->getTotal(); // 321 (300 + 21)
ด้วยความเข้าใจนี้ คุณจะออกแบบคลาสได้ตรงกับความต้องการของโปรเจกต์มากขึ้นครับ! ????