Tek karakterli sabitler değişmezlerden daha mı iyidir?


127

Geçenlerde hemen hemen her tek karakteri sabit olarak sağlayan bir sınıfa rastladım; dan her şey COMMAiçin BRACKET_OPEN. Bunun gerekli olup olmadığını merak ediyorum; Tek karakterli değişmezleri sabitlere çekmenin yararlı olabileceğini öneren bir "makale" okudum . O yüzden şüpheliyim.

Sabitleri kullanmanın ana çekiciliği, bir değişiklik gerektiğinde bakımı en aza indirmeleridir. Ama ne zaman virgül göstermek için ',' dan farklı bir sembol kullanmaya başlayacağız?

Sabitleri kullanmak yerine sabitleri kullanmamın tek nedeni kodu daha okunaklı hale getirmektir. Fakat city + CharacterClass.COMMA + state(örneğin) gerçekten bundan daha okunaklı city + ',' + statemı?

Benim için dezavantajları, artılarını daha ağır basar, temelde başka bir sınıf ve başka bir ithalatı tanıtırsınız. Ve mümkün olduğunda daha az koda inanıyorum. Genel konsensüsün burada ne olduğunu merak ediyorum.



33
Hmm ... farklı yerler için faydalı olabilir, belki? Örneğin, bazı diller guillements (açı tırnak kullanımı «ve »tırnak işareti yerine İngilizce en standart olarak) "(veya daha güzel görünümlü ve ). Bunun dışında, sadece bir dizi sihirli karakter gibi geliyor. İki örneğini varsayarsak CharacterClassdenir englishCharsve frenchCharsbu mümkündür englishChars.LEFT_QUOTEolabileceğini iken, frenchChars.LEFT_QUOTEolabilir «.
Justin Time

4
Virgüllerde birçok farklı varyasyon vardır: en.wikipedia.org/wiki/Comma#Comma_variants - belki de aptalca bir fikir değil, özellikle de kaynak kodunuz utf-8 olarak kodlanabiliyorsa.
Aaron Hall

21
Senin durumunda, "sayı" değişkenini çağırmak gibi. Sabitiniz DELIMITER olarak adlandırılmış olmalıydı. Ya da CITY_STATE = "{0}, {1}"
olmalı

13
Bağladığın yazı çok korkunç. Sabitler asla böyle bir kovaya atılmamalıdır . Onları bağlamlarının bulunduğu sınıflara koyun: özünde, sabit olan sınıf, sabitin kullanıldığı bağlamı sağlar. Örneğin, Java’lar File.separator. Sınıf size ayırıcı türünü söyler. Adında bir sınıf olması Constsya da Constantsbağlam içermemesi ve sabitlerin doğru kullanılmasını zorlaştırması.

Yanıtlar:


184

Tautology :

Sorunun ilk cümlesini okursanız, bu sorunun sihirli sayıları ortadan kaldırmak gibi uygun kullanımlarla ilgili olmadığı, en iyi şekilde akılsız aptalca tutarlılık ile ilgili olduğu çok açıktır . Bu cevabın adresi nedir

Sağduyu size bunu söyler const char UPPER_CASE_A = 'A';veya const char A = 'A'sisteminize bakım ve karmaşıklıktan başka bir şey eklememektedir. const char STATUS_CODE.ARRIVED = 'A'farklı bir durumdur.

Sabitler çalışma zamanında değiştirilemez şeyleri temsil etmelidir, ancak gelecekte derleme zamanında değiştirilmesi gerekebilir. const char A =Doğru olandan başka ne zaman eşit olur A?

public static final char COLON = ':'Java kodunda görürseniz , bunu kimin yazdığını bulun ve klavyelerini bozun. Temsilciniz sizden COLONhiç değişmezse, :sizde bir bakım kabusu göreceksiniz.

Gizleme:

Birisi onu değiştirdiğinde ne olur, COLON = '-'çünkü onu kullandıkları yerin -yerine her yere ihtiyaç duyar ? assertThat(':' == COLON)Her bir constreferans için değiştirilmediğinden emin olmak için temelde söyleyen birim testleri yazacak mısınız ? Sadece birisini değiştirdiğinde testi düzeltmesi için?

Birisi gerçekten public static final String EMPTY_STRING = "";faydalı ve faydalı olduğunu iddia ederse , sadece onların bilgisini nitelendirir ve diğer her şeyde onları güvenle görmezden gelirsiniz.

Her yazdırılabilir karakterin adlandırılmış bir sürümle birlikte sunulması, yalnızca kim yaptıysa, denetimsiz bir şekilde kod yazmaya uygun olmadığını gösterir.

Uyum:

Aynı zamanda yapay olarak uyumu azaltır, çünkü şeyleri, onları kullanan şeylerden uzaklaştırır ve onlarla ilişkilendirir.

Bilgisayar programlamasında, uyum, bir modülün elemanlarının birbirine ait olduğu dereceyi belirtir. Böylece, uyum belirli bir modül içindeki işlevsellik parçaları arasındaki ilişkinin gücünü ölçer. Örneğin, yüksek yapışma sistemlerinde işlevsellik güçlü bir şekilde ilişkilidir.

kavrama:

Aynı zamanda birbiriyle ilgisi olmayan sınıfları bir araya getirir çünkü hepsi, yaptıkları işle gerçekten ilgisi olmayan dosyalara atıfta bulunur.

Sıkı kavrama, bir sınıf grubunun birbirine çok bağımlı olduğu bir durumdur. Bu senaryo, bir sınıf çok fazla sorumluluk üstlendiğinde veya bir kaygı kendi sınıfına sahip olmak yerine birçok sınıfa yayıldığı zaman ortaya çıkar.

Eğer bir kullandıysanız iyi bir isim gibi DELIMITER = ','adı jenerik ve hiçbir anlamsal taşır çünkü hala aynı sorun olurdu. Değeri yeniden atamak, değişmez bir analiz yapmanıza yardımcı olmaktan başka bir şey değildir ','. Çünkü bazı kodların kullandığı ve ihtiyaç duyduğu ,ve bazı diğer kodların kullandığı ancak ;şimdi ihtiyaç duyduğu şey nedir? Yine de her kullanıma manuel olarak bakmak ve bunları değiştirmek zorundasınız.

Vahşi doğada:

Geçenlerde 1,000,000+ LOC18 yaşında bir uygulamayı yeniden ateşledim . Gibi şeyler vardı public static final COMMA = SPACE + "," + SPACE;. Bu, sadece " , "ihtiyaç duyulan yerin içine koymaktan daha iyi olamaz .

Okunabilirliği tartışmak istiyorsanız, IDE'nizi whitespaceonları görebileceğiniz karakterleri gösterecek şekilde yapılandırmanız gerektiğini öğrenmeniz gerekir. Bu, entropiyi bir sisteme sokmak için oldukça tembel bir nedendir.

Ayrıca ,birden COMMAfazla paket ve sınıfta kelimenin birden çok yanlış yazılmasıyla birden çok kez tanımlamıştı . Tüm varyasyonlara atıfta bulunarak kodda birbirine karıştırılır. Tamamen alakasız bir şeyi kırmadan bir şeyi denemek ve düzeltmek kabustan başka bir şey değildi.

Alfabe ile aynı, birden vardı UPPER_CASE_A, A, UPPER_A, A_UPPERçoğu zaman eşit olduğunu A ancak bazı durumlarda değildi . Neredeyse her karakter için değil, tüm karakterler için.

Ve düzenleme geçmişlerinden 18 yıl boyunca bunlardan birinin hiç birinin düzenlenmediği ya da değiştirildiği görülmedi, çünkü şimdi açık olması gereken nedeni, takip edilemeyecek çok fazla şeyi kıracağı, dolayısıyla yeni bir değişkeniniz olduğu aynı nedenden asla değiştirilemeyen aynı şeye işaret eden isimler.

Aklı başında hiçbir gerçeklikte, bu uygulamanın, en yüksek entropiden başlamaktan başka bir şey yapmadığını iddia edemezsiniz.

Tüm bu karışıklığı yeniden alevlendirdim ve tüm totolojileri belirledim ve yeni üniversite işe alımlarının çok daha üretken olduklarını const, çünkü bu referansların gerçekte neye işaret ettiklerini çok sayıda dolaylı yoldan avlamak zorunda olmadıklarını, çünkü isimlerinin ne olduğu konusunda güvenilir olmadıklarını belirttim. neleri içerdiklerine karşı.


112
Belki bir karşı örnek eklemelisin: const char DELIMITER = ':'gerçekten faydalı olurdu.
Bergi

115
EMPTY_STRINGFaydalı birkaç argüman yapardım . (1) EMPTY_STRINGBir dosyadaki tüm kullanımları bulabildiğimden çok daha kolay bulabilirim "". (2) Gördüğümde EMPTY_STRING, geliştiricinin o dizginin boş olmasını istediğinden ve daha sonra sağlanacak bir dizgenin yanlış düzenleme veya yer tutucu olmadığından emin olduğumu biliyorum. Şimdi, bu tartışmayı yaparak, bilgilerimi nitelendirebileceğimi ve beni sonsuza dek güvenle görmezden gelebileceğinizi iddia ediyorsunuz. Peki, bilgimi nasıl nitelersin? Ve sonsuza dek tavsiyemi görmezden gelmeyi planlıyor musun? Hiçbir şekilde sorunum yok.
Eric Lippert,

39
@ immibis: Değişim yönetimi bağlamında bu şeyleri düşünmeyi bırakabiliriz. Onlar sabittir. Değişmezler. Bunları , kodun anlamını arayan ve kavrayan insanlar bağlamında faydalı olarak düşünün . Bir şeyin bir anahtar-değer çifti sınırlayıcısı olduğunu bilmek, bir kolon olduğunu bilmekten çok daha faydalıdır; Bu, programın kaygısının anlamsal alanı ile ilgili bir gerçek , sözdizimi değil .
Eric Lippert

15
@EricLippert: Bir tür bir tek garanti işaret Burada başkalarının noktası görüyorum constben anlamsal anlamı olduğunu size katılıyorum gerçi sağlar o (derleme sonra) zamanında değişmeyeceği olduğunu constise değişim yönetimi aracı olarak kullanımından çok daha önemlidir. Bununla birlikte const EARLIEST_OS_SUPPORTED, bunun yalnızca anlamsal olarak tutarlı olmadığını, program geliştikçe ve eski kıtlık ortadan kalktıkça zamanla değişeceğini de kesinlikle söyleyebilirim .
Robert Harvey,

16
@DanielJour: Yani bu o zaman için üçüncü bir argümandır EMPTY_STRING; iyi tasarlanmış bir IDE'nin, bu varlığı sözdizimsel değil sembolik olarak ele almamı sağlayan araçları yüzeylendirmesi. Bunu dördüncü bir argümana genelleştirin: IDE'nin altında yer alan kod analiz araçları kütüphanesinin , sembolik düzeyde kod doğruluğunun gelişmiş programatik analizine izin verebileceği . Kelimelerin tam anlamıyla 40 yıl önce yazılanlardan daha gelişmiş araçlardan yararlanmak isteyen bir geliştiricinin, gelişmiş takımın ödüllerini alabilmesi için alışkanlıklarında yalnızca küçük değişiklikler yapılması gerekiyor.
Eric Lippert

145

Sabitleri kullanmanın ana çekiciliği, bir değişiklik gerektiğinde bakımı en aza indirmeleridir.

KESİNLİKLE HAYIR. Bu, sabitleri kullanmak için hiçbir neden değildir, çünkü sabitler tanımlara göre değişmez . Eğer bir sabit sürekli değişirse, o zaman sabit değildi, değil mi?

Sabitleri kullanmanın çekiciliğinin, değişim yönetimi ile ilgisi ne olursa olsun , insanlar tarafından yazılmaya, anlaşılmaya ve korunmaya uygun programlar yapmakla ilgili her şeyi yapmalısınız . Eğer programımda bir kolonun URL ayırıcı olarak kullanıldığı her yerde bilmek istersem, o zaman sabit bir URLSeparator tanımlamak için bir disipline sahipsem bunu çok kolay bir şekilde anlayabilirim; :ve koddaki her bir yeri, :bir temel sınıfı veya bir ?:operatörü veya herhangi bir şeyi belirtmek için kullanılan yeri alın .

Bunun anlamsız bir zaman kaybı olduğunu belirten diğer cevaplara tamamen katılmıyorum. Adlandırılmış sabitler bir programa anlam katar ve bu anlambilim, bir programı daha derinden anlamak ve daha etkin bir şekilde sürdürmek için hem insanlar hem de makineler tarafından kullanılabilir.

Buradaki hile, sabitlerden kaçmak değil, onları sözdizimsel özelliklerinden ziyade anlamsal özellikleriyle adlandırmaktır . Sabit kullanılan nedir? CommaProgramınızın ticari etki alanı tipografi, İngilizce dil ayrıştırma veya benzeri değilse, onu arama . Bir ListSeparatorşeyin anlamını netleştirmek için onu ya da öyle bir şeyi arayın .


42
Burada söylediklerinizin ruhuna katılıyorum, ancak ikinci / üçüncü cümle gerçekten doğru değil. Sabit bir dosyanın sürümleri arasında değişebilir. Aslında yazdığım programların çoğu MY_VER, "5.03.427.0038" gibi sihirli bir dizgeden ziyade, programın geri kalanında kullanılabilecek, programın geçerli sürüm numarasını içeren bir şeye sahip bir sabittir . Eklenen fayda, sizin anlamsal bilgi verildiğini söylediğiniz gibidir.
Monty Harder

50
Dürüst olmak gerekirse, bir sabitin amacı, başlatıldıktan sonra çalışma zamanı boyunca değişmemesi, derlemeler arasında değişmemesidir. Derleyicinin bakış açısından, derleyicinin programın onu değiştiremeyeceği varsayımlarını yapabileceği; Programcının, yeniden derlerken değiştirmesine izin verilip verilmeyeceği, sabitliğini değiştirmez. Yazılımın donanımdan salt okunur bir değer aldığı durumlar olabilir, belki bir const volatile T*işaretçiyi önceden belirlenmiş bir adrese silerek ; program değiştiremezken, donanım değiştirebilir.
Justin Time

6
@MontyHarder: İyi nokta. Benim fikrim, tipik olarak sabitler arasında - sonsuza dek değişmeyen - ve bir defa atanabilecek değişkenler - sürümden sürüme, koşmadan koşuya ya da her neyse değişebilen farklı dilleri kullandığım gerçeğidir . Bir sabit ve bir değişken farklı şeylerdir; biri aynı kalır ve biri zamanla değişir.
Eric Lippert,

7
@SteveCox: Katılıyorum; C / C ++ 'nın' const 'ı karakterize etme şekli tuhaf ve sınırlı kullanım alanıdır. Sabitlerin istediğim özelliği, değerlerinin değişmemesi, bazı işlevlerde onları değiştirmemden değil, diğerlerinde değiştirmem değil.
Eric Lippert,

15
"Bu, sabitleri kullanmak için hiçbir neden değildir, çünkü sabitler tanımlara göre değişmez. Eğer bir sabit değişirse, o zaman sabit değildi, değil mi?" Derleme zamanında sabitleri değiştirmek (açıkça çalışma zamanı değil) tamamen normaldir. Bu yüzden ilk başta onları açıkça etiketlenmiş bir “şey” yaptınız. Tabii ki, OP’nin sabitleri önemsizdir, ancak bir şey const VERSION='3.1.2'veya bir şey düşünün const KEYSIZE=1024.
AnoE

61

Hayır, bu aptalca.

Ne değil mutlaka dilsiz yerelleştirme nedenlerle adlandırılmış etiketler halinde böyle şeyler çekerek olduğunu. Örneğin, binlerce sınırlayıcı olan bir Amerika (1.000.000) virgülle ama değil , diğer yerlerdeki virgül. Bunu adlandırılmış bir etikete (uygun, virgül olmayan bir adla) çekmek, programcının bu ayrıntıları yoksaymasına / soyutlamasına izin verir.

Ancak "sihirli teller kötüdür" ifadesiyle sabit yapmak sadece kargo danışmanlığıdır.


8
Yerelleştirme genellikle sadece dize sabitlerinden daha karmaşıktır. Örneğin, bazı diller tüm liste öğeleri arasında liste sınırlayıcı isterken, diğerleri son öğeden önceki sınırlayıcıyı hariç tutar. Yani, genellikle bir yerel sabitlere değil, yerel kurallara ihtiyaç duyar .
Vlad

19
Aslında binlerce sınırlayıcı mutlaka diğer yerel bölgelerde (Çin / Japonya) binlerce sınırlayıcı değildir. Sabit sayıda rakamdan sonra bile ayarlanmadı (Hindistan). Ah, bunun 1000 sınırlayıcı mı yoksa 1000000 sınırlayıcı mı (Meksika) olduğuna bağlı olarak farklı sınırlayıcılar olabilir. Ancak bu, bazı bölgelerde ASCII rakamlarını 0-9 kullanmamaktan daha az problemdir (Farsça). ux.stackexchange.com/questions/23667/…
Peter

1
@Vlad Localization bundan çok daha karmaşık, ancak binlerce ayırıcı, insanların tanıdığı iyi bilinen bir örnek.

Yerelleştirme stratejisine bağlıdır ... programınızdaki tüm sabitleri çevirmek için değiştirir misiniz? Veya değerleri bir dosyadan (veya başka bir veri deposundan) okumayı mı tercih edersiniz, bunları çalışma zamanı değişkenlerini etkili bir şekilde yaparsınız?
Paŭlo Ebermann

O zaman bu hiç bir sabit olarak işe yaramaz. Programın, korkunç bir uygulama olan yerel yerler için yeniden derlenmesi gerekiyor. Tanım dosyalarından yüklenen değişkenler olmalı ve gerektiğinde aranmalılar. Bu noktaya katılmıyorum değil (cevabı ben oyladım), ama konuyla ilgili daha zorlanıyorum.

29

Belirsiz olabilen veya birkaç farklı amaç için kullanılan birkaç karakter vardır. Örneğin, '-'kısa çizgi, eksi işareti veya hatta bir tire kullanırız. Ayrı isimleri şu şekilde yapabilirsiniz:

static const wchar_t HYPHEN = '-';
static const wchar_t MINUS = '-';
static const wchar_t EM_DASH = '-';

Daha sonra, bunları yeniden tanımlayarak belirsizleştirmek için kodunuzu değiştirmeyi seçebilirsiniz:

static const wchar_t HYPHEN = '-';
static const wchar_t MINUS = '\u2122';
static const wchar_t EM_DASH = '\u2014';

Bu , belirli tek karakterler için sabitleri tanımlamayı düşünmenizin bir nedeni olabilir . Ancak , bu şekilde belirsiz olan karakter sayısı azdır. En çok, bunu sadece onlar için yapar gibi görünüyorsun. Ayrıca, kodu bu şekilde ele almadan önce belirsiz karakterleri ayırt etmek için bir ihtiyaç duyana kadar bekleyebileceğinizi savunuyorum.

Tipografik sözleşmeler dile ve bölgeye göre değişebildiğinden, bu belirsiz noktalama işaretlerini bir çeviri tablosundan yüklemekten muhtemelen daha iyi olursunuz.


Benim için karakter sabitleri oluşturabilmenin tek geçerli sebebi bu
FP

2
-Bir çizgi olarak kullanmak oldukça yanıltıcıdır ... çoğu yazı tipinde bunun için çok kısadır. (En kısa çizgiden bile kısadır.)
Paŭlo Ebermann

Tamam, en iyi örnek değil. stringS ile başladım ve çizgi için wchar_tstandart el yazması kuralını kullandım "--". Fakat orjinal örnek tek karakter kullanıyordu, bu yüzden soruya sadık kalmaya başladım. Tip millet vardır -, özellikle bir sabit aralıklı yazı çalışırken, tire için.
Adrian McCarthy,

1
@ PaŭloEbermann Hayır, geleneksel olarak em çizgi yazı karakterinin 'm' karakterinin genişliği ve en çizgi ise 'n' karakterinin genişliğidir.
Dizzley

@Dizzley evet ve kısa çizgi genişliği <n genişlik <m genişlik.
Paŭlo Ebermann

22

Bir sabit anlam katmak zorundadır.

COMMA'yı virgül olarak tanımlamak anlam kazandırmaz, çünkü virgülün virgül olduğunu biliyoruz. Bunun yerine anlamı imha ediyoruz, çünkü şimdi COMMA artık virgül olmayabilir.

Bir amaç için virgül kullanıyorsanız ve adlandırılmış bir sabit kullanmak istiyorsanız, bu amaçtan sonra adlandırın. Örnek:

  • city + CharacterClass.COMMA + state = kötü
  • city + CITY_STATE_DELIMITER + state = iyi

Biçimlendirme için işlevleri kullanın

Kişisel olarak FormatCityState(city, state), bu fonksiyonun gövdesinin kısa olduğu ve test durumlarını geçtiği sürece nasıl göründüğünü umursamıyorum.


1
Ah, ama virgül her zaman aynı virgül değildir. COMMA = '\ u0559' veya '\ u060C' vb. Tanımlayabilir (bkz. Unicode) veya daha sonra bir değişkene dönüştürebilir ve daha sonra config dosyasından okuyabilirim. Bu şekilde, yine aynı anlama gelecek , ama sadece farklı bir değer. Peki ya bu.
Bay Lister,

2
@ MrLister: YAGNI. Bu ihtiyaç varsa: harika! İyi bir çözümün var. Ama yapmazsan - kodunu karıştırma çünkü belki bir gün belki de. Ayrıca, benim deneyimlerime göre, kod tabanınızda hiçbir işlevi olmayan soyutlamalar ortaya çıkarmaya çalışırsanız, insanlar tutarlı olmak konusunda mükemmel değillerdir. Yani, COMMA'yı başka bir kod noktası kullanmak niyetinde tanımlamış olsanız bile, seçimin önemli olacağı şekilde yeterli büyüklükte ve yaşta bir programda, sabitin her yerde kullanılması gerekmediğini göreceksiniz. (ve aksine, uygun olmayan bir şekilde kullanılmış olabilir).
Eamon Nerbonne

17

Sabit bir COMMA'nın hatadan daha iyi ','veya ","daha kolay olduğu düşüncesi . Mantıklı olduğu durumlar olduğundan emin olun, örneğin final String QUOTE = "\"";tüm eğik çizgiler olmadan okunabilirlikten büyük ölçüde tasarruf etmek, ancak bunun gibi dil kontrol karakterlerini engellemek \ 've "onları çok faydalı bulduk.

Kullanmak final String COMMA = ","sadece kötü bir biçim değil, aynı zamanda tehlikeli! Birisi gelen ayırıcısını değiştirmek istediğinde ","için ";"onlar sabitler dosyasını değiştirmek gidebilir COMMA = ";"onları bunu yapmaya daha hızlı olduğu için ve çok işe yarıyor. Bunun dışında, COMMA'yı kullanan diğer tüm şeyler de dış tüketicilere gönderilenler de dahil olmak üzere noktalı virgüllerdir. Bu yüzden tüm testlerinizi geçiyor (çünkü tüm marshalling ve unmarshalling kodu da COMMA kullanıyordu) ancak harici testler başarısız olacak.

Yararlı olan, onlara yararlı isimler vermektir. Ve evet, bazen çoklu sabitler aynı içeriğe ancak farklı isimlere sahip olacaklardır. Örneğin final String LIST_SEPARATOR = ",".

Yani sorunuz, "değişmezlerden daha iyi tek char sabitleridir" ve cevap ise kesinlikle hayır, öyle değil. Ancak her ikisinden de daha iyisi, amacının ne olduğunu açıkça söyleyen dar kapsamlı bir değişken adıdır. Elbette, bu fazladan referanslara (fazladan derleneceklerini varsaymadıklarını varsayarsak), ancak fazladan bir bayt harcayacaksınız, ancak bir uygulamanın maliyetinin çoğunun olduğu uzun süreli bakımda, yapmak için zaman ayırmaya değer.


DISP_APOSTROPHE'nin, hedef platforma bağlı olarak koşullu olarak ASCII 0x27 veya Unicode tekli sağ fiyat teklifi karakteri (bu da bir kesme kabiliyetinin tipografik olarak daha uygun bir yorumudur) olarak tanımlanmasına ne dersiniz?
supercat,

3
aslında QUOTEörnek, genellikle / halk olarak bilinen atamadan beri de kötü bir fikir olduğunu kanıtlıyor DOUBLE QUOTEve QUOTEima SINGLE_QUOTEdaha doğru olarak anılacaktır olan APOSTROPHE.

3
@JarrodRoberson Alıntıyı kişisel olarak tek bir teklife işaret ettiğini sanmıyorum - ama yapabileceğiniz yerdeki belirsizliği ortadan kaldırmak için başka bir iyi sebep!
corsiKa

2
QUOTEEk bir nedenden ötürü örneği sevmiyorum - onunla yapılan okuma dizgilerini zorlaştırıyor, "Hello, my name is " + QUOTE + "My Name" + QUOTEbu önemsiz bir örnek ve yine de kötü görünüyor. Oh, elbette, birleştirme yerine, yerine belirteçleri kullanabilirsiniz, "Hello, my name is %sMy Name%s".format(QUOTE, QUOTE)daha da kötüsü olabilir. Ama, hey, hadi indekslenmiş belirteçleri deneyelim "Hello, my name is {0}My Name{0}".format(QUOTE), o kadar iyi değil. İçinde alıntılarla oluşturulan önemsiz olmayan herhangi bir dize daha da kötü olurdu.
VLAZ

2
@corsiKa - Ben kaçan gerçek tırnak ile yaşayacağım. Birinden kaçmayı özlersem, kullandığım IDE hemen şikayet eder. Kod büyük olasılıkla derlenmeyecek. Saptamak oldukça kolaydır. Yaparken bir hata yapmak ne kadar kolay, "My name is" + QUOTE + "My Name" + QUOTEaslında yukarıdaki hatayı üç kez yazarken aynı hatayı yaptım . Görebiliyor musun? Bu size biraz alırsa, bu eksik uzay peşinde olduğunu . Dizeyi biçimlendirir misiniz? Bu durumda, değiştirilecek birden fazla belirteçli bir dizgenin çalışması daha da kötüleşecek. Daha okunaklı olması için nasıl kullanabilirim?
VLAZ

3

Lexers ve parsers yazarak bazı çalışmalar yaptım ve terminalleri temsil etmek için tamsayı sabitleri kullandım. Tek karakterli terminaller, basitlik uğruna sayısal değerleri olarak ASCII koduna sahipti, ancak kod tamamen başka bir şey olabilirdi. Böylece, ASCII kodunu ',' sabit değeri olarak atanmış bir T_COMMA'ya sahip olurdum. Bununla birlikte, ASCII setinin üstünde tamsayılar atanan antrenmanlar için de sabitler vardı. Yacc veya bizon gibi ayrıştırıcı üreticilere veya bu araçları kullanarak yazılmış ayrıştırıcılara bakarken, temelde herkesin yaptığı gibi bir izlenim edindim.

Bu yüzden, diğerleri gibi, ben de kodunuz boyunca değişmezleri kullanmak yerine sabitleri kullanmak amacıyla ifade etmek için sabitleri tanımlamanın anlamsız olduğunu düşünüyorum; tarif ettiğiniz gibi sabitler. Ayrıştırıcı durumda, sabitlerin yalnızca karakter değişmezlerini temsil etmek için bulunmadığını unutmayın; onlar sadece olabilir varlıkları temsil gerçekleşmesi karakter değişmezleri olmak.

Karşılık gelen değişmezler yerine sabitleri kullanmanın mantıklı olabileceği birkaç daha yalıtılmış durumu düşünebilirim. Örneğin, NEWLINE'ı bir unix kutusundaki değişmez '\ n', pencerelerde veya mac kutusuysanız '\ r \ n' veya '\ n \ r' olarak tanımlayabilirsiniz. Aynısı, tablo verilerini temsil eden dosyaları ayrıştırmak için de geçerlidir; FIELDSEPARATOR ve RECORDSEPARATOR sabitlerini tanımlayabilirsiniz. Bu gibi durumlarda, aslında belirli bir işleve hizmet eden bir karakteri temsil etmek için bir sabit tanımlarsınız. Yine de acemi bir programcı olsaydınız, belki de alan ayırıcınıza COMMA ismini koyardınız, ALAN AYARLARI olarak adlandırmanız gerektiğini fark etmemeniz gerekirdi ve fark ettiğiniz zaman, kod üretimde olur ve bir sonraki sırada olursunuz. proje,

Son olarak, tanımladığınız uygulama, belirli bir karakter kodlamasında kodlanan verileri işlemek için kod yazdığınız birkaç durumda anlamlı olabilir , örneğin iso-8859-1, ancak kodlamanın daha sonra değişmesini bekleyin. Elbette böyle bir durumda, yerelleştirmeyi kullanmak veya onu kullanmak için kütüphaneleri kodlamak ve kodunu çözmek çok daha anlamlı olacaktır, ancak bir nedenden ötürü, sizin için kodlama sorunlarını işlemek için böyle bir kütüphaneyi kullanamazsanız, yalnızca tek bir dosyada yeniden tanımlamanız gerekmek yerine kaynak kodunuzun her tarafında yer alan sabit kodlu değişmezler gitmenin bir yolu olabilir.

Bağlandığınız makaleye gelince: Karakter değişmezlerini sabitler ile değiştirmek için bir durum oluşturmaya çalıştığını sanmıyorum. Sabitleri kod tabanınızın diğer kısımlarına çekmek için arayüzleri kullanmanın bir yöntemini göstermeye çalıştığını düşünüyorum. Bunu göstermek için kullanılan örnek sabitler çok kötü seçilir, ancak hiçbir şekilde önemli olduklarını sanmıyorum.


2
Sabitleri kod tabanınızın diğer kısımlarına çekmek için arayüzleri kullanmanın bir yöntemini göstermeye çalıştığını düşünüyorum. daha da kötü bir anti-patern olan ve sıkıca bağlanan ve aynı zamanda düşük yapışma olan da bunu yapmak için geçerli bir neden yoktur.

3

Buradaki tüm cevaplara ek olarak, iyi bir programlamanın, aynı kodu tekrar tekrar yapmak zorunda kalmadan kendiniz ve belki başkaları tarafından yapılabilecek uygun soyutlamalar sağlamakla ilgili olduğunu düşündüğüm yiyecek olarak eklemek isterim .

İyi soyutlamalar, kodun bir yandan kullanımı kolay, diğer yandan bakımı kolay hale getirir.

İçinde DELIMITER=':'ve kendisinin kötü bir soyutlama olduğuna tamamen katılıyorum ve sadece daha iyisi COLON=':'(ikincisi tamamen fakirleştirildiği için).

Dizeleri ve ayırıcıları içeren iyi bir soyutlama, sınırlandırıcının ne olduğunu söylemeden önce, bir veya daha fazla bireysel içerik öğesini diziye paketlemenin ve bunları paketlenmiş diziden de açmanın bir yolunu içerecektir. Böyle bir soyutlama, çoğu dilde sınıf olarak bir kavram olarak toplanır; örneğin, kullanımı pratikte kendi kendini belgelemek için, bu sınıfın kullanıldığı tüm yerleri arayabilir ve programcının bir dizi soyutlamanın kullanıldığı her durumda, paketlenmiş dizelerin formatıyla ilgili neyi istediğinden emin olabilirsiniz.

Böyle bir soyutlama temin edildikten sonra, hiç değeri nedir danışmak zorunda kalmadan kullanımı kolay olurdu DELIMITERya COLON, ve, genel olarak uygulanması sınırlı olacağını uygulama ayrıntıları değiştirerek. Dolayısıyla, kısacası, bu sabitler gerçekten uygun bir soyutlama içinde gizlenmiş olan uygulama detayları olmalıdır.

Sabitleri kullanmanın ana çekiciliği, bir değişiklik gerektiğinde bakımı en aza indirmeleridir.

Tipik olarak birkaç ilgili özelliğe sahip kompozisyonlar olan iyi soyutlamalar, bakımın en aza indirilmesinde daha iyidir. Birincisi, sağlayıcıyı tüketicilerden açıkça ayırıyorlar. İkincisi, uygulama ayrıntılarını gizler ve bunun yerine doğrudan kullanışlı işlevsellik sağlarlar. Üçüncüsü, nerede ve ne zaman kullanıldıklarını yüksek düzeyde belgelerler.


2

Etkin bir şekilde kullanılan bu sabitleri gördüğüm bir zaman, mevcut bir API veya belgeyle eşleşmektir. COMMABelirli bir yazılım parçasının COMMAsoyut bir sözdizimi ağacında etiket olarak kullanılan bir ayrıştırıcıya doğrudan bağlanması nedeniyle kullanılan gibi semboller gördüm . Ayrıca resmi bir şartnameye uyduğunu gördüm. Resmi şartnamelerde, bazen mümkün olduğu kadar açık ve net olmak istediklerinden COMMAziyade semboller göreceksiniz ','.

Her iki durumda da, benzer bir sembolün kullanılması, COMMAaksi halde ayrık olan bir üründe tutarlılığın sağlanmasına yardımcı olur. Bu değer, genellikle aşırı ayrıntılı notlandırmaların maliyetinden daha ağır basabilir.


2

Bir liste yapmaya çalıştığınızı gözlemleyin .

Yani, refactor olarak: String makeList(String[] items)

Başka bir deyişle, veri yerine mantığı hesaba katın . Diller listeleri nasıl temsil ettikleri konusunda farklı olabilir, ancak virgüller her zaman virgül olur (bu bir totoloji). Dil değişirse, virgül karakterini değiştirmek size yardımcı olmaz - ama bu olacaktır.


0

Bu, geliştiriciniz tarafından uygulamanın bir parçası olarak yazılmış bir sınıfsa, bu neredeyse kesinlikle kötü bir fikirdir. Diğerlerinin de belirttiği gibi SEPARATOR = ',', değeri değiştirebileceğiniz yer gibi sabitleri tanımlamak mantıklı , sabit ise yine de mantıklı ancak ismini sadece onların değerini tanımlayan sabitlerden çok daha az anlamlı.

Ancak, adının içeriğini tam olarak tanımlayan sabitleri bildirmenin ve sabitin adını uygun şekilde değiştirmeden değeri değiştiremediğiniz durumlarda, en az iki durum vardır:

  • Matematiksel veya fiziksel sabitler, örn PI = 3.14159. Burada, sabitin rolü, sembolik isim PItemsil ettiği değerden daha kısa ve okunabilir olduğundan, anımsatıcı gibi davranmaktır .
  • Ayrıştırıcıdaki sembollerin ayrıntılı listeleri veya klavyedeki tuşlar. Unicode karakterlerinin çoğunda veya hepsinde bir sabitler listesine sahip olmak bile mantıklı gelebilir ve bu, davanızın düşeceği yerdir. Gibi bazı karakterler Aaçık ve net bir şekilde tanınabilir. Ama kolayca söyleyebilir Аve Abirbirinden? Bunlardan ilki Kiril harf А , ikincisi Latin harf A'dır . Grafik olarak neredeyse özdeş olsalar bile, farklı Unicode kod noktaları ile temsil edilen farklı harflerdir. Sabitleri tercih ederim CYRILLIC_CAPITAL_AveLATIN_CAPITAL_AKodumda iki tane neredeyse aynı karakter var. Tabii ki, yalnızca Kiril içermeyen ASCII karakterleriyle çalışacağınızı biliyorsanız, bu anlamsızdır. Aynı şekilde: Latin alfabesini günlük kullanıyorum, bu yüzden Çince karakter gerektiren bir program yazıyorsam, muhtemelen anlamadığım bir karakter eklemek yerine sabit kullanmayı tercih ederim. Gündelik Çince karakterler kullanan biri için Çince karakter açık olabilir, ancak Latin karakterinin adlandırılmış bir sabit olarak gösterilmesi daha kolay olabilir. Gördüğünüz gibi, içeriğe bağlı. Yine de, bir kütüphane tüm karakterler için sembolik sabitler içerebilir, çünkü yazarlar kütüphanenin nasıl kullanılacağını önceden bilemez ve belirli bir uygulamada okunabilirliği artırmak için hangi karakterlerin sabitlere ihtiyacı olabilir.

Bununla birlikte, bu tür durumlar genellikle sistem sınıfları veya özel amaçlı kütüphaneler tarafından ele alınmaktadır ve çok özel bir proje üzerinde çalışmadığınız sürece, uygulama geliştiricileri tarafından yazılan kodlardaki oluşumları çok nadir görülmelidir.


-1

Olabilir.

Tek karakter sabitleri ayırt etmek nispeten zordur. Bu yüzden virgül yerine nokta eklediğiniz gerçeğini kaçırmanız kolay olabilir.

city + '.' + state

oysa bu yapmak için nispeten zor bir hata

city + Const.PERIOD + state

Uluslararasılaştırma ve küreselleşme ortamınıza bağlı olarak, bir ASCII kesme işareti ile Windows-1252 açık ve kapalı kesme işareti (veya ASCII çift alıntı ve Windows-1252 açık ve kapalı alıntı) arasındaki fark önemli olabilir ve görünüşü görselleştirmek zordur. Kodda

Şimdi, büyük olasılıkla, yanlışlıkla virgül yerine bir süre koyarak önemli bir işlevsel sorun olsaydı, yazım hatası bulmak için otomatik bir test olacaktı. Yazılımınız CSV dosyaları oluşturuyorsa, test süitinizin şehir ve eyalet arasında bir süre geçirdiğinizi çok çabuk keşfetmesini bekliyorum. Yazılımınızın çeşitli uluslararasılaştırma konfigürasyonları olan müşteriler için çalışması gerekiyorsa, muhtemelen test takımınız her ortamda çalışacak ve kesme işareti yaptırmak istemeniz durumunda Microsoft açık bir teklifiniz varsa alacaktır.

Muhtemelen bu şekilde kod yazmasam bile, kapsamlı bir test paketine sahip olmayan daha eski bir kodunuz olduğunda, bu sorunları giderebilecek daha ayrıntılı kodları seçmenin daha anlamlı olduğu bir proje hayal edebiliyorum. yeşil alan geliştirme projesi. Ve yalnızca noktalama karakterleri için bir sabit eklemek, yalnızca uygulamanızda potansiyel olarak sorunlu olanlardan ziyade, büyük olasılıkla brüt olabilir.


2
bazı moronlar Const.PERIODeşit olacak şekilde değiştiğinde ne olur ~? Adlandırılmış karakterlerin bir totolojisi için bir gerekçe yoktur, sadece günümüz programlama ortamlarında görülmeyen bakım ve karmaşıklığı arttırır. Temel olarak söyleyecek bir takım testler yazacak mısın assert(Const.PERIOD == '.')?

3
@ JarrodRoberson - Bu emmek, elbette. Fakat eğer birisi gerçek bir virgül yerine neredeyse tam olarak virgül gibi görünen bir Unicode sabiti eklediyse, sizin de başınız belaya girer. Dediğim gibi, bu bir yeşil alan geliştirme projesinde yapacağım türden bir şey değil. Ancak, virgül / periyot veya kesme işareti / Microsoft kullanımı kesme sorununu birkaç kez tetiklediğiniz sivilceli bir test paketine sahip eski bir kod tabanınız varsa, bazı sabitler oluşturmak ve insanlara bunları kullanmalarını söylemek için makul bir yol olabilir. Bir yıl yazma sınavlarına girmeden kodu daha iyi.
Justin Mağarası,

3
senin eski örneğin fakir bir örnek, 18 yaşını dolduran 1000.000'den fazla LOC kod üssünü yeniden düzenlemeyi yeni bitirdim. Hatta farklı çakışan isimlerle birden fazla defa tanımlanmış her basılabilir karaktere sahipti. Ve çoğu zaman adlandırılmış şeyler COMMAayarlandı = SPACE + "," + SPACE. Evet, bazı salaklar SPACEsabit kaldı. Onları TÜMÜNE yeniden kırdım ve kod daha okunaklıydı ve kolej işe alınan şeyleri daha fazla izleyebildi ve bir şeyin gerçekte neye ayarlanmış olduğunu bulmak için 6 seviyeye indirgeme yapmadan bunları düzeltebildi.

-1

Tek karakterli sabitler değişmezlerden daha mı iyidir?

Buralarda yüzen bir sürü çatışma var. Bakalım onları birbirinden ayırabilir miyim?

Sabitler şunları sağlar:

  • semantik
  • gelişim sırasında değişim
  • dolaylı söz

Tek bir karakter ismine gitmek sadece anlambilimi etkiler. Bir isim yorum olarak faydalı olmalı ve bağlamı netleştirmelidir. Değeri değil, anlamı ifade etmelidir. Tüm bunları tek bir karakterle yapabiliyorsa para cezası. Olmazsa, lütfen yapma.

Değişim sırasında değişmez ve değişmeyen bir durum değişebilir. Sihirli sayı konusunu ortaya çıkaran şey budur. Dizeler de sihirli sayılar olabilir.

Eğer anlamsal anlam varsa ve her ikisi de sabit olduğundan, o zaman sabitin değişmezden daha değerli olup olmadığı dolaylı olarak indirgenir.

Dolaylı aktarım, dolaysız olandan başka herhangi bir sorunu çözebilir.

İndirme, sihirli sayı problemini çözebilir çünkü tek bir yerde bir fikir için bir değere karar vermenize izin verir. Anlamsal olarak, buna değer olması için adın bu fikrin net olduğunu belirtmesi gerekir. İsim fikirle ilgili olmalı, değerle değil.

İndirme abartılabilir. Bazıları değişiklik yapmak için değişmezleri aramayı ve değiştirmeyi tercih ediyor. Bu, 42'nin açıkça hayatın anlamı olduğu ve atom sayısı molibden olan 42 ile karıştırılmadığı sürece sorun değil.

Tek bir harfle bunun gibi yararlı ayrımlar yapıp yapmamanız büyük oranda içeriğe bağlıdır. Ama bunu bir alışkanlık haline getiremezdim.


1
Anlamsal anahtardır. Eğer ve "A" basitçe "A" olmaktan daha anlamlıdırlarsa, o zaman aynı semantiği aynı "referans" a bağlamak gerekir. Sabit olup olmaması önemli değil. Tamamen katılıyorum.
oopexpert

-1

Çoğunluk görüşüne felsefi bir contrapunctus olarak, karmaşık olmayan 19. yüzyıl Fransız köylü programcısını takdir eden bazılarımız olduğunu belirtmeliyim ve

monotonluğunu, sonsuz netliğini, her şeyi aptalca algıladığı görüşlerini, gerçekleri ile muazzam memnuniyetini hatırladıklarını hatırladılar. "Her şeyi karıştırmak!" Turnbull'u kendisine “İltica durumundaysa dışarıda kimse olamaz” diye haykırdı.

GK Chesterton, Top ve Çapraz

Gerçeği takdir etmenin yanlış bir tarafı yoktur ve özellikle bir bilgisayarla konuşurken gerçeği belirten yanlış bir şey yoktur.

Bilgisayara yalan söylersen, seni yakalar

Perry Farrar - Germantown, Maryland (Daha Fazla Programlama İncili)


Ancak, çoğu zaman aptal olduğunu söyleyen insanlarla aynı fikirdeyim. Programlanmış FORTRAN'ı öğrenmek için çok gencim, ama 'A' = 'Q'her türlü harika şifreleme ile yeniden tanımlayabileceğinizi ve bulabileceğinizi söylemiştim . Bunu yapmıyorsun.

Daha önce gündeme getirilen i18n konularının ötesinde ("COMMA" karakterini değil, bir DECIMAL_POINT karakterinin karakterini gerçekten yeniden tanımlıyor). İnsanlara anlam ifade etmek için Fransız havuç alıntıları veya İngiliz tekli alıntılar inşa etmek bir şeydir ve sabit olması gereken değişkenler olmalıdır. Sabit olacaktı AMERICAN_COMMA := ','vecomma := AMERICAN_COMMA

Ve bir SQL Sorgu oluşturmak için bir kurucu desen kullanıyor olsaydım, daha çok görmeyi isterdim

sb.append("insert into ")
 .append(table_name)
 .append(" values ")
 .append(" ( ")
 .append(val_1)
 .append(",")
 .append(val_2)
 .append(" ); ")

her şeyden önce, ama eğer sabit ekleyecekseniz,

INSERT_VALUES_START = " ( "
INSERT_VALUES_END = " ) "
INSERT_VALUES_SEPARATOR = " , "
QUERY_TERMINATOR = ";"

sb.append("insert into ")
 .append(table_name)
 .append(" values ")
 .append(INSERT_VALUES_START)
 .append(val_1)
 .append(INSERT_VALUES_SEPARATOR)
 .append(val_2)
 .append(INSERT_VALUES_END)
 .append(QUERY_TERMINATOR)

Bununla birlikte, başka bir programda (veya yazımda) hiç izlediyseniz, bazı ilginç tuhaflıklar fark edebilirsiniz. Hepimiz yıldız yazarı değiliz. Birçoğumuz geç programlamaya girdik veya Sovyet klavyeleriyle büyüttük (anahtarlar üzerinize yazıyor) ve klavyede bulmaya çalışmak yerine tek tek harfleri kesip yapıştırmayı ve / veya otomatik tamamlamaya güvenmeyi seviyoruz .

Hiçbir şey sizin için bir dizgiyi otomatik olarak tamamlayamaz, bu nedenle 'con' tuşuna basarak virgül alabilirsem, alt-boşluk, aşağı, aşağı, aşağı, 'con', alt-boşluk, aşağı tuşlarına basarak bir fiyat teklifi alabilirsiniz. aşağı, girin. Bunu sadece yapabilirim.


Dize değişmezleri hakkında hatırlanması gereken bir diğer şey, derlenme biçimleridir. En azından Delphi'de, (yığınını kafasına taktığım tek dil budur), değişmezlerinizi her bir işlevin yığına fırlatırsınız. Yani, bir çok değişmez = ek yükü çok fazla; ",", function_A'da, "," function_B "de", "ile aynı bellek biti değildir. Bununla mücadele etmek için, yan yana inşa edilip bağlanabilen bir" kaynak dizgisi "vardır - ve i18n öğelerini böyle yaparlar (killing iki kovanlı iki kuş) Python'da tüm yazı diziniz değişmez nesnelerdir ve kullanımı hoş görünebilir utils.constants.COMMA.join(["some","happy","array","strings"]), ancak bu sayfada tekrar tekrar tekrarlanan noktalar için harika bir fikir değildir.


-4

Ama ne zaman virgül göstermek için ',' dan farklı bir sembol kullanmaya başlayacağız?

Yerelleştirme için.

İngilizce konuşulan ülkelerde, ondalık basamağın tamamını ve kesirli kısımlarını ayıran sembol “ondalık basamağı” adını verdiğimiz “.” Dır. Diğer birçok ülkede, sembol "," dir ve yerel dilde genellikle "virgül" denir. Benzer şekilde, İngilizce konuşulan ülkelerin üç basamaklı grupları büyük sayılarda (bir milyon için 1.000.000 gibi) ayırmak için "," kullandıkları yerlerde, virgülleri ondalık nokta olarak virgül kullanan ülkeler (1.000.000) kullanırlar.

Bu yüzden eğer globalleşme yapıyorsanız DECIMAL_POINT ve COMMA sabitlerini yapmak için bir durum var.


2
Ancak daha sonra COMMA ve DECIMAL_POINT varlıklar için doğru adlar değildir (bu yüzden muhtemelen aşağı oy kullandınız).
Kyle Strand,

Belirli yerelleştirilmiş sürümleri derlemeniz gerekir. Değişmez sabitler bunun için uygun değildir; Bu kullanım senaryosu tanım dosyalarına çağrı yapar ve bunlara bakar (sabitleri içerebilir, ancak sabit karakterleri aramaz).
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.