Memperkenalkan variabel lokal tambahan sebagai pengganti komentar

12

Apakah gaya yang baik untuk menggunakan variabel lokal tambahan yang secara teknis berlebihan untuk menggambarkan apa yang terjadi?

Sebagai contoh:

bool easyUnderstandableIsTrue = (/* rather cryptic boolean expessions */);

if(easyUnderstandableIsTrue)
{
    // ...
}

Ketika datang ke overhead teknis saya berharap kompiler untuk mengoptimalkan baris tambahan ini pergi. Tetapi apakah ini dianggap sebagai kode yang tidak perlu? Di mata saya itu mengurangi risiko komentar basi.

BooleanAssange
sumber
10
"Apakah gaya yang baik untuk menggunakan variabel lokal tambahan, secara teknis berlebihan, untuk menggambarkan apa yang terjadi?" Iya. Tidak banyak lagi yang bisa dikatakan di sini, sungguh.
David Arno
3
Saya menemukan gaya seperti itu (yaitu menggunakan banyak variabel perantara dengan nama deskriptif) cukup membantu ketika membaca kode saya nanti. Tentu saja Anda dapat menulis ekspresi kompleks dan menyimpan beberapa nama dengan tidak memperkenalkan variabel perantara, tetapi mengapa Anda mau? Membaca kode bisa menjadi tantangan yang cukup besar walaupun itu ditulis dengan relatif baik, jadi saya rasa tidak perlu menyulitkannya lebih merupakan rute yang masuk akal.
Mael
Saya percaya ini disebut Ekspresi Bersyarat Konsolidasi dalam katalog refactoring Martin Fowler .
Brandin

Jawaban:

16

Berapa biaya memiliki variabel tambahan? Di sebagian besar bahasa, tidak ada, keduanya dalam bahasa yang dikompilasi dan ditafsirkan.

Apa manfaatnya ini?

  • Demikian pula untuk mengekstraksi ekspresi boolean samar ke metode terpisah, Anda mengurangi risiko kode duplikat , tetapi sedikit kurang dari dalam kasus metode terpisah. Jika ekspresi kondisional digunakan kembali di dalam metode itu sendiri, Anda akan dapat menggunakan kembali variabel; jika ekspresi muncul dalam metode yang berbeda, Anda tidak akan melakukannya.

    Perhatikan bahwa kecuali jika bahasa pemrograman Anda memungkinkan Anda untuk memiliki variabel lokal yang tidak dapat diubah atau Anda memiliki cara untuk menegakkan, berdasarkan gaya, bahwa tidak ada variabel yang dipindahkan, refactoring tersebut dapat berisiko dalam jangka panjang. Jika nilai variabel diubah, bisa jadi sangat sulit untuk berpikir tentang kode tersebut.

  • Anda mengurangi risiko dokumentasi tidak sinkron dengan kode . Pengembang cenderung memperbarui nama-nama variabel dan metode lebih mudah daripada komentar. ¹ Dengan demikian, tidak biasa melihat kode seperti:

    // Find if the user is an actual author in order to allow her to edit the message.
    if (currentUser.isAdministrator || (message.author == currentUser && !message.locked))

Ekspresi mungkin dimulai dengan if (message.author == currentUser), dan kemudian berevolusi untuk menangani kasus pesan terkunci dan administrator yang tidak perlu menjadi penulis dan tidak peduli dengan hal-hal yang terkunci; Namun, komentar tersebut belum mencerminkan perubahan tersebut.

Kedua manfaat itu tidak terlalu penting, tetapi mengingat rendahnya biaya variabel tambahan, Anda mungkin memang mempertimbangkan untuk menggunakannya.

Perhatikan bahwa jika ekspresi boolean Anda menjadi terlalu rumit: ²

  • Ekstrak ke metode yang terpisah , dan:
  • Ubah menjadi beberapa ekspresi boolean sederhana.

Contoh di atas menjadi:

class Message
{
    ...
    public boolean canBeEditedBy(User user)
    {
        ...
        if (user.isAdministrator) {
            return true;
        }

        return this.author == user && !this.locked;
    }
}

...
if (message.canBeEditedBy(currentUser)) // See? Much more readable now!
{
    ...
}

¹ Sumber: pengamatan saya sendiri terhadap rekan-rekan saya yang sebagian besar mengembangkan perangkat lunak bisnis; YMMV. Penelitian nyata dapat menunjukkan hasil yang berbeda. Secara pribadi, saya kira bahwa ketika pengembang membaca kode, mereka berfokus pada kode , dan komentar adalah dokumentasi, bukan kode; oleh karena itu, mereka biasanya tidak membaca komentar, sehingga akan sulit untuk mengharapkan mereka memperbaruinya.

² Ambang batas yang terlalu rumit didefinisikan dengan rumus sederhana: jika setengah dari pengembang yang meninjau kode Anda menyatakan niat membunuh Anda, ambang tersebut tercapai. Ekspresi boolean di atas cukup sederhana untuk memerlukan refactoring; namun, empat bagian berturut-turut if ((a && b) || (c && d))akan membuatnya berpotensi dapat bereaksi kembali. Perhatikan bahwa jika ekspresi datar, jumlah bagian sebagian besar tidak relevan: if (a || b || c || d || ... || z)cukup mudah dibaca.

Arseni Mourzenko
sumber