Apakah lebih baik menjaga panggilan metode atau metode itu sendiri?

12

Saya sedang menulis aplikasi dan saya sampai pada titik ini:

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

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

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Ini terlihat sangat mudah. Ada beberapa kondisi dan jika itu benar metode tersebut dipanggil. Namun, saya berpikir, apakah lebih baik melakukan seperti ini:

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

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

    ...
}

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

    ...
}

Dalam kasus kedua, masing-masing metode menjaga dirinya sendiri, jadi bahkan jika salah satu metode GiveApplesatau GiveBananasdipanggil dari luar SomeMethod, mereka akan dieksekusi hanya jika mereka memiliki tanda yang benar di Pengaturan.

Apakah ini sesuatu yang seharusnya saya anggap sebagai masalah?

Dalam konteks saya saat ini, sangat tidak mungkin kedua metode tersebut akan dipanggil dari luar metode ini, tetapi tidak ada yang bisa menjamin itu.

Nikola
sumber
5
Itu tergantung pada apakah Anda mungkin perlu menelepon GiveApples atau GiveBananas tanpa memeriksa terlebih dahulu. Karena penjaga dikaitkan dengan metode, itu mungkin termasuk dalam metode.
Robert Harvey

Jawaban:

13

Saya menganggap penjaga sebagai sesuatu yang harus dipatuhi metode ini . Dalam contoh Anda, metode ini tidak boleh memberikan apel jika Settings.GiveApples salah.

Jika itu yang terjadi maka penjaga pasti termasuk dalam metode. Ini mencegah Anda secara tidak sengaja memanggilnya dari titik lain di aplikasi Anda tanpa memeriksa penjaga terlebih dahulu.

Di sisi lain jika pengaturan hanya berlaku untuk metode panggilan, dan metode lain di tempat lain dalam kode Anda dapat memberikan aplikasi terlepas dari pengaturan maka itu bukan penjaga dan mungkin harus dalam kode panggilan.

Jeremy Hutchinson
sumber
5

Tempatkan penjaga dalam metode itu sendiri. Konsumen GiveApples()atau GiveBananas()tidak seharusnya bertanggung jawab untuk mengelola penjaga GiveApples().

Dari sudut pandang desain SomeMethod()seharusnya hanya tahu bahwa itu membutuhkan buah dan tidak harus peduli tentang apa yang perlu dilakukan aplikasi Anda untuk mendapatkannya. Abstraksi pengambilan buah menjadi bocor jika SomeMethod()bertanggung jawab untuk mengetahui bahwa ada pengaturan global yang memungkinkan pengambilan buah tertentu. Ini mengalir jika mekanisme penjaga Anda pernah berubah, seperti sekarang semua metode yang perlu GetApples()atau GetBananas()perlu di refactored secara terpisah untuk menerapkan penjaga baru ini. Juga sangat mudah untuk mencoba dan mendapatkan buah tanpa tanda saat Anda menulis kode.

Apa yang harus Anda pertimbangkan dalam skenario ini adalah bagaimana aplikasi Anda harus bereaksi ketika Pengaturan tidak memungkinkan aplikasi Anda memberi hasil.

ravibhagw
sumber
4

Secara umum, sering kali merupakan ide yang baik untuk memisahkan tanggung jawab pengujian sesuatu seperti pengaturan yang disediakan secara eksternal, dan "kode bisnis inti" seperti GiveApples. Di sisi lain, memiliki fungsi yang mengelompokkan bersama apa yang menjadi milik bersama juga merupakan ide bagus. Anda dapat mencapai kedua sasaran dengan refactoring kode Anda seperti ini:

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

Ini memberi Anda kesempatan lebih baik untuk memperbaiki kode GiveApplesdan / atau GiveBananaske tempat yang terpisah tanpa ketergantungan dari Settingskelas. Itu jelas menguntungkan ketika Anda ingin memanggil metode-metode itu dalam suatu unit test yang tidak mempedulikannya Settings.

Namun, jika itu selalu salah dalam program Anda, dalam keadaan apa pun, bahkan dalam konteks pengujian, untuk memanggil sesuatu seperti di GiveApplesluar konteks di mana Settings.GiveApplesdiperiksa terlebih dahulu, dan Anda mendapat kesan hanya menyediakan fungsi seperti GiveApplestanpa Settingspemeriksaan itu rawan kesalahan. , lalu tempel ke varian tempat Anda menguji Settings.GiveApplesbagian dalam GiveApples.

Doc Brown
sumber