Class เป็นแม่แบบ, Object เป็นอินสแตนซ์

บทนำ: ความสัมพันธ์ระหว่าง Class และ Object

ในบทที่แล้ว เราเข้าใจว่า Object มี State และ Behavior แต่ว่า Object มาจากไหน?

คำตอบคือ: มาจาก Class

Class และ Object มีความสัมพันธ์ดังนี้:

แนวคิดความหมายตัวอย่าง
Classแบบพิมพ์เขียว (Blueprint)หลักการวิธีทำรถยนต์
Objectสิ่งของจริงที่สร้างจาก Classรถยนต์คันนี้ (Toyota Corolla สีแดง)
ยาวไปอยากเลือกอ่าน
  1. บทนำ: ความสัมพันธ์ระหว่าง Class และ Object
  2. Class: แบบพิมพ์เขียว (Blueprint)
  3. Class คืออะไร?
  4. ตัวอย่าง: Class ในการเขียนโปรแกรม
  5. Object: อินสแตนซ์ (Instance)
  6. Object คืออะไร?
  7. วิธีสร้าง Object จาก Class
  8. ความแตกต่างระหว่าง Class และ Object
  9. ตัวอย่างที่ 1: BankAccount
  10. Class: BankAccount (แบบแผน)
  11. Objects: Instances ของ BankAccount
  12. การใช้งาน Objects
  13. ตัวอย่างที่ 2: Car
  14. Class: Car (แบบแผน)
  15. Objects: Instances ของ Car
  16. ทำไมต้องแยก Class และ Object?
  17. ปัญหา: ไม่มี Class
  18. วิธี: ใช้ Class
  19. ความเป็นอิสระของ Objects
  20. Objects เป็นอิสระจากกัน
  21. ตัวอย่างที่ 3: Student Management System
  22. Class: Student (เขียนครั้งเดียว)
  23. Objects: Instances ของ Student (สร้างหลายตัว)
  24. ตัวอย่างที่ 4: Game Characters
  25. Class: GameCharacter
  26. Objects: Multiple Characters (เกมกำลังแสดง)
  27. Visual: Class vs Objects
  28. ดูภาพรวม
  29. สรุป: Class เป็นแม่แบบ, Object เป็นอินสแตนซ์
  30. Analogy
  31. ตัวอย่างสุดท้าย: Restaurant Reservation System
  32. Class: Restaurant
  33. Objects: Multiple Restaurants
  34. ข้อสังเกต: Class vs Object
  35. Class
  36. Object

Class: แบบพิมพ์เขียว (Blueprint)

Class คืออะไร?

Class คือ แบบแผน ที่บ่งบอกว่า:

  1. Object ที่สร้างจาก Class นี้จะมีข้อมูลอะไร (State)
  2. Object ที่สร้างจาก Class นี้จะทำอะไรได้บ้าง (Behavior)

ตัวอย่างในชีวิตจริง:

textClass: Vehicle
┌────────────────────┐
│ Blueprint ของรถ    │
├────────────────────┤
│ State ที่ต้องมี:   │
│ - brand            │
│ - color            │
│ - speed            │
│ - fuelLevel        │
├────────────────────┤
│ Behavior ที่ต้องมี:│
│ - start()          │
│ - accelerate()     │
│ - brake()          │
│ - stop()           │
└────────────────────┘

ตัวอย่าง: Class ในการเขียนโปรแกรม

java// นี่คือ CLASS - แบบพิมพ์เขียว
public class Student {
    
    // State - ข้อมูลที่ object ต้องมี
    private String studentID;
    private String name;
    private double gpa;
    private int year;
    
    // Constructor - สร้าง object
    public Student(String studentID, String name, double gpa, int year) {
        this.studentID = studentID;
        this.name = name;
        this.gpa = gpa;
        this.year = year;
    }
    
    // Behavior - สิ่งที่ object ทำได้
    public void study() {
        // เรียน
        this.gpa += 0.1;
    }
    
    public void displayInfo() {
        System.out.println("ID: " + studentID);
        System.out.println("Name: " + name);
        System.out.println("GPA: " + gpa);
    }
}

Class นี้บอกว่า:

  • Student object ต้องมี studentID, name, gpa, year
  • Student object สามารถ study() และ displayInfo()

แต่ ยังไม่มี object จริงๆ – เพียงแบบแผนเท่านั้น


Object: อินสแตนซ์ (Instance)

Object คืออะไร?

Object คือ สิ่งของจริง ที่สร้างจาก Class

เรียกว่า Instance เพราะ object คือ หนึ่งตัวอย่าง ของ Class

textClass: Student (แบบแผน)
  ↓
  ├─→ Object 1: john (Instance 1 - จริงๆ)
  ├─→ Object 2: jane (Instance 2 - จริงๆ)
  └─→ Object 3: bob (Instance 3 - จริงๆ)

ทั้ง john, jane, bob คือ Instance ของ Class Student

วิธีสร้าง Object จาก Class

java// syntax:
ClassName objectName = new ClassName(parameters);

// ตัวอย่าง:
Student john = new Student("6501001", "John Doe", 3.75, 2);
Student jane = new Student("6501002", "Jane Smith", 3.50, 2);
Student bob = new Student("6501003", "Bob Johnson", 3.90, 1);

สิ่งที่เกิดขึ้น:

text1. new Student(...) 
   ↓ สร้างพื้นที่เก็บข้อมูลในหน่วยความจำ
   ↓

2. Student(...) 
   ↓ เรียก Constructor เพื่อกำหนดค่าเริ่มต้น
   ↓

3. john = ...
   ↓ เก็บ reference ของ object
   ↓

ผลลัพธ์: john กลายเป็น object ของ Class Student

ความแตกต่างระหว่าง Class และ Object

ตัวอย่างที่ 1: BankAccount

Class: BankAccount (แบบแผน)

javapublic class BankAccount {
    // State
    private String accountNumber;
    private String accountHolder;
    private double balance;
    
    // Constructor
    public BankAccount(String accountNumber, String accountHolder, double balance) {
        this.accountNumber = accountNumber;
        this.accountHolder = accountHolder;
        this.balance = balance;
    }
    
    // Behavior
    public void deposit(double amount) {
        balance += amount;
    }
    
    public void withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount;
        }
    }
    
    public void displayBalance() {
        System.out.println("Balance: " + balance);
    }
}

Class นี้เป็นแบบแผน – ยังไม่มี account จริงๆ


Objects: Instances ของ BankAccount

java// สร้าง 3 objects จาก Class BankAccount

// Object 1: account ของ John
BankAccount johnAccount = new BankAccount("ACC001", "John Doe", 50000);

// Object 2: account ของ Jane
BankAccount janeAccount = new BankAccount("ACC002", "Jane Smith", 75000);

// Object 3: account ของ Bob
BankAccount bobAccount = new BankAccount("ACC003", "Bob Johnson", 30000);

ตอนนี้มี 3 objects จริงๆ:

textjohnAccount:
├─ accountNumber = "ACC001"
├─ accountHolder = "John Doe"
└─ balance = 50000

janeAccount:
├─ accountNumber = "ACC002"
├─ accountHolder = "Jane Smith"
└─ balance = 75000

bobAccount:
├─ accountNumber = "ACC003"
├─ accountHolder = "Bob Johnson"
└─ balance = 30000

การใช้งาน Objects

javapublic class BankDemo {
    public static void main(String[] args) {
        // สร้าง 3 objects
        BankAccount johnAccount = new BankAccount("ACC001", "John Doe", 50000);
        BankAccount janeAccount = new BankAccount("ACC002", "Jane Smith", 75000);
        
        // เรียก Behavior ของ johnAccount
        johnAccount.deposit(10000);    // ฝากเงิน
        johnAccount.displayBalance();  // Output: Balance: 60000
        
        // เรียก Behavior ของ janeAccount
        janeAccount.withdraw(20000);   // ถอนเงิน
        janeAccount.displayBalance();  // Output: Balance: 55000
        
        // สรุป
        System.out.println("johnAccount balance: 60000");
        System.out.println("janeAccount balance: 55000");
        System.out.println("โดยทั้งสองเป็น objects (instances) ของ Class BankAccount");
    }
}

Output:

textBalance: 60000
Balance: 55000
johnAccount balance: 60000
janeAccount balance: 55000
โดยทั้งสองเป็น objects (instances) ของ Class BankAccount

ตัวอย่างที่ 2: Car

Class: Car (แบบแผน)

textClass Car (แบบแผน)
┌─────────────────────────────┐
│ State:                      │
│ - brand                     │
│ - model                     │
│ - color                     │
│ - speed                     │
│ - fuelLevel                 │
│                             │
│ Behavior:                   │
│ - start()                   │
│ - accelerate()              │
│ - brake()                   │
│ - refuel()                  │
└─────────────────────────────┘

Class นี้บอก "รถควรมีข้อมูลและทำงานอย่างไร"
แต่ยังไม่มีรถจริง

Objects: Instances ของ Car

textInstance 1: myCar
┌──────────────────────┐
│ brand = "Toyota"     │
│ model = "Corolla"    │
│ color = "Red"        │
│ speed = 0            │
│ fuelLevel = 50       │
└──────────────────────┘

Instance 2: yourCar
┌──────────────────────┐
│ brand = "Honda"      │
│ model = "Civic"      │
│ color = "Blue"       │
│ speed = 0            │
│ fuelLevel = 100      │
└──────────────────────┘

Instance 3: carAtShop
┌──────────────────────┐
│ brand = "BMW"        │
│ model = "X5"         │
│ color = "Black"      │
│ speed = 0            │
│ fuelLevel = 30       │
└──────────────────────┘

ทั้ง 3 objects มาจาก Class Car เดียวกัน
แต่มี State ต่างกัน

ทำไมต้องแยก Class และ Object?

ปัญหา: ไม่มี Class

java// ❌ ไม่ใช้ Class - ต้องเขียนโค้ดซ้ำซ้อน

// Account 1 ของ John
String account1Number = "ACC001";
String account1Holder = "John Doe";
double account1Balance = 50000;

// Account 2 ของ Jane
String account2Number = "ACC002";
String account2Holder = "Jane Smith";
double account2Balance = 75000;

// Account 3 ของ Bob
String account3Number = "ACC003";
String account3Holder = "Bob Johnson";
double account3Balance = 30000;

// Behavior: ฝากเงิน (ต้องเขียนซ้ำ 3 ครั้ง!)
account1Balance += 10000;
account2Balance += 20000;
account3Balance += 5000;

// ถ้ามี 1000 accounts ต้องเขียน 3000 variables!

วิธี: ใช้ Class

java// ✓ ใช้ Class - เขียนครั้งเดียว ใช้หลายครั้ง

// Class BankAccount (เขียนครั้งเดียว)
public class BankAccount {
    private String accountNumber;
    private String accountHolder;
    private double balance;
    
    public void deposit(double amount) {
        balance += amount;
    }
}

// สร้าง 1000 objects ใน loop!
BankAccount[] accounts = new BankAccount[1000];
for (int i = 0; i < 1000; i++) {
    accounts[i] = new BankAccount(...);
}

// ใช้ทั้งหมด
for (BankAccount account : accounts) {
    account.deposit(1000);
}

ข้อดี:

  • ✓ เขียน Class ครั้งเดียว
  • ✓ สร้าง objects ได้หลายชั้นไป
  • ✓ ลดการเขียนโค้ดซ้ำ
  • ✓ ง่ายต่อการดูแล

ความเป็นอิสระของ Objects

Objects เป็นอิสระจากกัน

javaBankAccount account1 = new BankAccount("ACC001", "John", 50000);
BankAccount account2 = new BankAccount("ACC002", "Jane", 75000);

// account1 ทำสิ่งใดสิ่งหนึ่ง
account1.deposit(10000);
// account1.balance = 60000

// account2 ไม่ได้รับผลกระทบ
// account2.balance = 75000 (ยังเหมือนเดิม)

System.out.println(account1.getBalance());  // 60000
System.out.println(account2.getBalance());  // 75000

ทำไม?

  • account1 และ account2 เป็น objects ต่างกัน
  • มี หน่วยความจำต่างกัน
  • เปลี่ยนแปลง state ของ account1 ไม่ส่งผลกระทบ account2

ตัวอย่างที่ 3: Student Management System

Class: Student (เขียนครั้งเดียว)

javapublic class Student {
    // State
    private String studentID;
    private String name;
    private double gpa;
    private int year;
    
    // Constructor
    public Student(String studentID, String name, double gpa, int year) {
        this.studentID = studentID;
        this.name = name;
        this.gpa = gpa;
        this.year = year;
    }
    
    // Behavior
    public void updateGPA(double newGPA) {
        this.gpa = newGPA;
    }
    
    public void displayInfo() {
        System.out.printf("ID: %s, Name: %s, GPA: %.2f, Year: %d\n", 
                         studentID, name, gpa, year);
    }
}

Objects: Instances ของ Student (สร้างหลายตัว)

javapublic class StudentDemo {
    public static void main(String[] args) {
        // สร้าง 5 objects จาก Class Student
        Student student1 = new Student("6501001", "John Doe", 3.75, 2);
        Student student2 = new Student("6501002", "Jane Smith", 3.50, 2);
        Student student3 = new Student("6501003", "Bob Johnson", 3.90, 1);
        Student student4 = new Student("6501004", "Alice Brown", 3.45, 3);
        Student student5 = new Student("6501005", "Tom Wilson", 3.80, 1);
        
        // เรียก Behavior ของแต่ละ object
        System.out.println("=== Before Update ===");
        student1.displayInfo();
        student2.displayInfo();
        student3.displayInfo();
        
        // เปลี่ยน state ของ student1
        student1.updateGPA(3.85);
        
        // student2 และ student3 ไม่เปลี่ยน
        System.out.println("\n=== After Update (only student1) ===");
        student1.displayInfo();
        student2.displayInfo();  // ยังเหมือนเดิม
        student3.displayInfo();  // ยังเหมือนเดิม
        
        // เปลี่ยน state ของ student3
        student3.updateGPA(4.0);
        
        System.out.println("\n=== After Update (student3) ===");
        student3.displayInfo();  // เปลี่ยน
        student1.displayInfo();  // ยังเหมือนเดิม
    }
}

Output:

text=== Before Update ===
ID: 6501001, Name: John Doe, GPA: 3.75, Year: 2
ID: 6501002, Name: Jane Smith, GPA: 3.50, Year: 2
ID: 6501003, Name: Bob Johnson, GPA: 3.90, Year: 1

=== After Update (only student1) ===
ID: 6501001, Name: John Doe, GPA: 3.85, Year: 2
ID: 6501002, Name: Jane Smith, GPA: 3.50, Year: 2
ID: 6501003, Name: Bob Johnson, GPA: 3.90, Year: 1

=== After Update (student3) ===
ID: 6501003, Name: Bob Johnson, GPA: 4.00, Year: 1
ID: 6501001, Name: John Doe, GPA: 3.85, Year: 2

ตัวอย่างที่ 4: Game Characters

Class: GameCharacter

javapublic class GameCharacter {
    // State
    private String characterName;
    private int level;
    private int health;
    private int experience;
    
    // Constructor
    public GameCharacter(String characterName, int level) {
        this.characterName = characterName;
        this.level = level;
        this.health = 100;
        this.experience = 0;
    }
    
    // Behavior
    public void takeDamage(int damage) {
        health -= damage;
        if (health < 0) health = 0;
    }
    
    public void heal(int amount) {
        health += amount;
        if (health > 100) health = 100;
    }
    
    public void gainXP(int xp) {
        experience += xp;
        if (experience >= 100) {
            level++;
            experience = 0;
        }
    }
    
    public void displayStatus() {
        System.out.printf("Character: %s, Level: %d, HP: %d, XP: %d\n",
                         characterName, level, health, experience);
    }
}

Objects: Multiple Characters (เกมกำลังแสดง)

javapublic class GameDemo {
    public static void main(String[] args) {
        // สร้าง 3 character objects
        GameCharacter hero = new GameCharacter("Hero", 5);
        GameCharacter enemy1 = new GameCharacter("Goblin", 3);
        GameCharacter enemy2 = new GameCharacter("Orc", 4);
        
        System.out.println("=== Initial State ===");
        hero.displayStatus();
        enemy1.displayStatus();
        enemy2.displayStatus();
        
        System.out.println("\n=== Battle ===");
        
        // Hero ถูกโจมตี
        hero.takeDamage(20);
        System.out.println("Hero was attacked!");
        hero.displayStatus();
        
        // Hero กินยา
        hero.heal(15);
        System.out.println("Hero healed!");
        hero.displayStatus();
        
        // Hero ชนะศัตรู
        hero.gainXP(50);
        System.out.println("Hero defeated Goblin!");
        hero.displayStatus();
        
        // Enemy1 ถูกฆ่า
        enemy1.takeDamage(100);
        System.out.println("Goblin died!");
        enemy1.displayStatus();
        
        // Hero ชนะศัตรูต่อ
        hero.gainXP(100);
        System.out.println("Hero defeated Orc and leveled up!");
        hero.displayStatus();
        
        System.out.println("\n=== Final State ===");
        System.out.println("Hero is alive: " + (hero.health > 0));
        System.out.println("Goblin is alive: " + (enemy1.health > 0));
        System.out.println("Orc is alive: " + (enemy2.health > 0));
    }
}

Output:

text=== Initial State ===
Character: Hero, Level: 5, HP: 100, XP: 0
Character: Goblin, Level: 3, HP: 100, XP: 0
Character: Orc, Level: 4, HP: 100, XP: 0

=== Battle ===
Hero was attacked!
Character: Hero, Level: 5, HP: 80, XP: 0
Hero healed!
Character: Hero, Level: 5, HP: 95, XP: 0
Hero defeated Goblin!
Character: Hero, Level: 5, HP: 95, XP: 50
Goblin died!
Character: Goblin, Level: 3, HP: 0, XP: 0
Hero defeated Orc and leveled up!
Character: Hero, Level: 6, HP: 95, XP: 0

=== Final State ===
Hero is alive: true
Goblin is alive: false
Orc is alive: false

Visual: Class vs Objects

ดูภาพรวม

text┌─────────────────────────────────────┐
│         CLASS Student               │
│  (แบบแผนสำหรับสร้าง objects)       │
│                                     │
│ Attributes:                         │
│ - studentID: String                 │
│ - name: String                      │
│ - gpa: double                       │
│ - year: int                         │
│                                     │
│ Methods:                            │
│ - study()                           │
│ - updateGPA()                       │
│ - displayInfo()                     │
└─────────────────────────────────────┘
         ↓       ↓       ↓
    new Student  new Student  new Student
         ↓       ↓       ↓

┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│  OBJECT: john    │ │  OBJECT: jane    │ │  OBJECT: bob     │
│ (Instance 1)     │ │ (Instance 2)     │ │ (Instance 3)     │
│                  │ │                  │ │                  │
│ studentID:       │ │ studentID:       │ │ studentID:       │
│ "6501001"        │ │ "6501002"        │ │ "6501003"        │
│ name: "John Doe" │ │ name: "Jane"     │ │ name: "Bob"      │
│ gpa: 3.75        │ │ gpa: 3.50        │ │ gpa: 3.90        │
│ year: 2          │ │ year: 2          │ │ year: 1          │
└──────────────────┘ └──────────────────┘ └──────────────────┘

สรุป: Class เป็นแม่แบบ, Object เป็นอินสแตนซ์

แนวคิดความหมายตัวอย่าง
Classแบบพิมพ์เขียว (Blueprint)public class Student { ... }
Objectสิ่องจริงที่สร้างจาก Class (Instance)Student john = new Student(...);
Relationship1 Class สามารถสร้าง objects หลายตัว1 Class → ∞ Objects
IndependenceObjects เป็นอิสระจากกันเปลี่ยน john ไม่ส่งผลกับ jane

Analogy

textClass คือ: พิมพ์สำหรับทำคุ้กกี้
Object คือ: คุ้กกี้ที่ทำจากพิมพ์นั้น

- 1 พิมพ์ → ทำคุ้กกี้ได้หลายแบบ
- แต่ละคุ้กกี้ เป็นอิสระจากกัน (คุ้กกี้ตัวนึง หักหล่นไม่ส่งผลต่ออีกตัว)

ตัวอย่างสุดท้าย: Restaurant Reservation System

Class: Restaurant

javapublic class Restaurant {
    // State
    private String restaurantName;
    private String cuisine;
    private int totalTables;
    private int availableTables;
    private double rating;
    
    // Constructor
    public Restaurant(String restaurantName, String cuisine, int totalTables, double rating) {
        this.restaurantName = restaurantName;
        this.cuisine = cuisine;
        this.totalTables = totalTables;
        this.availableTables = totalTables;
        this.rating = rating;
    }
    
    // Behavior
    public boolean reserveTable(int numTables) {
        if (availableTables >= numTables) {
            availableTables -= numTables;
            return true;
        }
        return false;
    }
    
    public void cancelReservation(int numTables) {
        availableTables += numTables;
        if (availableTables > totalTables) {
            availableTables = totalTables;
        }
    }
    
    public void displayStatus() {
        System.out.printf("%s (%s) - Rating: %.1f ★ | Available Tables: %d/%d\n",
                         restaurantName, cuisine, rating, availableTables, totalTables);
    }
}

Objects: Multiple Restaurants

javapublic class RestaurantDemo {
    public static void main(String[] args) {
        // สร้าง 3 restaurant objects
        Restaurant restaurant1 = new Restaurant("Thai Palace", "Thai", 10, 4.5);
        Restaurant restaurant2 = new Restaurant("Pizza House", "Italian", 8, 4.2);
        Restaurant restaurant3 = new Restaurant("Sushi Master", "Japanese", 6, 4.8);
        
        System.out.println("=== Initial State ===");
        restaurant1.displayStatus();
        restaurant2.displayStatus();
        restaurant3.displayStatus();
        
        System.out.println("\n=== Making Reservations ===");
        
        // จองโต๊ะ Thai Palace 3 โต๊ะ
        if (restaurant1.reserveTable(3)) {
            System.out.println("Reserved 3 tables at Thai Palace");
        }
        restaurant1.displayStatus();
        
        // จองโต๊ะ Pizza House 4 โต๊ะ
        if (restaurant2.reserveTable(4)) {
            System.out.println("Reserved 4 tables at Pizza House");
        }
        restaurant2.displayStatus();
        
        // ลองจอง Sushi Master 10 โต๊ะ (ไม่พอ)
        if (restaurant3.reserveTable(10)) {
            System.out.println("Reserved 10 tables at Sushi Master");
        } else {
            System.out.println("Cannot reserve 10 tables at Sushi Master (only 6 available)");
        }
        restaurant3.displayStatus();
        
        System.out.println("\n=== After More Reservations ===");
        
        // จองโต๊ะ Sushi Master 5 โต๊ะ (พอ)
        if (restaurant3.reserveTable(5)) {
            System.out.println("Reserved 5 tables at Sushi Master");
        }
        restaurant3.displayStatus();
        
        System.out.println("\n=== Cancellations ===");
        
        // ยกเลิกการจอง Thai Palace 2 โต๊ะ
        restaurant1.cancelReservation(2);
        System.out.println("Cancelled 2 reservations at Thai Palace");
        restaurant1.displayStatus();
    }
}

Output:

text=== Initial State ===
Thai Palace (Thai) - Rating: 4.5 ★ | Available Tables: 10/10
Pizza House (Italian) - Rating: 4.2 ★ | Available Tables: 8/8
Sushi Master (Japanese) - Rating: 4.8 ★ | Available Tables: 6/6

=== Making Reservations ===
Reserved 3 tables at Thai Palace
Thai Palace (Thai) - Rating: 4.5 ★ | Available Tables: 7/10
Reserved 4 tables at Pizza House
Pizza House (Italian) - Rating: 4.2 ★ | Available Tables: 4/8
Cannot reserve 10 tables at Sushi Master (only 6 available)
Sushi Master (Japanese) - Rating: 4.8 ★ | Available Tables: 6/6

=== After More Reservations ===
Reserved 5 tables at Sushi Master
Sushi Master (Japanese) - Rating: 4.8 ★ | Available Tables: 1/6

=== Cancellations ===
Cancelled 2 reservations at Thai Palace
Thai Palace (Thai) - Rating: 4.5 ★ | Available Tables: 9/10

ข้อสังเกต: Class vs Object

Class

text✓ เขียนครั้งเดียว
✓ เป็น "template" อ้างอิง
✓ ไม่มี data จริงๆ
✓ อยู่ใน source code

Object

text✓ สร้างได้หลายตัว
✓ เป็น "สิ่องจริง"
✓ มี data จริงๆ ต่างกันแต่ละตัว
✓ มีอยู่ใน memory เมื่อรันโปรแกรม

บทความนี้เป็นส่วนหนึ่งของรายวิชา Object-Oriented Programming with Java สำหรับนักศึกษาวิศวกรรมคอมพิวเตอร์และวิศวกรรมซอฟต์แวร์