Yöntem çağrısını veya yöntemin kendisini korumak daha mı iyi?


12

Bir başvuru yazıyorum ve şu noktaya geldim:

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

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

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Bu oldukça basit görünüyor. Bazı koşullar vardır ve eğer doğrularsa yöntemler çağrılır. Ancak, böyle yapmak daha iyi mi diye düşünüyordum:

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

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

    ...
}

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

    ...
}

İkinci durumda, yöntemlerin her biri kendini korur, bu nedenle bu yöntemlerden herhangi biri GiveApplesveya GiveBananasdışarıdan SomeMethodçağrılsa bile, yalnızca Ayarlar'da doğru bayrağı varsa yürütüleceklerdir.

Bu aslında bir sorun olarak düşünmem gereken bir şey mi?

Mevcut bağlamımda, bu iki yöntemin bu yöntemin dışından çağrılması pek olası değildir, ancak hiç kimse bunu garanti edemez.


5
Öncelikle kontrol etmeden GiveApples veya GiveBananas'ı çağırmanız gerekip gerekmediğine bağlıdır. Muhafız yöntemle ilişkilendirildiğinden, muhtemelen yönteme aittir.
Robert Harvey

Yanıtlar:


13

Muhafızları yöntemin uyması gereken bir şey olarak düşünüyorum . Örneğin, Settings.GiveApples yanlışsa yöntem elma vermemelidir.

Durum buysa, bekçi kesinlikle yönteme aittir. Bu, önce korumaları kontrol etmeden yanlışlıkla uygulamanızın başka bir noktasından çağırmanızı önler.

Diğer yandan, ayarlar yalnızca çağrı yöntemine uygulanırsa ve kodunuzdaki başka bir yöntem, ayardan bağımsız olarak GiveApples'i verebilirse, bu bir koruma değildir ve muhtemelen çağrı kodunda olmalıdır.


5

Korumayı yöntemin içine yerleştirin. Muhafızlarının tüketicisi GiveApples()veya GiveBananas()bunlardan sorumlu olmamalıdır GiveApples().

Tasarım açısından bakıldığında SomeMethod(), sadece meyveye ihtiyacı olduğunu bilmeli ve uygulamanızın bunu elde etmek için ne yapması gerektiğine dikkat etmemelidir. SomeMethod()Belirli bir meyvenin alınmasına izin veren küresel bir ortamın olduğunu bilmekle sorumluysa , meyve alımının soyutlanması sızıntı yapar . Bu, yeni mekanizmayı uygulamak için ayrı olarak yeniden ayarlanması gereken GetApples()veya GetBananas()yeniden yapılması gereken tüm yöntemler olduğu gibi, koruma mekanizmanız hiç değişmezse kademelendirilir. Ayrıca kod yazarken bu çek olmadan meyveleri unutmak ve denemek çok kolaydır.

Bu senaryoda dikkate almanız gereken şey, Ayarlar uygulamanızın meyve vermesine izin vermediğinde uygulamanızın nasıl tepki vermesi gerektiğidir.


4

Genellikle, harici olarak sağlanan ayarlar ve "temel işletme kodu" gibi bir şeyi test etme sorumluluğunu ayırmak genellikle iyi bir fikirdir GiveApples. Öte yandan, birbirine ait olanları bir araya toplayan fonksiyonlara sahip olmak da iyi bir fikirdir. Kodunuzu aşağıdaki gibi yeniden düzenleyerek her iki hedefi de gerçekleştirebilirsiniz:

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()
{
    ...
}

Bu , sınıfın herhangi bir bağımlılığı olmaksızın kodunu GiveApplesve / veya GiveBananasayrı bir yere yeniden düzenleme şansı verir Settings. Bu yöntemleri, hiç kimsenin umurunda olmayan bir birim testinde çağırmak istediğinizde açıktır Settings.

Ancak, programınızda her zaman yanlışsa, herhangi bir koşulda, bir test bağlamında bile, ilk önce kontrol edilen GiveApplesbir bağlamın dışında gibi bir şey çağırmak Settings.GiveApplesve sadece çek GiveApplesolmadan Settingshataya eğilimli gibi bir işlev sağlama konusunda izlenim altındasınız. , Settings.GiveApplesiçinde test ettiğiniz değişkene sadık kalın GiveApples.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.