Là tốt hơn để bảo vệ cuộc gọi phương thức hoặc chính phương thức?


12

Tôi đang viết một ứng dụng và tôi đã đến điểm này:

private void SomeMethod()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }

    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Điều này có vẻ khá đơn giản. Có một số điều kiện và nếu chúng đúng, các phương thức đang được gọi. Tuy nhiên, tôi đã suy nghĩ, tốt hơn là làm như thế này:

private void SomeMethod()
{
    GiveApples();
    GiveBananas();
}

private void GiveApples()
{
    if (!Settings.GiveApples)
    {
        return;
    }

    ...
}

private void GiveBananas()
{
    if (!Settings.GiveBananas)
    {
        return;
    }

    ...
}

Trong trường hợp thứ hai, mỗi phương thức bảo vệ chính nó, vì vậy ngay cả khi bất kỳ phương thức nào GiveAppleshoặc GiveBananasđược gọi từ bên ngoài SomeMethod, chúng sẽ chỉ được thực thi nếu chúng có cờ chính xác trong Cài đặt.

Đây có phải là một cái gì đó mà tôi thực sự nên coi là một vấn đề?

Trong bối cảnh hiện tại của tôi, rất khó có khả năng hai phương thức đó sẽ được gọi từ bên ngoài phương thức này, nhưng không ai có thể đảm bảo điều đó.


5
Nó phụ thuộc vào việc bạn có bao giờ cần gọi GiveApples hoặc GiveBananas mà không cần kiểm tra trước hay không. Vì bảo vệ được liên kết với phương thức, nó có thể thuộc về phương thức.
Robert Harvey

Câu trả lời:


13

Tôi nghĩ về những người bảo vệ như một cái gì đó phương pháp phải tuân theo. Trong ví dụ của bạn, phương thức không được cung cấp táo nếu Settings.GiveApples là sai.

Nếu đó là trường hợp thì bảo vệ chắc chắn thuộc về phương pháp. Điều này ngăn bạn vô tình gọi nó từ một điểm khác trong ứng dụng của bạn mà không kiểm tra các vệ sĩ trước.

Mặt khác, nếu cài đặt chỉ áp dụng cho phương thức gọi và một phương thức khác ở đâu đó trong mã của bạn có thể GiveApples bất kể cài đặt thì đó không phải là bảo vệ và có lẽ nên có trong mã gọi.


5

Đặt bảo vệ trong chính phương thức. Người tiêu dùng GiveApples()hoặc GiveBananas()không nên chịu trách nhiệm quản lý các vệ sĩ của GiveApples().

Từ quan điểm thiết kế SomeMethod()chỉ nên biết rằng nó cần trái cây và không nên quan tâm đến những gì ứng dụng của bạn cần làm để có được nó. Sự trừu tượng của việc thu hồi trái cây trở nên rò rỉ nếu SomeMethod()chịu trách nhiệm biết rằng có một môi trường toàn cầu cho phép thu hồi một số loại trái cây nhất định. Thác này nếu cơ chế bảo vệ của bạn từng thay đổi, vì bây giờ tất cả các phương thức cần GetApples()hoặc GetBananas()cần được cấu trúc lại riêng để thực hiện bảo vệ mới này. Bạn cũng rất dễ dàng quên và thử trái cây mà không cần kiểm tra khi bạn đang viết mã.

Điều bạn nên xem xét trong kịch bản này là cách ứng dụng của bạn sẽ phản ứng khi Cài đặt không cho phép ứng dụng của bạn cho trái cây.


4

Nói chung, thường là một ý tưởng tốt để phân tách trách nhiệm kiểm tra một cái gì đó như cài đặt được cung cấp bên ngoài và "mã doanh nghiệp cốt lõi" như thế nào GiveApples. Mặt khác, có các chức năng nhóm lại những gì thuộc về nhau cũng là một ý tưởng tốt. Bạn có thể hoàn thành cả hai mục tiêu bằng cách cấu trúc lại mã của mình như thế này:

private void SomeMethod()
{
    GiveApplesIfActivated();
    GiveBananasIfActivated();
}

private void GiveApplesIfActivated()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }
}

private void GiveBananasIfActivated()
{
    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Điều này cho bạn cơ hội tốt hơn để cấu trúc lại mã GiveApplesvà / hoặc GiveBananasvào một nơi riêng biệt mà không có bất kỳ sự phụ thuộc nào từ Settingslớp. Điều đó rõ ràng có lợi khi bạn muốn gọi các phương thức đó trong một bài kiểm tra đơn vị mà không quan tâm đến bất kỳ Settings.

Tuy nhiên, nếu chương trình của bạn luôn bị sai, trong mọi trường hợp, ngay cả trong ngữ cảnh thử nghiệm, hãy gọi một cái gì đó như GiveApplesbên ngoài bối cảnh Settings.GiveApplesđược kiểm tra trước và bạn có ấn tượng chỉ cung cấp một chức năng như GiveAppleskhông có Settingskiểm tra là dễ bị lỗi , sau đó dính vào biến thể mà bạn kiểm tra Settings.GiveApplesbên trong GiveApples.

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.