Các phương thức getter và setter

Giới hạn khả năng truy cập của các trường dữ liệu giúp bảo vệ an toàn cho dữ liệu cũng như giúp class trở nên dễ bảo trì hơn.

Khi viết những class mới, để ý đến quyền truy cập là một thói quen tốt. Ngược lại với việc để một class được public sẽ khiến class đó có khả năng truy cập từ bất kỳ đâu, giới hạn khả năng truy cập của một thuộc tính xuống mức private sẽ khiến thuộc tính đó chỉ có thể được truy cập từ trong class định nghĩa nó mà thôi.

Theo quan điểm của nhiều lập trình viên, phần lớn các thuộc tính nên được đặt mức truy cập ở private. Cho phép lớp được trao toàn quyền điều khiển những thuộc tính đó.

Kể cả khi một thuộc tính là private, thông qua những phương thức truy cập (được publish), những class khác vẫn có khả năng tìm tới, sử dụng và thậm chí gián tiếp thay đổi giá trị của nó. Như trong ví dụ sau đây, phương thức truy cập có tên getTitle đã gián tiếp trao cho các lớp bên ngoài khả năng sử dụng đến giá trị của thuộc tính private title:

public String getTitle() {
  return title;
}

Theo quy ước, tên của phương thức truy cập của một thuộc tính được cấu tạo từ tiền tố get, sau đó tới tên của thuộc tính viết theo cú pháp CamelCase. Chính vì tiền tố này, các phương thức truy cập còn được gọi là các setter method.

Đôi khi, cho những thuộc tính của kiểu boolean, tiền tố is được sử dụng thay cho get. Ví dụ, phương thức truy cập cho thuộc tính done sẽ có tên là isDone().

Ta cũng có thể cung cấp khả năng “ghi” lên các thuộc tính private, giúp các class bên ngoài có khả năng đặt một giá trị xác định cho thuộc tính, thông qua các setter method. Các setter method được đặt tên với tiền tố set theo sau là tên của thuộc tính viết theo cú pháp CamelCase. Để đạt được mục đích, các phương thức này phải có một tham số có cùng kiểu với thuộc tính. Một setter method được viết cho thuộc tính title sẽ như sau:

public void setTitle( String newTitle ) {
  this.title = newTitle;
}

Bởi vì tên của tham số của setter, một cách tự nhiên, trùng tên với thuộc tính, cho nên trong setter, thuộc tính thường được gọi lên đi kèm với từ khóa this để tránh gây nhầm lẫn.

Thật tế, rất thường xuyên cả getter lẫn setter được viết để cung cấp khả năng đọc/ghi lên một thuộc tính, làm nảy sinh một câu hỏi là tại sao không chỉ cần làm cho thuộc tính được public là được.

Nguyên nhân ở đây là do getter và setter không chỉ hướng đến những thao tác đọc và ghi giá trị đơn giản. Trong thực tế, như các phương thức bình thường, chúng có thể thực hiện bất kỳ hành động nào. Ví dụ, một getter có thể lưu tồn số lần giá trị của thuộc tính được đọc ra:

public String getTitle() {
  titleAccessCount++;  // Increment member variable titleAccessCount.
  return title;
}

và một setter có thể kiểm tra sự hợp lệ của giá trị đang được yêu cầu ghi vào:

public void setTitle( String newTitle ) {
  if ( newTitle == null )   // Don’t allow null strings as titles!
     title = "(Untitled)";  // Use an appropriate default value instead.
  else
     title = newTitle;
}

Kể cả khi các getter và setter đang không thực hiện công việc gì khác, điều đó không có nghĩa rằng tương lai vẫn sẽ như vậy. Nếu các lớp khác đã truy cập tới thuộc tính thông qua getter và setter ngay từ đầu, trong tương lai, những điều chỉnh bên trong các getter và setter có thể được thực hiện mà không kéo theo bất kỳ thay đổi nào trên các lớp bên ngoài.

Một vài lưu ý cuối cùng ở đây là, đầu tiên, một vài khía cạnh nâng cao của Java phụ thuộc mạnh mẽ vào quy ước đặt tên cho các getter và setter, cho nên luôn tuyệt đối tuân thủ quy ước. Điều thứ hai, các getter và setter cho một “thuộc tính” của class có thể tồn tại mà không cần đến thuộc tính private tương ứng. Ví dụ, một class có thuộc tính firstName và lastName, class đó có thể có cặp phương thức truy cập getFullname và setFullname mà không cần tới thuộc tính fullname thực sự.

Bài viết liên quan

Leave a Reply

Your email address will not be published.