"Xin chào, Amigo! Tôi muốn dành bài giảng hôm nay cho sự đóng gói . Bạn đã có một ý tưởng chung về nó là gì."

Đóng gói - 1

Vì vậy, những lợi thế của đóng gói là gì? Có rất nhiều, nhưng tôi sẽ chỉ ra bốn điều mà theo quan điểm của tôi là quan trọng nhất:

1) Trạng thái bên trong hợp lệ.

Các chương trình thường có một số lớp tương tác với cùng một đối tượng. Bằng cách tương tác đồng thời với dữ liệu bên trong của đối tượng, chúng có thể vi phạm tính toàn vẹn dữ liệu của đối tượng, khiến đối tượng ngừng hoạt động bình thường.

Vì vậy, đối tượng phải theo dõi bất kỳ thay đổi nào đối với dữ liệu nội bộ của nó hoặc tốt hơn nữa – đối tượng phải là đối tượng thực hiện những thay đổi đó.

Nếu chúng ta không muốn một số biến lớp bị thay đổi bởi các lớp khác, thì chúng ta khai báo nó là private , nghĩa là chỉ các phương thức của lớp đó mới có thể truy cập nó. Nếu chúng ta muốn các biến ở chế độ chỉ đọc đối với các lớp khác, thì chúng ta thêm public getter vào các biến này.

Ví dụ: chúng tôi có thể muốn mọi người biết có bao nhiêu yếu tố trong bộ sưu tập của chúng tôi, nhưng không ai có thể thay đổi nó mà không có sự cho phép của chúng tôi. Trong trường hợp này, chúng ta khai báo một biến private int count và một phương thức public getCount() .

Việc đóng gói thích hợp đảm bảo rằng các lớp khác không thể truy cập trực tiếp vào dữ liệu nội bộ của lớp chúng ta và do đó, không thể thay đổi dữ liệu nếu chúng ta không thể kiểm soát hành động của chúng. Họ phải gọi các phương thức trên lớp chứa các biến sẽ được thay đổi.

Tốt nhất là giả định rằng các lập trình viên khác sẽ luôn sử dụng các lớp của bạn theo cách thuận tiện nhất cho họ, chứ không phải theo cách an toàn nhất cho bạn (hoặc lớp của bạn). Đây là một nguồn lỗi và một cách để ngăn chặn chúng.

2) Kiểm tra tham số.

Đôi khi bạn cần kiểm tra các tham số được truyền vào các phương thức của lớp. Ví dụ: giả sử chúng ta có một lớp đại diện cho một "người" và bạn có thể chỉ định ngày sinh của nó. Chúng ta nên xác minh rằng bất kỳ dữ liệu nào được truyền vào đều tương ứng với logic của chương trình và logic của lớp. Ví dụ: không có tháng 13, không có ngày 30 tháng 2, v.v.

"Tại sao ai đó lại cho biết ngày sinh là 30 tháng 2?"

"Chà, trước hết, nó có thể là kết quả của lỗi nhập dữ liệu."

Thứ hai, trước khi một chương trình hoạt động như kim đồng hồ, nó có thể có rất nhiều lỗi. Ví dụ, một cái gì đó như thế này có thể xảy ra.

Một lập trình viên viết mã xác định ai có sinh nhật vào ngày mốt. Giả sử hôm nay là ngày 3 tháng 3. Chương trình cộng 2 vào ngày hiện tại và tìm tất cả những người sinh vào ngày 5 tháng 3. Cho đến nay, rất tốt.

Nhưng khi đến ngày 30 tháng 3, chương trình không tìm thấy bất kỳ ai, vì không có ngày 32 tháng 3. Các chương trình ít lỗi hơn nhiều khi các phương thức thực hiện kiểm tra tham số."

"Tôi nhớ khi chúng tôi nghiên cứu ArrayList, tôi đã xem mã của nó và có các kiểm tra trong phương thức get và set để đảm bảo rằng tham số chỉ mục lớn hơn hoặc bằng 0 và nhỏ hơn độ dài của mảng. Mã sẽ đưa ra một ngoại lệ nếu mảng không có phần tử tương ứng với chỉ mục.

"Vâng, đó là kiểm tra đầu vào cổ điển. "

3) Ít lỗi hơn khi thay đổi mã bên trong các lớp.

Giả sử chúng ta đã viết một lớp thực sự hữu ích như một phần của một dự án lớn. Mọi người đều thích nó đến nỗi các lập trình viên khác bắt đầu sử dụng nó ở hàng trăm chỗ trong mã của họ.

Lớp học tỏ ra hữu ích đến mức bạn quyết định cải thiện nó. Nhưng nếu bạn loại bỏ bất kỳ phương thức nào trong lớp, mã của hàng chục lập trình viên khác sẽ không biên dịch được nữa. Họ sẽ phải nhanh chóng viết lại mã của họ. Và càng viết lại nhiều thì càng có nhiều cơ hội cho các lỗi. Nếu thường xuyên phá công trình, bạn sẽ bị ghét.

Nhưng nếu chúng ta thay đổi các phương thức được đánh dấu là riêng tư, thì chúng ta biết rằng các phương thức này không được gọi bởi mã của bất kỳ ai khác ở bất kỳ đâu. Chúng ta có thể viết lại chúng, thay đổi số lượng và loại tham số, và mã phụ thuộc sẽ vẫn hoạt động. Hoặc ít nhất nó vẫn sẽ biên dịch.

4) Chúng tôi xác định cách các đối tượng khác sẽ tương tác với đối tượng của chúng tôi.

Chúng tôi có thể hạn chế những hành động có thể được thực hiện trên đối tượng của chúng tôi. Ví dụ, chúng ta có thể chỉ muốn tạo một thể hiện của một lớp—ngay cả khi nó được tạo đồng thời ở nhiều nơi trong dự án. Và chúng ta có thể đạt được điều này bằng cách sử dụng đóng gói.

Đóng gói - 2

Đóng gói cho phép chúng tôi áp đặt các hạn chế bổ sung có thể chuyển thành các lợi ích bổ sung . Ví dụ, lớp String được triển khai như một đối tượng không thay đổi . Một thể hiện của lớp Chuỗi không thể bị thay đổi giữa quá trình tạo và hủy của nó. Tất cả các phương thức của lớp Chuỗi (loại bỏ, chuỗi con, ...) đều trả về một chuỗi mới và không có cách nào thay đổi đối tượng mà chúng được gọi.

"Thánh bò. Thì ra là thế."

"Đóng gói là hấp dẫn."

"Tôi đồng ý."