[Java] Tại sao cần getter và setter ?
Khi mới trở thành một lập trình viên Java, tác giả luôn trăn trở về setter và getter với câu hỏi duy nhất: “Tại sao cần viết getter và setter?”. Anh ta xem nó như một quy tắc “thừa”. Ai cũng biết java có 3 từ khóa phục vụ access modifier là public, ...
Khi mới trở thành một lập trình viên Java, tác giả luôn trăn trở về setter và getter với câu hỏi duy nhất: “Tại sao cần viết getter và setter?”. Anh ta xem nó như một quy tắc “thừa”.
Ai cũng biết java có 3 từ khóa phục vụ access modifier là public, protected và private. Mỗi từ khóa sẽ khoanh vùng các phạm vị truy cập cho các field được đính kèm với nó. Cụ thể như bảng sau:
Nếu ta để modifier cho các field là private rồi viết public setter và getter thì các component nằm ở ngoài package chứa class đó vẫn có thể lấy hoặc thay đổi giá trị của field.
1 2 3 4 5 6 7 8 9 10 |
<span class="hljs-keyword">public</span> String name = <span class="hljs-string">"TechmasterVN"</span>; <span class="hljs-comment">// caller:</span> String name = X.name; <span class="hljs-comment">//(X is a object instance);</span> X.name = <span class="hljs-string">"TechmasterUS"</span>; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="hljs-keyword">private</span> String name = <span class="hljs-string">"Techmaster"</span>; <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">return</span> name; } <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span><span class="hljs-params">(String name)</span> </span>{ <span class="hljs-keyword">this</span>.name = name; } <span class="hljs-comment">// caller:</span> String name = X.getname(); |
Ta thấy một đoạn code thì để field dưới dạng public, các component bên ngoài có thể tự do truy cập và thay đổi gía trị. Đoạn code còn lại sử dụng modifier là private và các component bên ngoài truy cập tới field thông qua getter, setter.
Sự khác biệt lớn nhất của 2 cách này chỉ xoay quanh kiểm soát quyền truy cập tới field của class.
Nếu ta cho field đó là public thì đối tượng gọi hoặc sử dụng field đó (gọi tắt là caller) sẽ có quyền tiến hành các thao tác trực tiếp với field này (kể cả gán cho nó giá trị null!!!!). Có lập trình viên nào muốn điều này xảy ra không? Chắc chắn là không rồi.
Nếu ta sử dụng getter và setter, caller sẽ không thể toàn quyền tác động lên field thuộc class. Lúc này, nếu muốn truy cập field thuộc class, ta chỉ có 1 lối vào duy nhất là setter và 1 lối ra duy nhất là getter. Nhờ đó, lập trình viên dễ dàng viết validation check trước khi set giá trị cho field hoặc return lại bản clone của field.
Khi mạch điện bị quá tải, atomat sẽ tự ngắt, đảm bảo an toàn cho đường dây và các thiết bị trong mạch. Ta có thể liên tưởng vai trò của atomat trong mạch điện khá giống với getter – setter trong lập trình hướng đối tượng.
Đôi khi trong getter và setter chúng ta không code thêm gì cả, chỉ có 1 dòng return hoặc set giá trị field. Như vậy chả khác gì để public field và làm code dài thêm?
Chắc chắc là có khác, khi viết getter và setter, chúng ta đã chuẩn bị một nền tảng cơ bản phục vụ việc bảo trì code sau này (thêm các validation, return clone của field,….). Khi đánh giá một class có được code “tốt” hay không, số lượng các dòng code chỉ là yếu tố đóng vai trò rất nhỏ. Rõ ràng khi phải lựa chọn giữa 2 việc: code làm sao cho dễ bảo trì và code làm sao để tốn ít dòng nhất. Tôi sẽ chọn cái đầu tiên.
Techtalk via Techmaster