Bakım açısından akıllıca, 'parantez içine alınmadan güvenli' sayılır mı?


26

Giriş else whileparantezleri olmadan bakımın "güvenli" olduğu düşünülüyor mu?

if-elseAşağıdaki gibi parantez olmadan kod yazma ...

if (blah)
    foo();
else
    bar();

... risk taşır çünkü parantez eksikliği, kodun anlamını istemeden değiştirmeyi çok kolaylaştırır.

Ancak, altında da riskli mi?

if (blah)
{
    ...
}
else while (!bloop())
{
    bar();
}

Yoksa else whilearaya giren parantezler “güvenli” sayılıyor mu?


20
bana göre else whileiğrenç görünüyor. Kullanırdım else { while (condition) { ... } }.
Joachim Sauer

7
Uygun bir cevap için çok öznel olduğunu düşünüyorum ... Orada bir döngü beklemeyeceğimden ve bunu okunabilirliği zorlaştırmayı beklemeyeceğimi düşündüğüm için kendim yapmazdım.
johannes

7
Ben ediyorum yöntemi ayıklamak while-şeyler için
tatarcık

12
Açıkçası, bana sürünür veriyor. ifyalnızca bir kez değerlendirilir, ancak whilebir döngüyü belirtir, bu yüzden her ikisini de bağlamak bana bir ifdöngünün parçası olduğu konusunda ... ... bir şekilde ...
kullanıcı281377,

4
Ve ne olursa elseyapmak istediğiniz maddesi while ve daha bir şeyler yapmak? Sadece diş telleri kullanın lütfen.
Carlos Campderrós

Yanıtlar:


57

Bu bana bu kodu hatırlatıyor:

if ( ... ) try {
..
} catch (Exception e) {
..
} else {
...
}

Her iki bloğu birleştirdiğinizde, diş tellerini unutarak ve girintiyi artırmazsanız, anlaşılması ve bakımı çok zor bir kod yaratırsınız.


18
İyi örnek. Yazmak için ne korkunç bir yol.
Leo,

4
Vay, bu cevap gülünç inandırıcı!
Mehrdad,

Diş teli takma ve girintiyi düzeltme dahil, kaydetme kodunu otomatik olarak formatlamak için modern IDE'leri kolayca ayarlayabilirsiniz. Yani bu sadece yarım argümandır. Düzgün bir şekilde girintili ise, parantez olsun ya da olmasın okunabilirlik için sorun çıkarmaz.
Hans-Peter Störr

55

Muhtemelen bu, Jackson Entity Structure Diagram yöntemini kullanarak işlemimi ( zamanın geri dönüşü) öğrendiğim içindi , ancak bir veya birinden sonra gelen tek doğru doğru olmayan terimin müteakip (yani bir merdivene izin vermek) olduğu görüşüne abone oldum.ifelseifelse if

Başka bir şey (amaçlanan herhangi bir amaç yoktur) yanlış anlama ve / veya bakım sorunları için potansiyel bırakır. OP’lerin fikrinin “güvensiz” olmasının temel yönü budur.

Ben de while()aynı çizgiye dahil olmak konusunda çok cagey olurdum else- kaşlı olsun ya da olmasın. Bana doğru okumuyor ... herhangi bir fazladan girinti maskesinin olmaması, bunun elsefıkra olduğunu gösteriyor. Netlik eksikliği, yanlış anlaşılmalara neden olur (yukarıya bakın).

Bu örnekte, şiddetle tavsiye ediyorum / öneriyorum (ve ekibimde ısrar ediyorum):

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

Tabii ki, ben de uygun yorumlar görmeyi beklerdim.

-- Düzenle --

Son zamanlarda Apple, temassız bir tek satıra ikinci bir satır ekleyen kötü bakım onarımının neden olduğu bir SSL güvenlik açığından muzdaripti. Öyleyse, sıralanmamış tek çizgilerin iyi olduğu fikrini yatalım.


2
Bir başkasını izleyen tek doğru terim olup olmadığına katılıyorum. Eğer bir tane else whileolsaydı, kodun hızlı bir şekilde kaybedilmesinde bir döngü olduğunu bile farketmemiştim, özellikle de aradığım koşul if tarafından karşılandıysa.
Drake Clarris

3
Komik. Herkes her şeyin parantez içinde olup olmadığını okumak için daha kolay olduğunu söylüyor. Aksini doğru buluyorum. Yalnızca bir ifade varsa, onu parantezlerden uzak tutmak okumayı kolaylaştırır. Daha az karışıklık. Bunun nedeni her zaman böyle yaptığım olabilir.
Jeff Davis,

2
@JeffDavis bu iyi bir yakalama. "Okuması daha kolay" yararsız kutsal savaşa tipik bir davetiye. Biri için diş tellerini tercih ediyorum, ancak alakasız "kolay okunan" çöplerden değil (bana göre tam tersi), ancak daha fazla kod bakımını yapmak daha zor çünkü. Yolu OP daha iyi sözkonusu hecelerdi ile: bir else whileparantez müdahale olmadan "güvenli" olarak kabul ?
tatarcık

@JeffDavis - Bu konunun iki yaşında olduğunu biliyorum, ancak Apple kısa süre önce diş tellerinin kullanılmamasının neden iyi bir fikir olmadığını keşfetti. Andrewbanks.com/…
Andrew

@Andrew Bu arada, Apple'ın Swift dili artık tek satırlık akış kontrolünü açıkça yasaklıyor. Bu böcek bunu yapmanın sebeplerinden biri olabilir.
Sulthan,

6

Her zaman her şeyi parantez içinde tutmam, öğrettiğim ve yorum verdiğim öğretildi. Hataları okumak ve tespit etmek çok daha kolay. Şahsen ben modülerliğin anahtar olduğunu düşünüyorum, bu yüzden daima böyle bir kod yazardım:

    if(blah)
    {
     ....
    }
    else
    {
       while(!bloop()
       {
        bar;
       }
    }

6

Ben metodu çıkarır ve yapardım .

if ( blah )
{
    ...
}
else
{
   newMethod();
}

Refactoring Catalogue sitesinde açıklanan "özü yöntemi" yaklaşımına bakın :

Birlikte gruplanabilen bir kod parçanız var.

Parçayı, adı yöntemin amacını açıklayan bir yönteme dönüştürün.

void printOwing() {
    printBanner();

    //print details
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + getOutstanding());
}

                                                                                                         http://www.refactoring.com/catalog/arrow.gif

void printOwing() {
    printBanner();
    printDetails(getOutstanding());
}

void printDetails (double outstanding) {
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + outstanding);
}

Değişir ... örneğin, while döngüsü işlev seviyesi verisi kullanıyorsa, şimdi bu verilere daha fazla modül (veya C ++ kullanıyorsanız sınıf) seviyesine sahip olmanız gerekir. Ve eğer sadece küçük bir kod pasajı varsa, önemsiz yöntemlerle karşı karşıya kalırsınız. Ama bazen şartlara bağlı olarak katılıyorum.
Andrew,

1
+1 Smart C ++ derleyicileri bir işlevi satır içi yapabilir. Net ortamında küçük fonksiyonlar JIT nedeniyle daha iyidir.
İş

4

Kötü bir kodlama alışkanlığı olarak düşünürdüm. Bazen mükemmel çalışıyor ve kodun derlenmesinde ve çalıştırılmasında sorun yaşamayacaksınız. Diğer zamanlarda ciddi hatalara neden olabilir ve bu hatayı düzeltmek için saatlerce harcamanız gerekecektir.

Kodunuzu her zaman modüler hale getirmeniz önerilir. Bir süre döngü başka bir yere koymak zorunda kalırsanız, bir bloğa koyun diğerleri böylece, kod üzerinde çalışırken kolayca mantığı anlayabilir.

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

Kodları bloklara koymak iyi bir uygulamadır. Aynı zamanda anlaşılması ve hata ayıklaması da daha basit ve kolaydır.


4

Bu kadar basit kalırsa kişisel olarak hoşuma gitmese de tercihim iyi olur; tercihim basit if / else kod blokları için bile parantez kullanmaktır. Bu sadece benim için daha düzenli.

Bununla birlikte, bunun dağınık olduğu yer, eğer iç içe geçmişseniz / başkaları bazılarını bazılarında olmayanlar ile döngüler. Bütün o spagetti ortasında bir döngü! O kadar kötü kodla çalıştım ve hata ayıklamak ve anlamak kabus gibi. Bu, ilk adımdan itibaren basit kaldığında ve onunla mutlu olduğunuzda sorun değil, ancak daha sonra diğer programcılar gelip bir şeyler ekliyorlar, muhtemelen bir süre içinde başka bir if varsa. İlk başta temiz yazılmışsa, bunun gerçekleşmesi için daha az şans vardır.

Önemli olan şeyleri açıklığa kavuşturmak ki diğer programcılar bir bakışta neyin doğru neyin yanlış olduğunu görebilsinler. Desen doğru görünüyor ve jarse olmaz kod yaz.

Bunun tersi, belki de bazı durumlarda bunun iyi okuduğunu iddia eden bazı insanları görebilmemdir. Kaynağa sahipsem, bu işlemi başka bir şey yapmayı beklerken yapmam gerekiyor. O zaman bile bana göre, while döngüsünü başka bir bloğun içine yerleştirmenin hiçbir farkı yoktur.


3

Eh, herkes diş telleri kullanmayı tartışsa da onları seviyor gibi görünse de, ben tam tersini tercih ederim. Sadece gerektiğim zaman diş telleri kullanıyorum çünkü onu daha okunaklı ve özlü buluyorum.

if (...)
   foo();
else while(...)
   bar();

... Aslında bunu " else while(...)" okunaklı buluyorum ! Hatta düz İngilizce gibi okur! Ama sanırım insanlar bunu garip bulacaklar çünkü en azını söylemek sıra dışı.

Sonunda, hepimiz onu diş telleriyle aptal geçirmez hale getirme eğilimindeyiz ... çünkü, bilirsin.


3
masum else while(...) bar();bir else while(...) foobar(); bar();
bakıcı

3
iyi, aptal ve tehlikeli bir masum koruyucu olduğunu söyleyebilirim . Aptalca hatalardan kaçınmak için onu aşağılama prensibini biliyorum ... ama bu ana kadar gelmek yine de oldukça üzücü. Ama böyle yorumlar ve indirimler alacağımı biliyordum. Sorun değil.
12'de

2
“Her zaman kodunuzu koruyacak kişi nerede yaşadığınızı bilen şiddetli bir psikopatmış gibi kodlayın.” ( Alan BRAGGINS )
tatarcık

1
Her şey, kodunuzda çalışan birinin en aptal seviyesinin olacağını varsaydığın şeye kadar kaynıyor. "Koruyucunuz" bu dört satırlık kodla karıştığında, o zaman elinizde büyük bir probleminiz olduğunu savunuyorum. Ve eğer şiddet içeren bir psikopatsa, iki tane var. ;)
dagnelies,

1
eğer - yukarıda bahsettiğim bağlantı , bu teklifin versiyonunu genişletti : Programcı 1: 'Burada güzel bir alıntı var - "Her zaman kodunuzu koruyacak kişi, nerede yaşadığınızı bilen şiddetli bir psikopatmış gibi kodlanır"' . Programcı 2: (Bakıcıya bakar) '' Sanki '' ne demek istiyorsun? '
tatarcık

2

Ben her zaman diş telleri koyarım, çünkü acele ederken başka bir çizgi ekleyebilirsin, girintili, diş tellerini unut ve kafanda ne olduğunu çizebilirsin. Açma braketini aynı hatta tutuyorum ama önemli değil. Her iki durumda da, onlara sahip olmak daha iyidir.

if(blah) {
    foo();
}
else {
    bar();
}

Diş tellerinin konumlandırılması muhtemelen dinin ötesinde (ya da muhtemelen dahil) herhangi bir şeyden daha fazla tartışmayı tetikler!
Andrew,

Kabul. Cevabımı, konumlarını değil varoluşlarını vurgulamak için düzenleyeceğim.
Tsvetomir Dimitrov

2

Diş tellerinde bu kadar yanlış olan, bu kadar çok insanın yazmaktan kaçınmaya çalıştığı şey nedir?

Hangi sorunu tam olarak else whileçözer?

Parantezler ucuz ve iyidir; zekice ve esprinin aksine kod niyetini açık ve net gösterirler.

Unix Felsefesinden Alıntı:

Berraklık Kuralı: Berraklık zeki olmaktan iyidir.

Bakım çok önemli ve çok pahalı olduğu için, programları en önemli iletişim sanki bunları yürüten bilgisayara değil, gelecekte kaynak kodunu okuyacak ve sürdürecek olan insanlara (kendiniz de dahil olmak üzere) yazıyor.


1

Yanlış bir şey yok

if (blah)
    foo();
else
    bar();

Tıpkı yanlış bir şey olmadığı gibi

if (blah) foo(); else bar();

doğru koşullarda (koşullarınız değişebilir, ancak belirli stiller çok fazla tekrarlayan kodunuz olduğunda en iyi şekilde kullanılır - o zaman her çizginin görünümü stilistik girintiden daha önemlidir)

Ancak, bir yol seçerseniz, buna devam edin - tutarlılık kraldır. Bu yüzden, ikinci örneğiniz çok kötü, eğer if ifadesi ifadesi için parantez içerdiğinden, while ifadesi dışında değil, diğer cümlecik için parantez içinde olmalıdır.


Ayrıca bu kodu daha önce görmüştüm:

if (x) foo()
{
  bar();
}

ve kodlama standardı nazi tarafından yazılmıştır (her şey için parantezde ısrar eden).


1

Modern IDE'ler kolayca yeniden biçimlendirmek (gereksiz parantezleri kaldırmak veya eklemek de dahil) ve / veya bir dosyayı kaydetme kodunu yeniden göndermek için kolayca yapılandırılabilir. Böylece örneğiniz otomatik olarak mesela benzeyecek

if (blah) {
  blub();
} else
  while (!bloop()) {
    bar();
  }

Girinti, gereksiz kümeler olmadan bile yuvalamayı her zaman kolayca görülebilir hale getirir. Dolayısıyla, bu IDE ayarlarını zorlamayı başarırsanız, risk görmem.

Şahsen, parantezleri ve çizgi şeritlerini yok sayan kod karmaşasını önlediği için çok daha okunaklı kod buluyorum:

if (blah) blub();
else while (!bloop()) bar();

Fakat elbette, birçok geliştirici sonsuza dek bir gün böyle şeyleri tartışmaktan çok mutludur.

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.