Penugasan boolean praktik terbaik [ditutup]


10

Saya menemukan persyaratan berikut dalam program yang telah saya ambil dari pengembang lain:

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

Saya percaya kode ini berlebihan dan jelek, jadi saya mengubahnya menjadi apa yang saya pikir merupakan tugas boolean sederhana berdasarkan perbandingan:

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE;

Setelah melihat ini, seseorang meninjau kode saya berkomentar bahwa meskipun perubahan saya secara fungsional benar, itu mungkin membingungkan orang lain yang melihatnya. Dia percaya bahwa menggunakan operator ternary membuat penugasan ini lebih jelas, sedangkan saya tidak suka penambahan kode yang lebih berlebihan:

obj.NeedsChange = (obj.Performance <= LOW_PERFORMANCE) ? true : false;

Alasannya adalah bahwa melakukan sesuatu dengan cara yang paling singkat tidak sepadan, jika itu menyebabkan pengembang lain harus berhenti dan mencari tahu apa yang telah Anda lakukan.

Pertanyaan sebenarnya di sini adalah mana dari tiga metode ini memberikan nilai ke boolean obj.NeedsChangeyang paling jelas dan paling bisa dipertahankan?


25
Bentuk ketiga adalah konyol; itu hanya menyatakan apa yang seharusnya sudah jelas terlihat dalam bentuk kedua.
Robert Harvey

6
Ini sepenuhnya terserah preferensi pribadi. Kita bisa berpura-pura sebaliknya, tetapi karena mereka semua secara fungsional setara, itu bermuara pada gaya . Tentu, ada perbedaan dalam keterbacaan, tetapi "terbaca dan transparan" saya mungkin "tumpul dan buram"
MetaFight

3
@scriptin 5-8 baris v 1 baris lebih dari preferensi, 5-8 liner biasanya lebih jelas dan lebih baik untuk itu. Dalam contoh sederhana ini, saya lebih suka 1 baris, tetapi secara umum saya telah melihat terlalu banyak 10 liner yang dikaburkan menjadi 1-liner untuk kenyamanan. Mengingat itu, saya tidak pernah mengeluh tentang varian 1, mungkin tidak cantik tetapi melakukan pekerjaan dengan jelas dan jelas.
gbjbaanb

4
Opsi 1 dan 3 mengatakan kepada saya "Penulis tidak benar-benar mengerti logika boolean".
17 dari 26

2
Varian 1 mungkin berguna jika Anda perlu sering menetapkan breakpoint yang tergantung pada nilainya.
Ian

Jawaban:


39

Saya lebih suka 2, tapi saya bisa melakukan sedikit penyesuaian untuk itu:

obj.NeedsChange = ( obj.Performance <= LOW_PERFORMANCE );

Bagi saya tanda kurung membuat garis lebih mudah diurai dan membuatnya sekilas jelas bahwa Anda menetapkan hasil perbandingan, dan tidak melakukan penugasan ganda. Saya tidak yakin mengapa itu (karena saya tidak bisa memikirkan bahasa di mana tanda kurung sebenarnya akan mencegah penugasan ganda), tetapi jika Anda harus memuaskan pengulas Anda maka mungkin ini akan menjadi kompromi yang dapat diterima.


4
ini adalah jawaban yang benar - meskipun kode dalam pertanyaan itu benar, menambahkan tanda kurung tidak memberitahu pembaca bahwa itu bukan tugas. Jika Anda dengan cepat mencari melalui kode, tanda kurung memberi Anda info tambahan instan yang menghentikan Anda melihat lebih dekat untuk melihat apakah kode itu dimaksudkan seperti itu, dan bukan bug yang tidak disengaja. Misalnya, bayangkan barisnya a = b == c, maksud Anda menetapkan bool atau maksud Anda menetapkan c untuk b dan a.
gbjbaanb

Kurung akan mencegah penugasan ganda di Python. Bahkan dalam bahasa di mana mereka tidak mencegah penugasan ganda, tanda kurung jelas membantu menunjukkan bahwa Anda berurusan dengan dua jenis operasi.
user2357112 mendukung Monica

23

Varian 1 mudah dipahami, tetapi itulah satu-satunya keunggulannya. Saya secara otomatis berasumsi bahwa siapa pun yang menulis seperti ini tidak benar-benar mengerti tentang boolean, dan akan menulis kode kekanak-kanakan yang serupa dalam banyak hal lainnya.

Varian 2 adalah apa yang akan selalu saya tulis, dan berharap untuk dibaca. Saya pikir siapa pun yang bingung dengan idiom itu tidak boleh menjadi penulis profesional perangkat lunak.

Varian 3 menggabungkan kerugian dari kata 1 dan 2. 'nuff.


Nah, varian 1 berbagi keunggulannya dengan varian 2 ...
Deduplicator

1
+1 untuk kode infantil. Saya telah melihat kode seperti itu selama bertahun-tahun, saya tidak memiliki kata yang tepat untuk mengidentifikasinya.
Lilienthal

1
Asumsi pertama saya dengan kode seperti Varian 1 adalah bahwa dua cabang pada satu titik di masa lalu lebih rumit, dan seseorang tidak memperhatikan ketika refactoring. Namun jika itu bagaimana itu ketika pertama kali ditulis, maka saya setuju dengan "tidak mengerti boolean"
Izkata

13

Kapan saja kode lebih rumit daripada yang harus dipicu sebuah "apa yang seharusnya dilakukan?" bau di pembaca.

Sebagai contoh, contoh pertama membuat saya bertanya-tanya, "adakah fungsi lain di pernyataan if / else di beberapa titik yang telah dihapus?"

Contoh (2) sederhana, jelas, dan melakukan apa yang dibutuhkan. Saya membacanya dan segera mengerti apa yang dilakukan kode.

Kelebihan ekstra dalam (3) akan membuat saya bertanya-tanya mengapa penulis menulisnya seperti itu alih-alih (2). Ada harus menjadi alasan, tetapi dalam kasus ini ada tampaknya tidak menjadi, sehingga tidak membantu sama sekali dan sulit untuk dibaca karena sintaks menunjukkan sesuatu yang hadir yang tidak ada. Mencoba mempelajari apa yang ada (ketika tidak ada) membuat kode lebih sulit dibaca.


2

Sangat mudah untuk melihat bahwa Varian 2 dan Varian 1 terkait melalui serangkaian refactoring yang jelas dan sederhana:

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

Di sini, kami memiliki duplikasi kode yang tidak perlu, kami dapat memfaktorkan tugas:

obj.NeedsChange = if (obj.Performance <= LOW_PERFORMANCE)
{
    true
}
else
{
    false
}

atau ditulis lebih ringkas:

obj.NeedsChange = if (obj.Performance <= LOW_PERFORMANCE) true else false

Sekarang, harus segera jelas bahwa ini akan menetapkan true jika kondisinya benar dan menetapkan false jika kondisinya salah, TKI itu hanya akan menetapkan nilai kondisi, yaitu setara dengan

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE

Varian 1 dan 3 adalah kode rookie khas yang ditulis oleh seseorang yang tidak mengerti apa nilai balik dari perbandingan.


Saya akan menambahkan Anda jika (...) ... bagian yang salah sebagai komentar sebelum yang bagus, maka Anda mendapatkan pemindaian sederhana melalui kejelasan kode dan kode yang lebih baik.
DaveM

2

Sementara pemrograman Anda harus cenderung lebih eksplisit daripada implisit "seolah-olah orang yang akhirnya mempertahankan kode Anda akan menjadi psikopat kejam yang tahu di mana Anda tinggal", Anda dapat mengasumsikan beberapa hal dasar yang menjadi kompeten penerus psiko Anda.

Salah satunya adalah sintaks bahasa yang digunakannya.

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE;

sangat jelas bagi siapa saja yang tahu sintaks C / C ++ / C # / Java / Javascript.

Ini juga jauh lebih mudah dibaca daripada 8 baris.

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

dan kurang rentan terhadap kesalahan

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.Needschange = false;
}

Dan itu lebih baik daripada menambahkan karakter yang tidak perlu, seolah-olah Anda setengah melupakan sintaks bahasa:

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE ? true : false;

obj.NeedsChange = (obj.Performance <= LOW_PERFORMANCE);

Saya pikir ada banyak yang salah tentang sintaksis mirip-C dari banyak bahasa: urutan operasi yang tidak konsisten, asosiasi kiri / kanan yang tidak konsisten, penggunaan simbol yang berlebihan, duplikasi kurung / lekukan, operator ternary, notasi infiks, dll.

Tapi solusinya bukan menciptakan versi milik Anda sendiri. Dengan begitu ada kegilaan, karena setiap orang menciptakan miliknya sendiri.


Secara umum, hal # 1 yang membuat kode Real World TM tidak terbaca adalah jumlahnya.

Antara program 200 jalur non-patologis dan program 1.600 jalur yang identik, yang lebih pendek akan selalu lebih mudah diurai dan dipahami. Saya akan menyambut perubahan Anda setiap hari.


1

Sebagian besar pengembang akan dapat memahami bentuk ke-2 dengan lirikan. Menurut pendapat saya tentang penyederhanaan seperti pada formulir 1 sama sekali tidak perlu.

Anda dapat meningkatkan keterbacaan dengan menambahkan spasi dan kawat gigi seperti:

obj.NeedsChange =    obj.Performance <= LOW_PERFORMANCE;

atau

obj.NeedsChange = ( obj.Performance <= LOW_PERFORMANCE );

seperti yang disebutkan oleh Jacob Raihle.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.