Getters và setters trong TypeScript là các phương thức cho phép bạn truy cập và cập nhật các thuộc tính của một đối tượng một cách an toàn và có kiểm soát. Chúng cung cấp một cách để thêm logic vào việc truy xuất và gán giá trị cho các thuộc tính, giúp đảm bảo rằng các ràng buộc và quy tắc được áp dụng. Trong bài viết này, chúng ta sẽ tìm hiểu cách sử dụng getters và setters, lợi ích của chúng, cùng với các ví dụ minh họa.

1. Getters

Getters là các phương thức được sử dụng để lấy giá trị của một thuộc tính. Khi bạn định nghĩa một getter, bạn có thể truy cập thuộc tính đó như một thuộc tính bình thường mà không cần gọi phương thức.

Cách Định Nghĩa Getter

Để định nghĩa một getter trong TypeScript, bạn sử dụng từ khóa get theo sau là tên của thuộc tính. Bên trong getter, bạn có thể thực hiện các phép toán hoặc kiểm tra trước khi trả về giá trị.

Ví dụ về Getter

class Circle {
    private radius: number;

    constructor(radius: number) {
        this.radius = radius;
    }

    get area(): number {
        return Math.PI * this.radius * this.radius;
    }
}

const circle = new Circle(5);
console.log(circle.area); // Kết quả: 78.53981633974483

Trong ví dụ trên, getter area được định nghĩa để tính diện tích của hình tròn dựa trên bán kính. Bạn có thể truy cập diện tích như một thuộc tính mà không cần gọi hàm.

2. Setters

Setters là các phương thức được sử dụng để cập nhật giá trị của một thuộc tính. Khi bạn định nghĩa một setter, bạn có thể gán giá trị cho thuộc tính đó như một thuộc tính bình thường.

Cách Định Nghĩa Setter

Để định nghĩa một setter trong TypeScript, bạn sử dụng từ khóa set theo sau là tên của thuộc tính. Bên trong setter, bạn có thể thêm logic để xử lý giá trị trước khi gán cho thuộc tính.

Ví dụ về Setter

class Rectangle {
    private _width: number;
    private _height: number;

    constructor(width: number, height: number) {
        this._width = width;
        this._height = height;
    }

    set width(value: number) {
        if (value <= 0) {
            throw new Error("Width must be positive.");
        }
        this._width = value;
    }

    get width(): number {
        return this._width;
    }

    set height(value: number) {
        if (value <= 0) {
            throw new Error("Height must be positive.");
        }
        this._height = value;
    }

    get height(): number {
        return this._height;
    }

    get area(): number {
        return this._width * this._height;
    }
}

const rectangle = new Rectangle(10, 5);
console.log(rectangle.area); // Kết quả: 50

rectangle.width = 20; // Thay đổi chiều rộng
console.log(rectangle.area); // Kết quả: 100

// rectangle.width = -5; // Lỗi: Width must be positive.

Trong ví dụ này, các setter cho widthheight được định nghĩa với logic kiểm tra để đảm bảo rằng các giá trị được gán là dương. Nếu bạn cố gắng gán giá trị âm, một lỗi sẽ được ném ra.

3. Lợi Ích của Getters và Setters

3.1. Kiểm Soát Truy Cập Dữ Liệu

Getters và setters cho phép bạn kiểm soát cách mà các thuộc tính được truy cập và cập nhật. Bạn có thể thêm logic để đảm bảo rằng các giá trị luôn hợp lệ, như trong ví dụ về Rectangle.

3.2. Tính Ẩn Dữ Liệu

Bằng cách sử dụng getters và setters, bạn có thể ẩn các thuộc tính của lớp và chỉ cung cấp quyền truy cập thông qua các phương thức. Điều này giúp bảo vệ dữ liệu và đảm bảo rằng các quy tắc được tuân thủ.

3.3. Tính Linh Hoạt

Getters và setters cung cấp sự linh hoạt trong cách mà bạn có thể thay đổi cách một thuộc tính được tính toán hoặc lưu trữ mà không làm thay đổi mã nơi thuộc tính đó được sử dụng.

4. Kết Hợp với Các Tính Năng Khác

Getters và setters có thể được kết hợp với các tính năng khác trong TypeScript, chẳng hạn như tính kế thừa và các giao diện.

Ví dụ Kết Hợp với Kế Thừa

class Shape {
    constructor(public name: string) {}
}

class Square extends Shape {
    private _sideLength: number;

    constructor(name: string, sideLength: number) {
        super(name);
        this._sideLength = sideLength;
    }

    set sideLength(value: number) {
        if (value <= 0) {
            throw new Error("Side length must be positive.");
        }
        this._sideLength = value;
    }

    get sideLength(): number {
        return this._sideLength;
    }

    get area(): number {
        return this._sideLength * this._sideLength;
    }
}

const square = new Square("MySquare", 4);
console.log(square.area); // Kết quả: 16

Trong ví dụ này, lớp Square kế thừa từ lớp Shape và sử dụng getters và setters để quản lý chiều dài cạnh của hình vuông.

Kết Luận

Getters và setters trong TypeScript là những công cụ mạnh mẽ giúp quản lý và kiểm soát quyền truy cập vào các thuộc tính của lớp. Chúng cho phép bạn thêm logic để đảm bảo tính hợp lệ của dữ liệu và ẩn các chi tiết triển khai khỏi người sử dụng. Việc sử dụng getters và setters không chỉ giúp mã nguồn trở nên rõ ràng hơn mà còn cải thiện tính bảo trì và khả năng mở rộng của ứng dụng.