ในโลกของการพัฒนาซอฟต์แวร์สมัยใหม่ การจัดการข้อมูลที่เชื่อถือได้และมีโครงสร้างเป็นสิ่งสำคัญยิ่งกว่าการแค่เก็บค่าไว้เฉย ๆ TypeScript ซึ่งถูกออกแบบมาเพื่อเพิ่มความแข็งแรงให้กับ JavaScript จึงนำเสนอคุณสมบัติขั้นสูงอย่าง Getters และ Setters เข้ามา เพื่อให้เราสามารถควบคุมวงจรชีวิตของข้อมูลของคุณสมบัติต่างๆ ได้ราวกับนักสถาปนิกผู้ออกแบบระบบนิเวศน์ทางดิจิทัล
TypeScript Getters และ Setters คืออะไร?
Getters และ Setters ไม่ใช่เพียงไวยากรณ์เพิ่มเติม แต่คือกลไกเชิง Object-Oriented Programming ที่ช่วยให้นักพัฒนามีอำนาจในการกำหนดตรรกะเมื่อมีการเข้าถึงหรือเปลี่ยนแปลงสถานะ (State) ของ property หนึ่งๆ โดยพื้นฐานแล้วมันทำหน้าที่เหมือน ‘ประตู’ เฝ้าทรัพย์สินภายในคลาส เมื่อใดก็ตามที่เราเรียกใช้ Getter ระบบจะรันโค้ดส่วนลอจิกรุ่นอ่าน ขณะที่ถ้าเป็นการ Assign ค่าผ่าน Setter โค้ด Validation หรือ Transformation ก็จะทำงานทันที ทำให้มั่นใจว่า data ภายนอกจากมุมมองของผู้ใช้งานจะไม่ขัดแย้งกับกฎเกณฑ์ทางธุรกิจหลัก.
วิธีควบคุมและตรวจสอบข้อมูลอย่างมืออาชีพด้วย Encapsulation
- Validation Logic ใน Setter: นี่คือการนำไปใช้อย่างสำคัญที่สุด แทนที่จะปล่อยให้ค่าที่ไม่ถูกต้องถูกเก็บลงใน object เราสามารถเขียนฟังก์ชัน Validator เข้าไปใน Setter เพื่อตรวจจับเงื่อนไข เช่น หากต้องการบันทึกอายุ จะต้องแน่ใจเสมอว่าตัวเลขนั้นเป็นบวกและอยู่ในช่วงปีที่มีเหตุผล การผูก logic เหล่านี้ไว้ทำให้ Class นั้นมีความรับผิดชอบต่อความสมบูรณ์ของตัวเองโดยอัตโนมัติ
- Computed Properties ผ่าน Getter: บางครั้งเราไม่ได้ต้องการแค่แสดงค่าดิบ แต่ต้องการสร้างคุณสมบัติใหม่จากการคำนวณจากหลาย property ที่มีอยู่ ตัวอย่างเช่น การหา ‘สถานะผู้เชี่ยวชาญ’ ซึ่งอาจมาจากการรวมกันระหว่างระดับประสบการณ์ (Years) และจำนวนโครงการสำเร็จ (Projects Count) โดยที่เราไม่จำเป็นต้องประกาศ variable ใหม่สำหรับ ‘Status’ นี้เลย แค่อ้างอิงผ่าน getter ก็ได้ทันที ทำให้โค้ดสะอาดตาขึ้นมาก.
Code Demonstration แนวคิดเชิงลึก
class User {
private _firstName = '';
private _lastName = ''; <0xC2><0xA0>
// GETTER สำหรับชื่อเต็มที่เกิดจากการคำนวณ (Computation) get fullName(): string {
return `${this._firstName} ${this._lastName}`;
}
setter firstName(name: string): void {
if (!isValidNameFormat(name)) throw new Error('Invalid format'); // Validation!
this._firstName = name;
}
set lastName(surname: string): void {
if (typeof surname !== 'string') throw new TypeError('Must be a string.'); // Type Check!
this._lastName = surname;
}
}
try {
const userInstance = new User();
userInstance.firstName = "John"; /* เรียกใช้ Setter */
userInstance.lastName = "Doe"; /* เรียกใช้ Setter */
console.log(`Full Name is: ${userInstance.fullName}`); /* เรียกใช้ Getter, รัน logic การรวมสตริง */
} catch (e) {/* จัดการ error ที่เกิดขึ้นจาก validation/type check */}
ด้วยกลไกเหล่านี้ เราไม่ได้แค่เก็บข้อมูล แต่เรากำลังสร้างระบบควบคุมทางตรรกะรอบๆ ข้อมูลเหล่านั้น ทำให้โค้ดของเรามีความทนทานสูงขึ้น สามารถตรวจสอบสถานะของ object ได้อย่างแม่นยำแม้จะถูกเรียกใช้งานในบริบทที่แตกต่างกันก็ตาม นี่คือหลักปฏิบัติของการเขียนโปรแกรมเชิงวัตถุระดับมืออาชีพ.