# 32: Đóng gói phương thức, không chỉ là trạng thái

Trong lý thuyết hệ thống, kiểm soát là một trong những cách xử lý tối ưu nhất khi xử lý các hệ thống có cấu trúc lớn và phức tạp. Trong ngành công nghiệp phần mềm, việc kiểm soát là cực kỳ cần thiết. Việc kiểm soát được hỗ trợ bởi các cấu trúc của ngôn ngữ lập trình như subroutines (các chương trình con) và functions, modulespackages, classes,...

Modulespackages được sử dụng để giải quyết các nhu cầu lớn hơn cho việc kiểm soát, trong khi các class, subroutinefunction lại được sử dụng để giải quyết các khía cạnh chi tiết hơn của vấn đề. Trong những năm qua, tôi phát hiện ra rằng các class dường như là một trong những cấu trúc kiểm soát khó nhất cho các nhà phát triển trong việc lấy quyền. Điều này không phải là hiếm khi tìm thấy một class chỉ với duy nhất 1 main method (phương thức chính) với 3000 dòng lệnh hoặc một class chỉ có duy nhất các phương thức get và set cho các thuộc tính ban đầu của nó.

Những ví dụ này chứng minh rằng các nhà phát triển đã không hiểu đầy đủ về tư duy hướng đối tượng, đã không tận dụng được sức mạnh của các đối tượng như các cấu trúc mô hình. Đối với các nhà phát triển đã quen thuộc với thuật ngữ POJO(Plain Old Java Object) và POCO (Plain Old C# Object hay Plain Old CLR Object), thì đây là sự quay trở lại các khái niệm cơ bản của OO như một mô hình hoá các đối tượng rõ ràng và đơn giản, nhưng không hề ngu ngốc.

Một đối tượng gói gọn cả trạng thái và phương thức, trong đó phương thức được xác định bởi thuộc tính thực tế. Ví dụ như một object cửa 🚪. Nó sẽ có 4 trạng thái: đóng, mở, đang đóng, đang mở. Nó sử dụng 2 quá trình: mởđóng. Phụ thuộc vào trạng thái, các quá trình mở và đóng sẽ khác nhau. Thuộc tính vốn có của 1 đối tượng làm cho quá trình thiết kế đơn giản hơn về mặt khái niệm. Nó nắm 2 nhiệm vụ đơn giản: phân bổ và giao trách nhiệm cho các đối tượng khác nhau bao gồm các giao thức tương tác xen kẽ.

Cách nó hoạt động trong thực tế là một ví dụ minh hoạ rõ ràng nhất. Ví dụ chúng ta có 3 class: Customer, OrderItem. Customer là đối tượng yêu cầu xác thực thông tin tốt nhất cho việc giới hạn tín dụng và các quy tắc xác thực tín dụng. Order là đối tượng xác định mối liên kết giữa khách hàng và quá trình addItems của nó bằng cách gọi đến hàm customer.validateCredit(item.price()), để kiểm tra tín dụng thực tế của đối tượng Customer. Nếu như hàm đó không thành công, nó sẽ tạo ra 1 ngoại lệ ⚠ và huỷ bỏ ❌ quá trình mua.

Các nhà phát triển hướng đối tượng ít kinh nghiệm hơn có thể quyết định gói tất cả các quy tắc kinh doanh vào một đối tượng như OrderManager hoặc OrderService. Trong các thiết kế này, Order, CustomerItem sẽ ghi ít bản ghi hơn. Tất cả các xử lý logic sẽ bao gồm các class và các liên kết của chúng trong một phương thức với nhiều cấu trúc if-then-else. Các method gần như không thể duy trì và dễ dàng bị phá vỡ. Còn lý do? Do kiểm soát không trọn vẹn.

Do vậy, đừng phá vỡ sự đóng gói và sử dụng sức mạnh của ngôn ngữ lập trình mà bạn sử dụng để duy trì nó.