Sihirli dizelerin / sayıların kullanımı [kapalı]


31

Bu biraz tartışmalı bir konudur ve sanırım programcılar kadar çok fikir var. Ancak bunun uğruna, iş dünyasında (veya iş yerinizde) ortak uygulamaların ne olduğunu bilmek istiyorum.

İş yerimde katı bir kodlama kurallarımız var. Bunun bir bölümü sihirli dizgelere / sayılara ayrılmıştır. (C # için) belirtir:

Kodunda, sembolik sabitleri tanımlamak dışında, sayısal ya da dizgi değişmez değerleri kullanmayın. Sabitleri tanımlamak için aşağıdaki deseni kullanın:

public class Whatever  
{  
   public static readonly Color PapayaWhip = new Color(0xFFEFD5);  
   public const int MaxNumberOfWheels = 18;  
}

İstisnalar var: 0, 1 ve null değerleri neredeyse her zaman güvenle kullanılabilir. Çok sık 2 ve -1 değerleri de sorun yok. Kayıt veya izlemeye yönelik dizeler bu kuraldan muaftır. Değişmezlere, anlamları bağlamdan açık ve gelecekteki değişikliklere tabi olmadığında izin verilir.

mean = (a + b) / 2; // okay  
WaitMilliseconds(waitTimeInSeconds * 1000); // clear enough

İdeal bir durum, aşağıdaki durumlarda kodun okunabilirliği / sürdürülebilirliği üzerindeki etkileri gösteren resmi bir araştırma belgesi olacaktır:

  • Sihirli sayılar / dizgiler her yerde
  • Sihirli dizgiler / sayılar sabit (ya da farklı kapsama derecelerinde) sürekli bildirimlerle değiştirilir - ve lütfen "makul" kullanımı için bana bağırma, herkesin "makul" olduğu konusunda farklı fikirleri olduğunu biliyorum
  • Sihirli dizgiler / sayılar fazla miktarda ve olmak zorunda kalmayacakları yerlerde yerleştirilmişlerdir (aşağıdaki örneğe bakın)

Bunu, meslektaşlarımdan biriyle tartıştığımda, şöyle bir sabit ilan edeceğini belirten bilimsel temelli argümanlara sahip olmak istiyorum:

private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;

Başka bir örnek olacaktır (ve bu da JavaScript’tedir):

var someNumericDisplay = new NumericDisplay("#Div_ID_Here");

DOM kimliklerini javascript dosyanızın üzerine yapıştırıyor musunuz, eğer bu kimliği sadece 1 yerde kullanılıyorsa?

Aşağıdaki konuları okudum:
StackExchange
StackOverflow
Bytes Bilişim Topluluğu
Çok daha fazla makale var ve bunları okuduktan sonra bazı desenler ortaya çıkıyor.

Öyleyse benim sorum, kodumuzda sihirli dizeleri ve sayıları kullanmak mıdır? Özellikle mümkünse referanslar tarafından desteklenen uzman cevaplarını arıyorum.


2
Sihirli değişken, içeriği tarafından yansıtılmayan bir anlama sahip olan bir değişkendir. '10' tamsayı değeri, 10 sayısının anlamını yansıtır, bu yüzden onu sabitleştirmeye gerek yoktur. Aynı şey boşluk ve noktalı virgül için de geçerlidir. Öte yandan, '%% ?? %%' değerine sahipseniz ve bu bazı özel sınırlayıcılar ise, o zaman sabit olarak yerleştirilmelidir, çünkü içeriği sınırlayıcı olduğu gerçeğini yansıtmaz.
Jeroen Vannevel

23
NumberTen = 10Bu, 10 sayısı yeniden tanımlanmayacağından anlamsızdır. MaxRetryCount = 10Bu bir noktaya sahiptir, maksimum deneme sayısını değiştirmek isteyebiliriz. private const char SemiColon = ';'; Salak. private const char LineTerminator = ';'; Akıllı.
Mike,

1
Gerçek soru belli değil.
Tulains Córdova

Yanıtlar:


89

... meslektaşlarımdan biriyle tartıştığım zaman, kim şöyle bir sabit ilan edeceğini gösteriyor:

private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;

Meslektaşınızla birlikte yapmanız gereken argüman, değişmez bir alan olarak adlandırmak değil, değişmez bir isim seçmekten ibarettir Space.

Diyelim ki kodunuzun işi, noktalı virgülle ( a;b;c) ayrılmış ve kendileri boşlukla ( a;b;c d;e;f) ayrılmış alanları içeren bir kayıt akışını ayrıştırmaktır . Spesifikasyonunuzu kim yazdıysa, sizi bir ay sonra arar ve “yanılıyorduk, kayıtlardaki alanlar boru sembolleriyle ( a|b|c d|e|f) ayrılır” der, ne yaparsınız?

İsim-değeri-değeri şemasında meslektaşınız tercih ediyorsa, değişmezin ( SemiColon = '|') değerini değiştirmeniz ve SemiColonartık gerçekten noktalı virgül olmayan bir şey için kullanmaya devam eden kodla yaşamanız gerekir . Bu kod incelemelerinde olumsuz yorumlara yol açacaktır . Bu hafifler için, hazır bilgi adını değiştirebilir PipeSymbolve geçmesi ve her olay değiştirmek SemiColoniçin PipeSymbol. Bu hızda ';', ilk etapta sadece bir hazırda noktalı virgül ( ) kullanmış olabilirsiniz , çünkü her bir kullanımını ayrı ayrı değerlendirmek zorunda kalacaksınız ve aynı sayıda değişiklik yapacaksınız.

Sabitleri için Tanımlayıcıları açıklayıcı olması gerekir değeri nedir yapar , değer değil ne olduğunu , ve iş arkadaşınız yabani otlar içine sola dönüş yapmıştır en söyledi. Yukarıda açıklanan alan bölme uygulamasında, noktalı virgülün amacı bir alan ayırıcısıdır ve sabitler buna göre adlandırılmalıdır:

private const char FieldSeparator = ';';    // Will become '|' a month from now
private const char RecordSeparator = ' ';
private const int MaxFieldsPerRecord = 10;

Bu şekilde, alan ayırıcısı değiştiğinde, tam olarak bir kod satırını, sabitin bildirimini değiştirirsiniz. Değişikliğe bakan biri sadece bir satır görecek ve alan ayırıcısının noktalı virgülden boru sembolüne dönüştüğünü hemen anlayacaktır. Sabit kullandığı için değiştirmesi gerekmeyen kodun kalanı aynı kalır ve okuyucunun başka ne yaptığını görmek için okuyucuyu kazması gerekmez.


Tamamen katılıyorum. Birkaç on yıl önce, her biri 8 genel kayıt kullanan mesajların mesajların gönderildiği bir proje üzerinde çalıştım. Birisi #define one 1 #define two 2 vb. (Veya eşdeğeri, o zamanki seçim dili olan Birleşik Krallık Postanesi Mercan'sında olanı) ilan etmişti . Word, ileride uzunluk alanının bölüm sayısı değil, bayt sayısı olacağı yönünden yüksek çıktı, bu yüzden kod açıkça#define one 8 #define two 16 vb.
Olarak

3
Semicolon veya PipeSymbol gibi isimler göründüğü kadar saçma, bir komut dosyası kullanarak birini diğerine değiştirmek, etkilenen her ;kişiyi değiştirmekten çok daha kolay olacaktır |.
Brandin

Belirli bir String değişmezinin bir dosyada birçok kez kullanıldığı, ancak değeri dışında bir anlamı olmadığı durumundan ne haber? Örneğin, 20 farklı senaryoda bir haritada belirli bir anahtar alabileceğinizi test ediyorsanız, bunun gibi bir sabit tanımlamalı mıyım ?: public static final String MY_KEY_NAME = "MyKeyName"
Jordan McQueen

1
@JordanMcQueen Eğer her biri tam olarak bir kez kullanılmışsa ve başka bir yerde gerekli değilse, tam anlamıyla değişmezleri kullanmak için yapılmış bir durum var. Farklı bir dosya biçimi işler her senaryo varlık kodu gibi 's şey, her biçim (örneğin, kendi sabit tanımlamak gerekiyorsa CSV_RECORD_SEPARATOR, TSV_RECORD_SEPARATORvs.).
Blrfl

8

Noktalı virgülün sabit olarak tanımlanması gereksizdir, çünkü noktalı virgül zaten kendiliğinden sabittir . Hiç değişmeyecek.

Bir gün birilerinin "terminolojinin değişimini, + şimdi yeni noktalı virgül olduğunu " duyurması gibi bir şey değil ve meslektaşınız sadece sabiti güncellemek için mutlu bir şekilde acele edecektir (bana güldüler - şimdi bakın).

Bir de tutarlılık sorunu var. NumberTenSabitinin herkes tarafından kullanılmayacağını garanti ediyorum (çoğu kodlayıcı aklı dışında değil), bu nedenle ne olması beklenen bir amaç için hizmet etmeyecek. Kıyamet geldiğinde ve "on" global olarak 9'a ölçeklendiğinde, sabitin güncellenmesi hile yapmaz, çünkü sizi hala 10kodunuzda değişmez bir yığınla bırakacaktır , bu yüzden sistem kapsam dahilinde bile tamamen tahmin edilemez hale geliyor "on" un "9" anlamına geldiği devrimci bir varsayımda.

Tüm ayarları mazeret olarak saklamak, benim de ikinci düşüncelerim var. İnsan bunu hafifçe yapmamalı.

Şu ana kadar bu türden kullanım örnekleri neler? Hat sonlandırıcı ... maksimum deneme sayısı ... maksimum tekerlek sayısı ... bunların asla değişmeyeceğinden emin miyiz?

Maliyet, varsayılan ayarların değiştirilmesinin bir uygulamanın yeniden derlenmesini gerektirdiğini ve bazı durumlarda bağımlılıklarının bile (sayısal yapı değerleri derleme sırasında kodlanmış olabileceğinden).

Test ve alaycı yönü de var. Bağlantı dizesini bir const olarak tanımladınız, ancak artık birim testinizde veritabanı erişimiyle (sahte bir bağlantı kurarak) dalga geçemezsiniz.


4
“Hiç değişmeyecek.” Ben kesme işareti hakkında düşünürdüm (sonsuza dek ASCII değer 39'a bağlı). Kesme işareti kıvırmak için kullanılan bazı eski uygulamalar. Ancak şimdi modern uygulamalar, ASCII değerini eski uygulamalarla uyumlu düz bir kesme işareti olarak görüyor ve bunun yerine insanlar sık ​​sık kıvrılmış işaret için farklı bir glif göstermeyle uyumlu uygulamalar için kullanıyorlar (sol tek alıntı, Unicode 8217 ). Avrupa’nın, Amerikalıların dönemleri ondalık sayı olarak kullanma şeklini virgül olarak kullandığım için kendimi “hiç değil” ilan etmek için biraz tereddütlü buluyorum.
TOOGAM

@TOOGAM, örneğinizin bir DecimalPointsabiti - haklı kılmak Commaya da Periodsabittir. Bu oldukça fark: eski, bir işlevi , değerin bir rolünü veya amacını belirtir. "Noktalı virgül" veya "virgül" bu kategoriye girmez.
Konrad Morawski

Ondalık Nokta örneği için bu doğru. Ancak kesme işareti örneği, virgül (veya noktalı virgül) ile benzer (veya aynı) bir kategoriye benziyor.
TOOGAM

@KonradMorawski Noktalı virgül, ipi bölmek veya çizgiyi sonlandırmak gibi birçok amaç için kullanılabilir. Constance'ı isimlendirmek için kullanılması gereken anlamdır (değer değil). Gelecekteki değişimi göz önünde bulundurun, yani yarın 20 kaydın işlenmesine izin veriyoruz, bu nedenle NumberTen olarak adlandırılan konsolidasyon bağlam dışında, maxRecord hala iyi olacak.
MaxZoom,

5
private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;

Demek meslektaşın Daily WTF girişi yapmayı hedefliyor. Bu tanımlar aptal ve gereksizdir. Başkaları tarafından işaret edildiği gibi Ancak, aşağıdaki tanımlar olur değil saçma ya da gereksiz olabilir:

private const char StatementTerminator = ';';
private const char Delimiter = ' ';
private const int  BalanceInquiryCode = 10;

"Sihirli" sayılar ve dizgiler, gerçek, değişmez değerlerinin ötesinde bir anlam ifade eden sabitlerdir. 10Sabitin "on şeyin" ötesinde bir anlamı varsa (belirli bir işlem veya hata koşulu için bir kod olarak söyleyin), "sihir" haline geldiğinde ve bu soyut anlamı tanımlayan sembolik bir sabitle değiştirilmelidir.

Niyeti açıkça tanımlamanın ötesinde, sembolik sabitler, değişmezi yanlış yazdığınızda size bazı baş ağrılarından da tasarruf sağlar. Tek bir kod satırında "CVS" den "CSV" ye basit bir geçiş, ünite testi ve KG ile tüm yolu ele geçirdi ve belirli bir işlemin başarısız olmasına neden olan üretime soktu. Evet, açıkçası, ünite ve KG testleri eksikti ve bu kendi sorunu, ancak sembolik bir sabit kullanmak, o mide ekşimesi miktarını tamamen önlerdi.


3

Bu konuda tartışmalı bir şey olmamalıdır. Mesele, sihirli sayılar kullanıp kullanmamakla ilgili değil, nokta okunabilir kodlara sahip olmak.
Ve arasındaki farkı göz önünde bulundurun: if(request.StatusCode == 1)ve if(request.HasSucceeded). Bu durumda, ikincisinin daha okunaklı olduğunu savunuyorum, ancak bu hiçbir zaman böyle bir kodun olamayacağı anlamına gelmez int MaxNumberOfWheels = 18.

Not: Bu yüzden kodlama kurallarından kesinlikle nefret ediyorum. Geliştiriciler bu gibi karar çağrıları yapabilmek için yeterince olgun olmalıdır; Kimin tanrı tarafından oluşturulmuş bir metne bırakmamasını biliyor.


13
Sürücüler, yolun hangi tarafında sürdükleri konusunda karar verebilecek kadar olgun olmalıdır;)
Konrad Morawski

2
Bir karar çağrısının sonucu, olgun geliştiriciler arasında bile değişebildiğinden, rastgele kodlama kılavuzlarının bile tutarlılık yoluyla okunabilirliği arttırması amaçlanmıştır. Bu, NumberTen sabitinin yaratılmasının hiç bir anlamı yoktur.
Mike Partridge

1
Resmi olmaları, damgalanmaları vs. konusunda ısrar etmemeliydim, gayrı resmi olabilirler ancak üzerinde anlaşılmalılar ve bu zaten kişinin bireysel yargı olgunluğunu kullanmanın ötesine geçiyor. Ancak yorumunuzu şimdi sildiniz Stefan :)
Konrad Morawski

1
@StefanBilliet - hiç de değil. Demek istediğim, okunabilirliğin tutarlılıkla arttırıldığı yönünde. Buradaki sorun kodlama kılavuzunun kendisi değil, yanlış anlama yoluyla aşırılıklara sürüklenen bir kılavuzdur.
Mike Partridge

@MikePartridge Belki de detaylandırmalıydım; muhtemelen :-) gördüğüm kodlama kurallar daha yerde birisi yazılım ziyade siz ve Konrad gibi anlaşmalar daha yazılmalıdır düşünce nasıl bir genel kural kitabındaki eğilim içindedir düşünüyorsun
Stefan Billiet
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.