Bao nhiêu logic có thể được đưa vào một lệnh? Hoặc khác nhau: Loại logic nào là mẫu lệnh cho?


8

Tôi đã sử dụng mẫu lệnh trong một thời gian khá lâu nhưng tôi không bao giờ thực sự chắc chắn rằng tôi thực sự có thể đưa bao nhiêu logic vào Executephương thức.

Việc triển khai mẫu lệnh hiện tại của tôi trông tương tự như sau:

public abstract class Command
{
    public static event EventHandler Completed = delegate { };        

    public bool Success { get; private set; }

    public Exception Exception {get; private set; }

    public abstract bool Execute();

    protected bool OnCompleted(bool success, Exception ex = null)
    {       
        Success = success;
        Exception = ex;
        Completed(this, EventArgs.Empty)
        return success;
    }
}

và đây là những câu hỏi mà tôi tự hỏi mình (và thực hành trong các mệnh lệnh của mình):

  1. Có thể hiển thị hộp messege hoặc hộp thoại mở tập tin, vv?
  2. Có thể đặt thuộc tính của bất kỳ đối tượng nào không?
  3. Một lệnh có thể chứa logic kinh doanh?
  4. Một lệnh có thể sửa đổi các điều khiển GUI trong anyway?
  5. Những lệnh lớp nào thuộc về? Xem hoặc lớp dữ liệu? Tôi có thể có các lệnh trong cả hai lớp không?
  6. Một lệnh có thể làm tất cả những gì trước đây là trong button1_Click?
  7. Có nên ra lệnh bằng đơn vị kiểm tra?
  8. Một lệnh có thể được xem như là một người dùng sử dụng API và xây dựng lớp cuối cùng của ứng dụng và cũng là biện pháp cuối cùng để bắt ngoại lệ không?
  9. Các lệnh có thể được thực thi bằng mã (lệnh gọi api, api chạy và cuối cùng một số api khác gọi lệnh) hoặc chỉ người dùng có thể gọi nó và API không được biết về sự tồn tại?
  10. Có chỗ nào cho các lệnh trong MVC hoặc MVVC hoặc bất kỳ mẫu thiết kế nào khác với bộ điều khiển không? Họ dường như là loại trừ lẫn nhau. Cái gì thích hơn?

Có rất nhiều hướng dẫn chỉ ra cách thực hiện mẫu lệnh nhưng không thực sự thảo luận về cách áp dụng nó trong một ứng dụng wold thực sự.

Câu trả lời:


7

Mẫu lệnh thường được sử dụng để tách rời WHAT từ WHO và WHAT từ WHEN. Đây là lợi ích của việc có một giao diện đơn giản đơn giản như:

public abstract class Command {
    public abstract void execute();
}

Hãy tưởng tượng rằng bạn có một lớp học EngineOnCommand. Bạn có thể truyền Lệnh này cho các đối tượng khác chấp nhận các thể hiện của Lệnh. Vì vậy, điều này có nghĩa là lớp nhận EngineOnCommand này, cũng có thể nhận được một Lệnh khác được thực thi bởi nó và nó không bao giờ nên biết. Điều này có nghĩa là bạn đã tách rời CÁI GÌ từ WHO .

Bây giờ, trường hợp thứ hai cho Command Patterm là tách rời CÁI GÌ từ KHI . Hãy tưởng tượng rằng bạn muốn tạo một hệ thống trong đó các hành động trong Cơ sở dữ liệu chỉ nên được thực hiện vào ban đêm, nhưng tuân theo trình tự mà chúng được yêu cầu. Với một hàng các Lệnh trong đó bạn có thể thực thi từng cái một, bạn có thể đạt được điều này. Ý tưởng là việc gọi lệnh thực sự chỉ kích hoạt một lệnh của lệnh trong danh sách sẽ được thực hiện sau đó.

Tôi hy vọng các ví dụ của tôi ở trên sẽ giúp hiểu ý tưởng của mẫu là gì. Bây giờ tôi sẽ cố gắng trả lời một số câu hỏi của bạn bằng cách sử dụng ở trên làm cơ sở.

Một lệnh có thể chứa logic kinh doanh?

vâng, tôi tin rằng nó nên chứa nó Nó sẽ chứa nó theo cách tách rời của WHO và KHI NÀO.

Một lệnh có thể sửa đổi các điều khiển GUI trong anyway?

Điều này có nghĩa là bạn đang ghép nó với GUI. Điều này có nghĩa là nó không được sử dụng cho mục đích tách rời CÁI GÌ từ WHO. Lệnh lý tưởng không nên biết ai đang gọi nó, nếu đó là GUI hoặc chức năng hàng loạt.

Có nên ra lệnh bằng đơn vị kiểm tra?

Nó không nên, nó phải là đơn vị thử nghiệm . Tất cả các mã phải là đơn vị có thể kiểm tra được, nhưng lý tưởng là tất cả các lệnh phải là đơn vị kiểm tra được.

Xin lỗi vì đã không trả lời tất cả các câu hỏi của bạn, nhưng tôi tin rằng bạn nên kiểm tra sách GOF . Nó chứa một số ví dụ tốt.


+1 Câu trả lời tuyệt vời, mặc dù là một câu đố nhỏ: Vận động cho một thực hành nhất định như kiểm tra đơn vị là rất tốt, nhưng chỉ huy những thực hành đó như thể chúng là bắt buộc phổ biến có xu hướng không hữu ích cho các lập trình viên trẻ. Nói từ kinh nghiệm.
Phil

2

Hầu hết lợi ích của các lệnh là chúng giúp dễ dàng hoàn tác một hành động, làm lại một hành động, thực hiện một hành động ở nhiều nơi (qua kết nối mạng) hoặc thực hiện nó vào một ngày sau đó, v.v.

Với ý nghĩ đó:

  1. Chắc là không. Thật khó để tưởng tượng bất kỳ tình huống nào trong đó "hoàn tác" một hộp thoại có ý nghĩa và đây là loại điều tôi muốn đặt vào mã UI.

  2. Miễn là đối tượng đó có thể truy cập từ mọi nơi có thể muốn thực thi lệnh, thì dĩ nhiên việc thay đổi thuộc tính của nó là điều tốt.

  3. Chắc chắn rồi. Điều này liên quan đến việc mô hình của bạn có nên "chứa" logic kinh doanh hay không; nó thực sự được coi là một mô hình chống ("mô hình miền thiếu máu") có quá ít logic kinh doanh trong đó.

  4. Nếu các điều khiển GUI là một phần của mô hình của bạn, hoàn toàn. Nếu không, nó là nghi vấn.

  5. Chắc chắn không phải là xem. Quan điểm cần được thông báo rằng dữ liệu hoặc mô hình đã thay đổi và phản ứng tương ứng, nhưng thay đổi thực tế sẽ diễn ra trong dữ liệu hoặc mô hình.

  6. Về nguyên tắc, có lẽ là có. Có thể hoàn tác các lệnh là một trong những điều tốt nhất về mẫu.

  7. Hàm exec () của lệnh chắc chắn phải được kiểm tra đơn vị. Một lần nữa, nếu các lệnh được gắn với một mô hình nào đó, chúng là một trong những phần dễ nhất của ứng dụng để kiểm tra.

  8. Tôi không chắc ý của bạn là gì, nhưng:

    • Việc API bên ngoài sử dụng các lệnh làm đầu vào hoặc đầu ra là hoàn toàn tốt. Tất nhiên, giả sử bạn xác nhận chúng.
    • "Lớp cuối cùng" nghe giống như Xem với tôi. Trong MVC, các lệnh có thể được tạo bởi bộ điều khiển và được xử lý bởi mô hình, do đó, có thể nói rằng khung nhìn được xây dựng "bên trên" các công cụ lệnh, nếu đó là những gì bạn đang làm.
    • Đối với trường hợp ngoại lệ, có lẽ không. Trong MVC, tôi hy vọng bộ điều khiển sẽ là một ngoại lệ bắt được và biến chúng thành loại hộp thoại phù hợp. Không phải mô hình / lệnh.
  9. Chắc chắn rồi. Hầu hết các lợi ích của các lệnh là không thể thực hiện nếu mã không bao giờ thực thi chúng.

  10. Bây giờ có lẽ rõ ràng, nhưng tôi không thấy chúng là loại trừ lẫn nhau. Trong nhóm của tôi tại nơi làm việc, bộ điều khiển chuyển các sự kiện do người dùng tạo thành các lệnh, mô hình nhận và thực hiện các lệnh (và lưu các lệnh "hoàn tác" ở đâu đó) và khi hoàn thành, bộ điều khiển sẽ báo cho chế độ xem tự cập nhật dựa trên mô hình mới . Các lệnh cũng được gửi qua mạng tới bất kỳ bản sao nào của mô hình đang được người dùng khác xem, vì vậy họ cũng thấy nó. Nó hoạt động rực rỡ.

Và câu hỏi tiêu đề: Bao nhiêu logic để đặt trong một lệnh? Tôi sẽ không đặt bất kỳ tối thiểu hoặc tối đa cho nó. Điều tôi muốn nói là đó là một ý tưởng rất hay để thực hiện các lệnh phức tạp hơn bằng cách sử dụng một loạt các lệnh đơn giản hơn và các lệnh tái cấu trúc giống như cách bạn tái cấu trúc các hàm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.