บทนำ: ทำไมต้อง Getter/Setter?
จากตอนที่ 1 เรารู้ว่า private attributes ต้องเข้าถึงผ่าน methods
แต่ methods นั้นต้องทำอะไร?
java// ❌ ปัญหา: Setter ไม่มี validation
public class Student {
private double gpa;
// ❌ ตัวอย่างที่ผิด
public void setGPA(double gpa) {
this.gpa = gpa; // ← เข้ากล่องสิ้นสุด validate!
}
}
// ใช้งาน
Student student = new Student();
student.setGPA(3.75); // ✓ OK
student.setGPA(10.5); // ❌ ยัง set ได้! (ไม่ถูก)
student.setGPA(-5); // ❌ ยัง set ได้! (ไม่ถูก)
ปัญหา:
- ❌ ไม่มี validation
- ❌ data ยังเป็นไปไม่ได้
- ❌ encapsulation ไม่เสร็จสมบูรณ์
ยาวไปอยากเลือกอ่าน
- บทนำ: ทำไมต้อง Getter/Setter?
- ความแตกต่าง: Getter/Setter vs Direct Access
- ❌ ไม่มี Getter/Setter
- ✓ มี Getter/Setter
- Getter: อ่านค่า
- Getter คืออะไร?
- ตัวอย่าง: Simple Getters
- ประเภท Getter
- 1. Simple Getter – อ่านค่าตรงๆ
- 2. Computed Getter – คำนวณหาค่า
- 3. Conditional Getter – ตรวจสอบเงื่อนไข
- Setter: เปลี่ยนค่า
- Setter คืออะไร?
- ตัวอย่าง: Simple Setters
- Validation: ตรวจสอบข้อมูล
- Validation คืออะไร?
- ประเภท Validation
- 1. Null Check – ตรวจสอบ null
- 2. Empty Check – ตรวจสอบว่าง
- 3. Range Check – ตรวจสอบช่วง
- 4. Format Check – ตรวจสอบรูปแบบ
- 5. Business Logic Check – ตรวจสอบตรรกะธุรกิจ
- ตัวอย่างที่ 1: User Account ที่มี Validation
- ตัวอย่างที่ 2: Product ด้วย Validation
- ตัวอย่างที่ 3: Validation ระดับสูง
- Best Practices: Getter/Setter ที่ดี
- 1. Naming Convention ที่ถูก
- 2. Validation ที่สำคัญ
- 3. Exception ที่ชัดเจน
- 4. Getter ที่ safe
- 5. ไม่มี Setter สำหรับบางที่
- สรุป: Getter/Setter ที่ดี
ความแตกต่าง: Getter/Setter vs Direct Access
❌ ไม่มี Getter/Setter
javapublic class BankAccount {
public double balance; // ← public
}
// ใช้งาน
BankAccount account = new BankAccount();
account.balance = 50000; // ✓ OK
account.balance = -10000; // ❌ ยังได้! ผิด!
account.balance = 999999999; // ❌ ยังได้! ผิด!
ปัญหา:
- ใครก็เปลี่ยนได้
- ไม่มีเงื่อนไข
- data inconsistent
✓ มี Getter/Setter
javapublic class BankAccount {
private double balance; // ← private
public void setBalance(double newBalance) {
// ✓ ตรวจสอบเงื่อนไข
if (newBalance < 0) {
throw new IllegalArgumentException("Balance cannot be negative");
}
this.balance = newBalance;
}
public double getBalance() {
return this.balance;
}
}
// ใช้งาน
BankAccount account = new BankAccount();
account.setBalance(50000); // ✓ OK
account.setBalance(-10000); // ❌ ERROR! "Balance cannot be negative"
account.setBalance(999999999); // ✓ OK (ถ้าเงื่อนไขผ่าน)
ประโยชน์:
- ✓ มี validation
- ✓ data ถูกต้อง
- ✓ encapsulation สมบูรณ์
Getter: อ่านค่า
Getter คืออะไร?
Getter = method ที่ อ่านค่า attribute
textNaming convention:
get + AttributeName + () + return type
ตัวอย่าง:
- getName() // return String
- getAge() // return int
- getBalance() // return double
- isActive() // return boolean (special case)
ตัวอย่าง: Simple Getters
javapublic class Student {
private String studentID;
private String name;
private double gpa;
private boolean isActive;
// ===== Getters =====
// Getter for studentID
public String getStudentID() {
return this.studentID;
}
// Getter for name
public String getName() {
return this.name;
}
// Getter for gpa
public double getGPA() {
return this.gpa;
}
// Getter for isActive (boolean uses "is" prefix)
public boolean isActive() {
return this.isActive;
}
}
// ใช้งาน
Student student = new Student();
// ... initialize ...
String id = student.getStudentID(); // ✓ อ่านค่า
String name = student.getName(); // ✓ อ่านค่า
double gpa = student.getGPA(); // ✓ อ่านค่า
boolean active = student.isActive(); // ✓ อ่านค่า
ประเภท Getter
1. Simple Getter – อ่านค่าตรงๆ
javapublic class Person {
private String name;
// Simple getter - อ่านค่าตรงๆ
public String getName() {
return this.name;
}
}
2. Computed Getter – คำนวณหาค่า
javapublic class Circle {
private double radius;
// Computed getter - คำนวณ
public double getArea() {
return Math.PI * radius * radius;
}
public double getCircumference() {
return 2 * Math.PI * radius;
}
}
// ใช้งาน
Circle circle = new Circle(5);
double area = circle.getArea(); // 78.54 (computed)
3. Conditional Getter – ตรวจสอบเงื่อนไข
javapublic class Student {
private double gpa;
// Conditional getter
public String getGradeLevel() {
if (gpa >= 3.5) {
return "Excellent";
} else if (gpa >= 3.0) {
return "Good";
} else if (gpa >= 2.0) {
return "Pass";
} else {
return "Fail";
}
}
}
// ใช้งาน
Student student = new Student();
// ... set gpa ...
String grade = student.getGradeLevel(); // "Excellent"
Setter: เปลี่ยนค่า
Setter คืออะไร?
Setter = method ที่ เปลี่ยนค่า attribute พร้อม validation
textNaming convention:
set + AttributeName + (type value) + void
ตัวอย่าง:
- setName(String name) // void
- setAge(int age) // void
- setBalance(double balance) // void
- setActive(boolean active) // void
ตัวอย่าง: Simple Setters
javapublic class Student {
private String studentID;
private String name;
private double gpa;
private boolean isActive;
// ===== Setters =====
// Setter for studentID
public void setStudentID(String studentID) {
if (studentID == null || studentID.isEmpty()) {
throw new IllegalArgumentException("Student ID cannot be empty");
}
this.studentID = studentID;
}
// Setter for name
public void setName(String name) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Name cannot be empty");
}
this.name = name;
}
// Setter for gpa (WITH VALIDATION)
public void setGPA(double gpa) {
if (gpa < 0 || gpa > 4.0) {
throw new IllegalArgumentException("GPA must be between 0 and 4.0");
}
this.gpa = gpa;
}
// Setter for isActive
public void setActive(boolean isActive) {
this.isActive = isActive;
}
}
// ใช้งาน
Student student = new Student();
student.setStudentID("6501001"); // ✓ OK
student.setName("John Doe"); // ✓ OK
student.setGPA(3.75); // ✓ OK
student.setGPA(5.0); // ❌ ERROR! "GPA must be between 0 and 4.0"
student.setActive(true); // ✓ OK
Validation: ตรวจสอบข้อมูล
Validation คืออะไร?
Validation = ตรวจสอบ ว่าข้อมูลถูกต้องตามกฎก่อน save
java// ✓ ตัวอย่างที่ดี
public void setAge(int age) {
// Validation: ตรวจสอบเงื่อนไข
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Age must be between 0 and 150");
}
// หลังผ่าน validation → set ค่า
this.age = age;
}
ประเภท Validation
1. Null Check – ตรวจสอบ null
javapublic void setName(String name) {
// ตรวจสอบ null
if (name == null) {
throw new IllegalArgumentException("Name cannot be null");
}
this.name = name;
}
2. Empty Check – ตรวจสอบว่าง
javapublic void setEmail(String email) {
// ตรวจสอบว่าง
if (email == null || email.isEmpty()) {
throw new IllegalArgumentException("Email cannot be empty");
}
this.email = email;
}
3. Range Check – ตรวจสอบช่วง
javapublic void setGPA(double gpa) {
// ตรวจสอบช่วง (0-4.0)
if (gpa < 0 || gpa > 4.0) {
throw new IllegalArgumentException("GPA must be between 0 and 4.0");
}
this.gpa = gpa;
}
public void setYear(int year) {
// ตรวจสอบช่วง (1-4)
if (year < 1 || year > 4) {
throw new IllegalArgumentException("Year must be between 1 and 4");
}
this.year = year;
}
4. Format Check – ตรวจสอบรูปแบบ
javapublic void setEmail(String email) {
// ตรวจสอบรูปแบบ email
if (!email.contains("@")) {
throw new IllegalArgumentException("Invalid email format");
}
if (!email.contains(".")) {
throw new IllegalArgumentException("Invalid email format");
}
this.email = email;
}
public void setPhoneNumber(String phone) {
// ตรวจสอบรูปแบบเบอร์โทร
if (!phone.matches("\\d{10}")) { // ต้องเป็นตัวเลข 10 ตัว
throw new IllegalArgumentException("Phone number must be 10 digits");
}
this.phone = phone;
}
5. Business Logic Check – ตรวจสอบตรรกะธุรกิจ
javapublic class BankAccount {
private double balance;
public void withdraw(double amount) {
// ตรวจสอบตรรกะธุรกิจ
if (amount > this.balance) {
throw new IllegalArgumentException("Insufficient balance");
}
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
this.balance -= amount;
}
}
ตัวอย่างที่ 1: User Account ที่มี Validation
javapublic class UserAccount {
private String username;
private String email;
private String password;
private int age;
private boolean isVerified;
// ===== Constructor =====
public UserAccount(String username, String email, String password, int age) {
setUsername(username);
setEmail(email);
setPassword(password);
setAge(age);
this.isVerified = false;
}
// ===== GETTERS =====
public String getUsername() {
return this.username;
}
public String getEmail() {
return this.email;
}
// ❌ ไม่ return password (security!)
// public String getPassword() { return password; }
public int getAge() {
return this.age;
}
public boolean isVerified() {
return this.isVerified;
}
// ===== SETTERS (WITH VALIDATION) =====
// Setter 1: Username
public void setUsername(String username) {
// Validation 1: Null check
if (username == null) {
throw new IllegalArgumentException("Username cannot be null");
}
// Validation 2: Empty check
if (username.isEmpty()) {
throw new IllegalArgumentException("Username cannot be empty");
}
// Validation 3: Length check
if (username.length() < 3) {
throw new IllegalArgumentException("Username must be at least 3 characters");
}
if (username.length() > 20) {
throw new IllegalArgumentException("Username cannot exceed 20 characters");
}
// Validation 4: Format check (alphanumeric only)
if (!username.matches("^[a-zA-Z0-9_]+$")) {
throw new IllegalArgumentException("Username can only contain letters, numbers, and underscore");
}
this.username = username;
}
// Setter 2: Email
public void setEmail(String email) {
// Validation 1: Null check
if (email == null) {
throw new IllegalArgumentException("Email cannot be null");
}
// Validation 2: Format check
if (!email.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
throw new IllegalArgumentException("Invalid email format");
}
this.email = email;
}
// Setter 3: Password
public void setPassword(String password) {
// Validation 1: Null check
if (password == null) {
throw new IllegalArgumentException("Password cannot be null");
}
// Validation 2: Length check
if (password.length() < 8) {
throw new IllegalArgumentException("Password must be at least 8 characters");
}
// Validation 3: Complexity check (must have number)
if (!password.matches(".*\\d.*")) {
throw new IllegalArgumentException("Password must contain at least one digit");
}
// Validation 4: Complexity check (must have uppercase)
if (!password.matches(".*[A-Z].*")) {
throw new IllegalArgumentException("Password must contain at least one uppercase letter");
}
this.password = password;
}
// Setter 4: Age
public void setAge(int age) {
// Validation 1: Range check
if (age < 13) {
throw new IllegalArgumentException("User must be at least 13 years old");
}
if (age > 120) {
throw new IllegalArgumentException("Invalid age");
}
this.age = age;
}
// ===== BUSINESS METHODS =====
public void verifyEmail() {
this.isVerified = true;
System.out.println("✓ Email verified!");
}
public void displayInfo() {
System.out.printf("Username: %s | Email: %s | Age: %d | Verified: %s\n",
username, email, age, isVerified ? "Yes" : "No");
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
System.out.println("=== Valid User ===");
try {
UserAccount user = new UserAccount("john_doe", "[email protected]", "SecurePass123", 25);
user.displayInfo();
user.verifyEmail();
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\n=== Invalid Username (too short) ===");
try {
UserAccount user = new UserAccount("ab", "[email protected]", "SecurePass123", 25);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\n=== Invalid Email ===");
try {
UserAccount user = new UserAccount("john_doe", "invalid-email", "SecurePass123", 25);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\n=== Invalid Password (no uppercase) ===");
try {
UserAccount user = new UserAccount("john_doe", "[email protected]", "securepass123", 25);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\n=== Invalid Age ===");
try {
UserAccount user = new UserAccount("john_doe", "[email protected]", "SecurePass123", 10);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
Output:
text=== Valid User ===
Username: john_doe | Email: [email protected] | Age: 25 | Verified: No
✓ Email verified!
=== Invalid Username (too short) ===
Error: Username must be at least 3 characters
=== Invalid Email ===
Error: Invalid email format
=== Invalid Password (no uppercase) ===
Error: Password must contain at least one uppercase letter
=== Invalid Age ===
Error: User must be at least 13 years old
ตัวอย่างที่ 2: Product ด้วย Validation
javapublic class Product {
private String productID;
private String productName;
private double price;
private int quantity;
private String category;
// ===== Constructor =====
public Product(String id, String name, double price, int qty, String category) {
setProductID(id);
setProductName(name);
setPrice(price);
setQuantity(qty);
setCategory(category);
}
// ===== GETTERS =====
public String getProductID() {
return this.productID;
}
public String getProductName() {
return this.productName;
}
public double getPrice() {
return this.price;
}
public int getQuantity() {
return this.quantity;
}
public String getCategory() {
return this.category;
}
public boolean isInStock() {
return this.quantity > 0;
}
public double getTotalValue() {
return this.price * this.quantity;
}
// ===== SETTERS (WITH VALIDATION) =====
public void setProductID(String id) {
if (id == null || id.isEmpty()) {
throw new IllegalArgumentException("Product ID cannot be empty");
}
this.productID = id;
}
public void setProductName(String name) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Product name cannot be empty");
}
if (name.length() > 100) {
throw new IllegalArgumentException("Product name is too long");
}
this.productName = name;
}
public void setPrice(double price) {
// ตรวจสอบ negative
if (price < 0) {
throw new IllegalArgumentException("Price cannot be negative");
}
// ตรวจสอบ unreasonable high
if (price > 1_000_000) {
throw new IllegalArgumentException("Price is unreasonably high");
}
this.price = price;
}
public void setQuantity(int qty) {
// ตรวจสอบ negative
if (qty < 0) {
throw new IllegalArgumentException("Quantity cannot be negative");
}
// ตรวจสอบ unreasonable high
if (qty > 100_000) {
throw new IllegalArgumentException("Quantity is unreasonably high");
}
this.quantity = qty;
}
public void setCategory(String category) {
if (category == null || category.isEmpty()) {
throw new IllegalArgumentException("Category cannot be empty");
}
// ตรวจสอบ category ที่รู้จัก
String[] validCategories = {"Electronics", "Clothing", "Food", "Books", "Other"};
boolean found = false;
for (String valid : validCategories) {
if (valid.equalsIgnoreCase(category)) {
found = true;
break;
}
}
if (!found) {
throw new IllegalArgumentException("Invalid category");
}
this.category = category;
}
// ===== BUSINESS METHODS =====
public void addStock(int amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
int newQuantity = this.quantity + amount;
setQuantity(newQuantity); // ใช้ setter เพื่อ validate
System.out.printf("✓ Added %d units. New stock: %d\n", amount, this.quantity);
}
public void removeStock(int amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
if (amount > this.quantity) {
throw new IllegalArgumentException("Not enough stock");
}
this.quantity -= amount;
System.out.printf("✓ Removed %d units. Remaining: %d\n", amount, this.quantity);
}
public void displayInfo() {
System.out.printf("ID: %s | Name: %s | Price: %.2f | Qty: %d | Category: %s | Total: %.2f\n",
productID, productName, price, quantity, category, getTotalValue());
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
System.out.println("=== Create Product ===");
Product laptop = new Product("P001", "Laptop", 25000, 10, "Electronics");
laptop.displayInfo();
System.out.println("\n=== Add Stock ===");
laptop.addStock(5);
laptop.displayInfo();
System.out.println("\n=== Remove Stock ===");
laptop.removeStock(3);
laptop.displayInfo();
System.out.println("\n=== Try Invalid Price ===");
try {
Product mouse = new Product("P002", "Mouse", -100, 50, "Electronics");
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\n=== Try Invalid Category ===");
try {
Product book = new Product("P003", "Book", 200, 100, "Magazine");
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\n=== Try Remove Too Much Stock ===");
try {
laptop.removeStock(20); // มี 12 เท่านั้น
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
ตัวอย่างที่ 3: Validation ระดับสูง
javapublic class BankAccount {
private String accountNumber;
private String accountHolder;
private double balance;
private double dailyWithdrawalLimit = 50000;
private double dailyWithdrawnAmount = 0;
// ===== Constructor =====
public BankAccount(String accountNumber, String accountHolder, double initialBalance) {
setAccountNumber(accountNumber);
setAccountHolder(accountHolder);
setBalance(initialBalance);
}
// ===== GETTERS =====
public String getAccountNumber() {
return this.accountNumber;
}
public String getAccountHolder() {
return this.accountHolder;
}
public double getBalance() {
return this.balance;
}
// ===== SETTERS =====
public void setAccountNumber(String accountNumber) {
if (accountNumber == null || accountNumber.isEmpty()) {
throw new IllegalArgumentException("Account number cannot be empty");
}
if (!accountNumber.matches("^[0-9]{10,20}$")) {
throw new IllegalArgumentException("Invalid account number format");
}
this.accountNumber = accountNumber;
}
public void setAccountHolder(String accountHolder) {
if (accountHolder == null || accountHolder.trim().isEmpty()) {
throw new IllegalArgumentException("Account holder name cannot be empty");
}
this.accountHolder = accountHolder;
}
public void setBalance(double balance) {
if (balance < 0) {
throw new IllegalArgumentException("Balance cannot be negative");
}
this.balance = balance;
}
// ===== BUSINESS METHODS WITH VALIDATION =====
public void deposit(double amount) {
// Validation: ตรวจสอบ amount
if (amount <= 0) {
throw new IllegalArgumentException("Deposit amount must be positive");
}
if (amount > 1_000_000) {
throw new IllegalArgumentException("Deposit amount is too large");
}
// Execute
this.balance += amount;
System.out.printf("✓ Deposited: %.2f | New balance: %.2f\n", amount, this.balance);
}
public void withdraw(double amount) {
// Validation 1: ตรวจสอบ amount
if (amount <= 0) {
throw new IllegalArgumentException("Withdrawal amount must be positive");
}
// Validation 2: ตรวจสอบ balance
if (amount > this.balance) {
throw new IllegalArgumentException("Insufficient balance");
}
// Validation 3: ตรวจสอบ daily limit
if (this.dailyWithdrawnAmount + amount > this.dailyWithdrawalLimit) {
throw new IllegalArgumentException(
"Daily withdrawal limit exceeded. Limit: " + dailyWithdrawalLimit);
}
// Execute
this.balance -= amount;
this.dailyWithdrawnAmount += amount;
System.out.printf("✓ Withdrawn: %.2f | New balance: %.2f\n", amount, this.balance);
}
public void transfer(BankAccount recipient, double amount) {
// Validation 1: recipient ไม่ null
if (recipient == null) {
throw new IllegalArgumentException("Recipient account cannot be null");
}
// Validation 2: ตรวจสอบ amount
if (amount <= 0) {
throw new IllegalArgumentException("Transfer amount must be positive");
}
// Validation 3: ตรวจสอบ balance
if (amount > this.balance) {
throw new IllegalArgumentException("Insufficient balance for transfer");
}
// Execute
this.withdraw(amount);
recipient.deposit(amount);
System.out.printf("✓ Transferred %.2f from %s to %s\n",
amount, this.accountNumber, recipient.getAccountNumber());
}
public void displayInfo() {
System.out.printf("Account: %s | Holder: %s | Balance: %.2f\n",
accountNumber, accountHolder, balance);
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
System.out.println("=== Create Accounts ===");
BankAccount account1 = new BankAccount("1234567890", "John Doe", 100000);
BankAccount account2 = new BankAccount("0987654321", "Jane Smith", 50000);
account1.displayInfo();
account2.displayInfo();
System.out.println("\n=== Deposit ===");
account1.deposit(20000);
System.out.println("\n=== Withdraw ===");
account1.withdraw(15000);
System.out.println("\n=== Transfer ===");
account1.transfer(account2, 10000);
System.out.println("\n=== Error: Insufficient Balance ===");
try {
account2.withdraw(100000);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\n=== Error: Invalid Account ===");
try {
BankAccount bad = new BankAccount("123", "John", 50000);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
Best Practices: Getter/Setter ที่ดี
1. Naming Convention ที่ถูก
java// ✓ ดี
public String getName() { }
public void setName(String name) { }
public int getAge() { }
public void setAge(int age) { }
public boolean isActive() { } // boolean uses "is"
public void setActive(boolean active) { }
// ❌ ไม่ดี
public String GetName() { } // CapitalG
public void setname(String name) { } // lowercase n
public boolean getActive() { } // should be isActive()
public void set_name(String name) { } // underscore
2. Validation ที่สำคัญ
java// ✓ ดี: มี validation
public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Age must be between 0 and 150");
}
this.age = age;
}
// ❌ ไม่ดี: ไม่มี validation
public void setAge(int age) {
this.age = age;
}
3. Exception ที่ชัดเจน
java// ✓ ดี: Error message ชัดเจน
if (email == null) {
throw new IllegalArgumentException(
"Email cannot be null. Expected format: [email protected]");
}
// ❌ ไม่ดี: Message สั้นเกินไป
if (email == null) {
throw new IllegalArgumentException("Invalid email");
}
4. Getter ที่ safe
java// ✓ ดี: ไม่ให้แก้ได้
public List<String> getCourses() {
return new ArrayList<>(this.courses); // copy
}
// ❌ ไม่ดี: ให้แก้ได้โดยตรง
public List<String> getCourses() {
return this.courses; // original reference
}
5. ไม่มี Setter สำหรับบางที่
java// ✓ ดี: ไม่มี setter สำหรับ ID (immutable)
public class Student {
private String studentID;
public String getStudentID() {
return studentID;
}
// ❌ ไม่มี setStudentID()
// ID ตั้งแต่เริ่มต้น ไม่เปลี่ยน
}
// ✓ ดี: ไม่มี setter สำหรับ password (only verify)
public class Account {
private String password;
public boolean verifyPassword(String input) {
return password.equals(input);
}
// ❌ ไม่มี getPassword()
// ไม่ให้อ่าน password
}
สรุป: Getter/Setter ที่ดี
text┌─────────────────────────────────────────┐
│ GETTER (อ่านค่า) │
├─────────────────────────────────────────┤
│ ✓ Naming: getName() │
│ ✓ Simple: return value │
│ ✓ Safe: return copy (if needed) │
│ ✓ Computed: คำนวณหาค่าได้ │
│ ✓ No side effects │
│ │
│ SETTER (เปลี่ยนค่า) │
├─────────────────────────────────────────┤
│ ✓ Naming: setName(Type value) │
│ ✓ Validation: check before assign │
│ ✓ Clear error: throw exception │
│ ✓ Call other setters: reuse logic │
│ ✓ No returning value (void) │
│ │
│ VALIDATION (ตรวจสอบ) │
├─────────────────────────────────────────┤
│ ✓ Null check: != null │
│ ✓ Empty check: !isEmpty() │
│ ✓ Range check: min/max │
│ ✓ Format check: regex/pattern │
│ ✓ Business logic: domain rules │
│ │
└─────────────────────────────────────────┘
บทความนี้เป็นส่วนหนึ่งของรายวิชา Object-Oriented Programming with Java สำหรับนักศึกษาวิศวกรรมคอมพิวเตอร์และวิศวกรรมซอฟต์แวร์
