Cara yang paling mudah dibaca untuk memformat panjang jika kondisinya? [Tutup]

43

ifKondisi yang berliku panjang harus dihindari jika memungkinkan, namun terkadang kita semua akhirnya menulisnya. Bahkan jika itu adalah kondisi yang sangat sederhana, pernyataan yang terlibat terkadang sangat bertele-tele, sehingga seluruh kondisi menjadi sangat panjang. Apa cara yang paling mudah dibaca untuk memformatnya?

if (FoobarBaz::quxQuux(corge, grault) || !garply(waldo) || fred(plugh) !== xyzzy) {
    thud();
}

atau

if (
    FoobarBaz::quxQuux(corge, grault)
 || !garply(waldo)
 || fred(plugh) !== xyzzy
) {
    thud();
}

atau

if (FoobarBaz::quxQuux(corge, grault)
    || !garply(waldo)
    || fred(plugh) !== xyzzy) {
    thud();
}

atau

thudable = FoobarBaz::quxQuux(corge, grault);
thudable ||= !garply(waldo);
thudable ||= fred(plugh) !== xyzzy;

if (thudable) {
    thud();
}

atau preferensi lain?

menipu
sumber

Jawaban:

30

Seringkali, kondisi lama jika merupakan tanda kode yang perlu refactoring, tetapi kadang-kadang Anda tidak dapat menghindarinya. Dalam kasus itu, saya lebih suka yang pertama:

if (bar || baz || quux) { ... }

Karena Anda dapat mengetahui apa yang terjadi dengan satu baris. Namun, saya lebih suka melakukan sesuatu seperti ini, jika memungkinkan:

function foo() {
  return bar || baz || quux;
}

if (foo()) { ... }
Dorian
sumber
3
bergulir ke samping vs vertikal hampir tidak terbatas pada masa lalu yang buruk ...
Bill
2
dan berikan nama yang bermakna (bisnis) ke fungsi tersebut sehingga orang mengerti apa yang diuji di sini.
Matthieu M.
19

Saya suka menjaga operator di akhir untuk menunjukkan kelanjutan:

if (the_function_being_called() != RETURNCODE_SUCCESS &&
    the_possibly_useful_recovery_strategy() == RETURNCODE_EPICFAIL &&
    this_user_has_elected_to_recieve_error_reports)
{
    report_error();
}
ASHelly
sumber
1
Saya pikir saya suka yang ini. Saya menggunakan banyak tanda kurung untuk memastikan saya dapat memahami urutan prioritas juga.
Jasarien
5
Saya lebih suka menempatkan operator logis pada awal baris sehingga ketika saya membaca baris saya dapat dengan mudah melihatnya adalah bagian dari kondisional dan bukan hanya baris kode biasa.
11

Saya penggemar nama variabel yang berarti:

const bool isInAStrangeCondition =
    FoobarBaz::quxQuux(corge, grault) ||
    !garply(waldo) ||
    fred(plugh) !== xyzzy;

if (isInAStrangeCondition) {
    thud();
}

Atau refactor sebagai fungsi, seperti yang disebutkan di atas.

Program Lenny
sumber
7

Saya memecahkan subekspresi yang berantakan, atau semuanya, sebagai variabel bool. Kemudian logika boolean tingkat atas dari pernyataan 'jika' dapat dibuat jelas. Dalam jenis pekerjaan yang saya lakukan, tidak selalu ada beberapa hal ORed atau ANDed.

bool goodblah = some_mess < whatever;
bool frobnacious = messy_crud != junky_expression;
bool yetanother = long_winded_condition;

if (goodblah || (frobnacious && yetanother))   {
    ...
}

Ini sangat bagus di debugger, di mana saya bisa melihat semua bools sebelum menjalankan 'jika'.

DarW
sumber
Saya suka ini juga, tetapi Anda kehilangan satu manfaat: tidak lagi mungkin untuk melakukan hubungan pendek perbandingan mahal.
... Dan Anda harus pandai menamai banyak variabel setiap hari ...
cronvel
6

Saya cenderung untuk menyelaraskan operator pada awal baris baru jadi saya ingat bagaimana saya menggabungkan istilah (baik untuk logika panjang dan aritmatika panjang). Seperti ini:

if (first_attempt(data) == SUCCESS
    || (reusable(data) && second_attempt(data) == SUCCESS)
    || (still_reusable(data) && third_attempt(data) == SUCCESS))
  return SUCCESS;

Ini hanya berfungsi jika saya membuat indentasi dengan 2 spasi atau mengatur setel lingkungan saya ke indentasi multiline lebih banyak, atau kalau tidak akan sulit untuk mengetahui di mana predikat berakhir dan kode yang berguna dimulai.

Hoa Long Tam
sumber
0

Saya penggemar berikut ini:

if (really_long_expression && another_really_really_long_expression && 
            another_very_long_expression_OMG_id_it_long){
    bugs();
}

Dengan cara ini, ia masih terlihat seperti ekspresi if dan bukan ekspresi yang dipecah-pecah. Lekukan membantu dalam menunjukkan bahwa itu merupakan kelanjutan dari baris sebelumnya.

Anda juga bisa memasukkannya sampai braket pembuka berada di akhir baris sebelumnya sehingga berada di akhir ekspresi if seperti yang seharusnya.

EpsilonVector
sumber
1
Saya sangat menyukai bug Anda () metode: D
Joe Phillips