Thay thế các phụ thuộc trực tiếp bằng tin nhắn
Đôi khi một mô-đun chỉ cần thông báo cho những người khác rằng một số sự kiện/thay đổi đã xảy ra trong đó và điều gì xảy ra với thông tin này sau đó không quan trọng.
Trong trường hợp này, các mô-đun hoàn toàn không cần phải “biết về nhau”, nghĩa là chứa các liên kết trực tiếp và tương tác trực tiếp, mà chỉ cần trao đổi tin nhắn (message) hoặc sự kiện (event) là đủ.
Đôi khi có vẻ như giao tiếp mô-đun qua tin nhắn yếu hơn nhiều so với sự phụ thuộc trực tiếp. Thật vậy, vì các phương thức không được gọi nên không có thông tin về các lớp. Nhưng điều này không hơn gì một ảo ảnh.
Thay vì tên phương thức, logic bắt đầu được gắn với các loại thông báo, tham số của chúng và dữ liệu được truyền. Khả năng kết nối của các mô-đun như vậy bị bôi nhọ.
Nó từng giống như: chúng tôi gọi các phương thức - có kết nối, chúng tôi không gọi các phương thức - không có kết nối. Bây giờ hãy tưởng tượng rằng mô-đun A bắt đầu gửi dữ liệu hơi khác trong các tin nhắn của nó. Đồng thời, tất cả các mô-đun phụ thuộc vào các thông báo này sẽ không hoạt động bình thường.
Giả sử, trước đó, khi thêm một người dùng mới, mô-đun ủy quyền đã gửi tin nhắn USER_ADDED và sau khi cập nhật, nó bắt đầu gửi tin nhắn này khi cố gắng đăng ký và cho biết thêm đăng ký thành công hay không trong các tham số.
Do đó, điều rất quan trọng là phải thực hiện cơ chế thông điệp thật thành thạo. Có nhiều mẫu khác nhau cho việc này.
Người quan sát. Nó được sử dụng trong trường hợp phụ thuộc một-nhiều, khi nhiều mô-đun phụ thuộc vào trạng thái của một - mô-đun chính. Nó sử dụng cơ chế gửi thư, có nghĩa là mô-đun chính chỉ cần gửi cùng một thông điệp đến tất cả những người đăng ký của nó và các mô-đun quan tâm đến thông tin này thực hiện giao diện “người đăng ký” và đăng ký vào danh sách gửi thư.
Cách tiếp cận này được sử dụng rộng rãi trong các hệ thống có giao diện người dùng, cho phép lõi của ứng dụng (mô hình) duy trì tính độc lập trong khi thông báo cho các giao diện liên kết của nó rằng có điều gì đó đã thay đổi và cần được cập nhật.
Ở đây, định dạng thông báo được chuẩn hóa ở cấp hệ điều hành, mà các nhà phát triển phải quan tâm đến khả năng tương thích ngược và tài liệu tốt.
Việc tổ chức tương tác thông qua việc phân phối tin nhắn có một “phần thưởng” bổ sung - sự tồn tại tùy chọn của “người đăng ký” đối với các tin nhắn “đã xuất bản” (nghĩa là đã gửi đi). Một hệ thống được thiết kế tốt như thế này cho phép thêm/bớt các mô-đun bất cứ lúc nào.
xe buýt nhắn tin
Bạn có thể tổ chức việc trao đổi tin nhắn và sử dụng mẫu Người hòa giải cho việc này theo một cách khác .
Nó được sử dụng khi có sự phụ thuộc nhiều-nhiều giữa các mô-đun. Người hòa giải hoạt động như một trung gian trong giao tiếp giữa các mô-đun, hoạt động như một trung tâm giao tiếp và loại bỏ nhu cầu các mô-đun tham chiếu rõ ràng với nhau.
Do đó, sự tương tác của các mô-đun với nhau (“tất cả với tất cả”) được thay thế bằng sự tương tác giữa các mô-đun chỉ với một trung gian (“một với tất cả”). Người hòa giải được cho là gói gọn sự tương tác giữa nhiều mô-đun.
Đây được gọi là trung gian thông minh . Chính ở đó, các nhà phát triển thường bắt đầu bổ sung các biện pháp hỗ trợ của họ, điều này ảnh hưởng đến hành vi của các mô-đun riêng lẻ bằng cách bật / tắt nhận một số thông báo nhất định.
Một ví dụ thực tế điển hình là kiểm soát giao thông sân bay. Tất cả các tin nhắn từ máy bay đi đến tháp điều khiển của bộ điều khiển thay vì được gửi trực tiếp giữa các máy bay. Và bộ điều khiển đã đưa ra quyết định về việc máy bay nào có thể cất cánh hoặc hạ cánh, và lần lượt gửi tin nhắn đến các máy bay.
Quan trọng! Các mô-đun có thể gửi cho nhau không chỉ các thông báo đơn giản mà còn cả các đối tượng lệnh. Tương tác như vậy được mô tả bởi mẫu Lệnh. Điểm mấu chốt là đóng gói một yêu cầu để thực hiện một hành động cụ thể dưới dạng một đối tượng riêng biệt.
Trên thực tế, đối tượng này chứa một phương thức exec() duy nhất , sau đó cho phép bạn chuyển hành động này sang các mô-đun khác để thực thi dưới dạng tham số và thường thực hiện bất kỳ thao tác nào với đối tượng lệnh có thể được thực hiện trên các đối tượng thông thường.
luật Demeter
Luật Demeter cấm sử dụng các phụ thuộc ngầm định: "Đối tượng A không được truy cập trực tiếp vào đối tượng C nếu đối tượng A có quyền truy cập vào đối tượng B và đối tượng B có quyền truy cập vào đối tượng C."
Điều này có nghĩa là tất cả các phần phụ thuộc trong mã phải “rõ ràng” - các lớp / mô-đun chỉ có thể sử dụng “các phần phụ thuộc của chúng” trong công việc của chúng và không được chuyển qua chúng sang phần khác. Một ví dụ điển hình là kiến trúc ba tầng. Lớp giao diện nên hoạt động với lớp logic, nhưng không nên tương tác trực tiếp với lớp cơ sở dữ liệu.
Tóm lại, nguyên tắc này cũng được hình thành theo cách này: "Chỉ tương tác với những người bạn trực tiếp chứ không phải với bạn của bạn bè." Điều này khiến mã ít gắn kết hơn, cũng như khả năng hiển thị và tính minh bạch cao hơn của thiết kế.
Luật Demeter thực hiện “nguyên tắc hiểu biết tối thiểu” đã đề cập, đây là cơ sở của sự liên kết lỏng lẻo và bao gồm thực tế là một đối tượng / mô-đun nên biết càng ít chi tiết càng tốt về cấu trúc và thuộc tính của các đối tượng / mô-đun khác và bất cứ thứ gì nói chung, kể cả các thành phần riêng của nó .
Một sự tương tự từ cuộc sống: nếu bạn muốn con chó chạy, thật ngu ngốc khi ra lệnh cho bàn chân của nó, tốt hơn là ra lệnh cho con chó, và nó sẽ tự xử lý bàn chân của mình.
Thành phần thay vì kế thừa
Đây là một chủ đề rất lớn và thú vị và ít nhất nó xứng đáng có một bài giảng riêng. Rất nhiều bản sao đã bị hỏng về chủ đề này trên Internet cho đến khi đạt được sự đồng thuận - chúng tôi sử dụng tính kế thừa ở mức tối thiểu, bố cục - ở mức tối đa.
Vấn đề là tính kế thừa thực sự cung cấp kết nối mạnh nhất giữa các lớp, vì vậy nên tránh sử dụng nó. Chủ đề này được đề cập kỹ lưỡng trong bài viết của Herb Sutter " Prefer Composition Over Inheritance ".
Khi bạn bắt đầu học các mẫu thiết kế, bạn sẽ bắt gặp một loạt các mẫu chi phối việc tạo ra một đối tượng hoặc cấu trúc bên trong của nó. Nhân tiện, trong ngữ cảnh này, tôi có thể khuyên bạn nên chú ý đến mẫu Đại biểu / Đại biểu và mẫu Thành phần , xuất phát từ các trò chơi .
Chúng ta sẽ nói nhiều hơn về các mẫu sau.
GO TO FULL VERSION