Thật buồn cười, câu hỏi này chỉ khiến tôi nhớ lại chính xác cuộc trò chuyện tôi có với một trong những kỹ sư của chúng tôi về thư viện liên lạc mà tôi đang làm việc.
Thay vì các lệnh, tôi có các lớp Request và sau đó tôi có RequestHandlers. Thiết kế rất giống với những gì bạn đang mô tả. Tôi nghĩ một phần của sự nhầm lẫn mà bạn có là bạn thấy từ "lệnh" trong tiếng Anh và ngay lập tức nghĩ "động từ, hành động ... vv".
Nhưng trong thiết kế này, hãy nghĩ về Command (hoặc Request) như một chữ cái. Hoặc đối với những người không biết dịch vụ bưu chính là gì, hãy nghĩ e-mail. Nó chỉ đơn giản là nội dung, tách rời khỏi cách thức nội dung đó nên được hành động.
Tại sao bạn sẽ làm điều này? Trong hầu hết các trường hợp đơn giản, Mẫu lệnh không có lý do và bạn có thể yêu cầu lớp này thực hiện công việc trực tiếp. Tuy nhiên, thực hiện việc tách rời như trong thiết kế của bạn có ý nghĩa nếu hành động / lệnh / yêu cầu của bạn phải di chuyển một khoảng cách. Ví dụ: qua, ổ cắm hoặc đường ống, hoặc giữa tên miền và cơ sở hạ tầng. Hoặc có thể trong kiến trúc của bạn, các lệnh của bạn cần phải được duy trì (ví dụ: trình xử lý lệnh có thể thực hiện 1 lệnh một lần, do một số sự kiện hệ thống, 200 lệnh đến và sau 40 quá trình đầu tiên bị tắt). Trong trường hợp đó, có một lớp chỉ có thông báo đơn giản, việc tuần tự hóa phần chỉ thành JSON / XML / binary / bất cứ thứ gì và chuyển nó xuống đường ống cho đến khi trình xử lý lệnh của nó sẵn sàng để xử lý nó.
Một ưu điểm khác của việc tách lệnh từ CommandHandler là bây giờ bạn có tùy chọn phân cấp kế thừa song song. Ví dụ, tất cả các lệnh của bạn có thể xuất phát từ một lớp lệnh cơ sở hỗ trợ tuần tự hóa. Và có thể bạn có 4 trong số 20 trình xử lý lệnh có nhiều điểm tương đồng, bây giờ bạn có thể lấy được chúng từ lớp cơ sở xử lý đã đến. Nếu bạn có dữ liệu và xử lý lệnh trong một lớp, loại mối quan hệ này sẽ nhanh chóng vượt khỏi tầm kiểm soát.
Một ví dụ khác cho việc tách rời sẽ là nếu lệnh của bạn yêu cầu rất ít đầu vào (ví dụ 2 số nguyên và một chuỗi) nhưng logic xử lý của nó đủ phức tạp để bạn muốn lưu trữ dữ liệu trong các biến thành viên trung gian. Nếu bạn xếp hàng 50 lệnh, bạn không muốn phân bổ bộ nhớ cho tất cả bộ lưu trữ trung gian đó, vì vậy bạn tách Command khỏi CommandHandler. Bây giờ bạn xếp hàng 50 cấu trúc dữ liệu trọng lượng nhẹ và lưu trữ dữ liệu phức tạp hơn chỉ được phân bổ một lần (hoặc N lần nếu bạn có N xử lý) bởi CommandHandler đang xử lý các lệnh.