Bu sembolik bir sabit overkill kullanımı mı?


34

Yazılım mühendisliği konusunda oldukça yeniyim ve bir öğrenme alıştırması olarak bir satranç oyunu yazdım. Arkadaşım bir göz attı ve kodumun böyle göründüğünü belirtti.

for (int i = 0; i < 8; i++){
    for (int j = 0; j < 8; j++){

Olması gerektiği konusunda ısrar ederken

for (int i = 0; i < CHESS_CONST; i++){
    for (int j = 0; j < CHESS_CONST; j++){

daha iyi bir sembol ismi ile şu anda düşünmek için canımı sıkmayacağım.

Şimdi tabii ki genellikle sihirli sayılar kullanmaktan kaçınmayı biliyorum, ama o zamandan beri hissediyorum

  1. bu sayı asla değişmeyecek;
  2. isim kod boyunca pek çok yerde kullanıldığı için bu isim bu kadar açıklayıcı olamazdı; ve
  3. Bir satranç programı için kaynak kodundan geçen herkes satranç hakkında 8'in ne işe yaradığını bilecek kadar çok şey bilmeli,

sembolik bir sabite gerçekten gerek yok.

Peki siz ne düşünüyorsunuz? Bu overkill mi, yoksa kongre ile gidip bir sembol kullanmalı mıyım?


46
CHESS_CONST, 8 sayısını kullanmaktan çok daha kötü, ancak açıklayıcı bir isme sahip bir sabit, bir gelişme olabilir. Kodda neyin 8'in ne anlama geldiğini bilmesi gerektiğini söylüyorsunuz, ancak bu doğru değil. Bağlamsız bir tamsayı değişmezi, bir dizi hareket, tahtadaki taşların sayısı gibi herhangi bir şey anlamına gelebilir. Sabit için açıklayıcı bir isim, niyeti açık ve dolayısıyla kodun anlaşılmasını kolaylaştıracaktır.
JacquesB

43
Şahsen, sihir sayısından çok daha fazla ciddiye aldığım şey isimler ive jdöngü değişkenleridir. Hayatım boyunca, hangisinin rütbeyi temsil etmesi ve hangisinin dosyayı temsil etmesi gerektiğini çözemiyorum. Sıralar, 1.8 arasındadır ve dosyalar a..h arasındadır, ancak sizin durumunuzda, ikisi de ive j0..7 arasındadır, bu da hangisinin hangisi olduğunu görmeme yardımcı olmaz. Ben bilmem bazı uluslararası mektup sıkıntısı kriz var mı, yoksa ne isimlerinin değiştirilmesi ile yanlış rankve file?
Jörg W Mittag

4
Bir saniye için şeytanın avukatı oyna; Birinin 8 numaralı sihirli numarasını kullandıkları satranç kodunu okuduğunuzu hayal edin. Ne için kullanıldığını bildiğinizi varsayabilir misiniz? Nasıl% 100 emin olabilirsin? Başka bir anlama gelme olasılığı var mı? Bir varsayımda bulunmak zorunda olmasaydın, biraz daha iyi olmaz mıydı? Varsayımınızın doğru olup olmadığını anlamak için kod boyunca ne kadar zaman harcayabilirsiniz? Kod, anlamlı ve anlayışlı bir ad kullanarak kendi kendini belgeliyor olsaydı daha az zaman harcar mıydınız?
Ben Cottrell

16
@ JacquesB: Gerçekten de. 8 rütbe, 8 dosya, 8 piyon var. Bazı satranç motorları, belirli parçaların, belirli alanların ve belirli hareketlerin kendilerine eklenmiş noktalara sahip olduğu ve motorun en yüksek puanı alan hareketi seçtiği bir puan sistemi kullanır. 8 böyle bir puan olabilir. 8 varsayılan bir arama derinliği olabilir. Hemen hemen her şey olabilir.
Jörg W Mittag

9
Örneğin, bir foreach döngüsü kullanmayı düşünürdüm foreach(var rank in Ranks). Her iki döngüyü de her bir elemanın bir (sıralama, dosya) tupleı olarak birleştirmeyi düşünürdüm.
CodesInChaos

Yanıtlar:


101

Ben isim kesinlikle (gibi daha açıklayıcı olması gerektiğini düşünüyorum gerçi imho arkadaşınız, sembolik adı kullanılarak haklı BOARD_WIDTHyerine CHESS_CONST).

Sayı, programın ömrü boyunca hiçbir zaman değişmeyecek olsa bile, programınızda 8 sayısının farklı bir anlamla ortaya çıkacağı başka yerler olabilir. BOARD_WIDTHTahta genişliğinin kastedildiği her yerde "8" değiştirilmesi ve farklı bir şey kastedildiğinde başka bir sembolik isim kullanılması, bu farklı anlamları açık, açık ve genel programınızın daha okunaklı ve sürdürülebilir olmasını sağlar. Ayrıca, kodun pano genişliğine bağlı tüm kodları hızlı bir şekilde tanımlamanız gerektiğinde, programınız üzerinde genel bir arama (veya ortamınız sağlarsa ters sembol araması) yapmanızı sağlar.

Ayrıca , numaralar için adların nasıl seçileceğini (veya nasıl seçmeyeceğini) bir tartışma için bu eski SE.SE yayınına bakınız .

Bir yan not olarak, burada yorumlarda tartışıldığı için : eğer gerçek programınızın kodunda, değişkenin isatırlara ve jtahtanın sütunlarına mı yoksa tersi olduğuna mı dikkat eder, o zaman değişken isimlerinin seçilmesi önerilir. rowve gibi ayrım netleştirmek col. Bu tür isimlerin yararı, yanlış kodun yanlış görünmesidir.


22
Eğer OP gerçekten harika bir satranç motoru yazmışsa, 3D satranç veya diğer varyantları içerecek şekilde genişletmek istese, o zaman 8'lerin değişmesi gereken bir meydan okuma olacak.
Steve Barnes

32
@SteveBarnes: Bu tür argümanlardan kaçınmaya çalışıyorum, çünkü "
Doktor Brown

4
@IllusiveBrian Bu iki nedenden dolayı klasik bir "saman adam" argümanıdır: (1) sadece bir sabit tanımlamak, programcının hala "8" (kaza, tasarım veya kötülükten dolayı!) Ve (2) yazamayacağı anlamına gelmez. sadece sabit bir BOARD_WIDTH = 8 olduğu için BOARD_WIDTH programını programda belirli bir yerde kullanmak için doğru sabit yapmaz .
alephzero

3
@Blrfl ... veya kodun değiştirilmesine yol açacaktır. Gelecekte neyin değişebileceğini anlamak ve buna göre kod yazmak geliştiricinin sorumluluğundadır. Gibi gereksinimleri kodlama değişmeyecek sorunlara neden olur, ancak diğer aşırı iyi değil.
Malcolm

4
@corsiKa Döngü değişkenleri fiziksel eksenlere karşılık geldiğinde, bunlar satranç, dosya, rütbe için x, y veya satır, col veya adlandırılmalıdır.
user949300

11

Tamam, işte birkaç yorumum:

Sihirli sayılardan kurtulmak harika bir fikir. DRY olarak bilinen ve genellikle yanlış tanıtılan bir kavram var, ancak fikir projenizdeki kavramların bilgisini çoğaltmamanızdır. Yani ChessBoard adlı bir sınıfınız varsa, buna bağlı olarak BOARD_SIZE veya ChessBoard.SIZE adlı bir sabit tutabilirsiniz. Bu şekilde, bu bilgi için tek bir kaynak var. Ayrıca, bu daha sonra okunabilirliğe yardımcı olur:

for (int i = 0; i < ChessBoard.SIZE; i++){
  for (int j = 0; j < ChessBoard.SIZE; j++){

Sayı hiç değişmese bile, programınız kesinlikle daha iyi. Bunu okuyan herhangi biri kodun ne yaptığı hakkında daha fazla bilgi bilir.

Kötü bir isim, isimsiz olmaktan daha kötüdür, ancak bu, bir şeyin isimlendirilmemesi gerektiği anlamına gelmez. Sadece adını değiştir. Bebeği banyo suyuyla atmayın. : p Adın ne tarif ettiğini iyi anladığınız sürece açıklayıcı olabilir. Ardından, bu kavram birden fazla farklı şey için kullanılabilir.


8
Bu, sadece önceden yapılmış ve en iyi yanıtta açıklanan noktaları tekrar ediyor gibi görünüyor
gnat

-7

Asıl istediğin, ad nauseum adındaki veya çıplak olan ad nauseum referanslarını sabitlere atmak.

for_each_chess_square (row, col) {
  /*...*/
}

Eğer gerçekten bu tür döngüleri tekrarlayarak ve ne olursa olsun tekrarlayarak sabiti çoğaltacaksanız, buna bağlı kalmak en iyisidir 8.

8kendini tanımlayan; başka bir şey için duran bir makro değil.

Asla Gonna'yı (TM) 9x9'luk bir satranç programına dönüştürmüyorsunuz ve eğer yaparsanız, 8'in çoğalması en büyük zorluk olmayacak.

Belirteç 8 için 150.000 satırlık bir kod tabanı arayabilir ve hangi olayların saniye cinsinden ne anlama geldiğini sınıflandırabiliriz.

Daha da önemlisi, kodu modüler hale getirerek satranç bilgisinin mümkün olduğu kadar az yerde yoğunlaşmasını sağlamaktır. Sembolik bir isimle 8'e atıfta bulunan, satrança özgü sorumlulukla bağlanmış otuz yedi modülden, edebi bir 8'in gerçekleştiği bir satrança özgü üç modüle sahip olmak daha iyidir.

Bu 8 sabit programınızdaki bir gerilim kaynağı olduğunda veya bu durumda kolayca düzeltebilirsiniz. Şimdi olan gerçek sorunları düzeltin. Bu belirli 8 tarafından engellendiğinizi hissetmiyorsanız, bu içgüdü ile gidin.

Gelecekte alternatif tahta boyutlarını desteklemek istediğinizi varsayalım. Bu durumda, bu döngüler adlandırılmış bir sabit kullanıp kullanmadıklarını değiştirmek zorunda kalacaklardır 8, çünkü boyutlar board.widthve gibi bir ifade tarafından alınacaktır board.height. BOARD_SIZEBunun yerine varsa 8, bu yerleri bulmak daha kolay olacaktır. Yani bu daha az çaba. Ancak, değiştirilmesi çaba hakkında unutmamak gerekir 8ile BOARD_SIZEilk etapta. Genel çaba daha düşük değil. Birinin kod üzerinde geçiş 8yapması BOARD_SIZEve ardından alternatif boyutları desteklemek için bir başkasının değiştirilmesi, sadece 8alternatif boyut desteğinden geçmekten daha ucuz değildir .

Buna tamamen soğuk, nesnel bir risk / fayda analizinden de bakabiliriz. Programın içinde şimdi çıplak sabitler var. Bunlar sabit ile değiştirilirse, faydası yoktur; program aynı. Her türlü değişiklikte sıfır riski yoktur. Bu durumda, küçük. Yine de, hiçbir faydası olmadan risk alınmamalıdır. Bu akıl yürütme karşısındaki değişikliği "satmak" için, bir fayda varsaymak zorundayız: farklı bir programla yardımcı olacak gelecekteki bir fayda: Programın şimdi bulunmayan gelecekteki bir versiyonu. Böyle bir program planlanmış ediliyorsa, bu hipotez ve ilişkili akıl vardır niyetli bona ve ciddiye alınmalıdır.

Örneğin, bu sabitleri daha da artıracak daha fazla kod eklemekten kaçınıyorsanız, onlardan kurtulmak isteyebilirsiniz. Bu sabitlerin örnekleri, yaklaşık olarak şimdiye kadar varolanların hepsi ise, neden rahatsız ediyorlarsa.

Ticari bir yazılım üzerinde çalıştıysanız, yatırım getirisi argümanları da geçerli olacaktır. Bir program satmıyorsa ve bazı sabit kodlanmış sayıları sabit olarak değiştirmek satışları iyileştirmeyecekse, çaba için tazminat almayacaksınız. Değişimin zaman yatırımının getirisi sıfırdır. Yatırım Getirisi argümanları paranın ötesine geçiyor. Bir program yazdınız, zamana ve emeğe yatırım yaptınız ve bundan bir şey çıkardınız: iadeniz, "R" iniz. Bu değişikliği tek başına yaparak, "R" den daha fazlasını elde edersiniz, ne olursa olsun, o zaman elbette. Daha fazla gelişme için bir planınız varsa ve bu değişiklik "R" inizi geliştirirse, aynen öyle. Değişiklik sizin için acil veya öngörülebilir "R" içermiyorsa, unut gitsin.


13
8bu kendini tanımlayan DEĞİL, herhangi bir şey ifade edebilecek bir sayıdır. Belki de 9x9'luk bir satranç oyunu oynamak istiyorlar, neden olmasın? 150.000 kod satırınız varsa, kodda her birinin ne 8anlama geldiğini ezberlemeniz mümkün değildir , ve yapabilseniz bile, neden istiyorsunuz? Bu sadece bir sürü ekstra güçlük. Modülerleştirmeye gelince , bunun 8gibi bir şeyle değiştirmek NUM_RANKSmodülerliğe zarar vermez, aslında kodun kontrol edilmesini kolaylaştırdığı için yardımcı olur.
Jerfov2

4
@Kaz Ben de yapıyorum. Ve sonra, çok garip hatalar ortaya koyuyorum çünkü bir avuç kullanım, düşündüğüm gibi değildi, çünkü çok sayıda değişime bu kadar dikkat etmek ve her seferinde doğru olmak zor. Bu nedenle ilk önce bu senaryoya girmekten kaçınıyorum, bu yüzden içine girmeyi düşünen tavsiyeleri destekleyemiyorum.
doppelgreener

1
"Ancak, değiştirilmesi çaba hakkında unutmamak gerekir 8ile BOARD_SIZEilk etapta" her şey şekle çalışırken kodun üzerine incelemeye geçirdiği zaman - 8büyük olasılıkla zaman yerine harcanan aşacaktır şu andan itibaren program aylarda yaptığı 8ile anlamlı bir modül seviyesi sabiti.
Christian Dean

1
@doppelganger Bu senaryo zaten burada. Söylemiyorum, sabitleri kullanan bir satranç programı alın ve bunları 8 ile değiştirin. Ben de, "henüz yazılı olmayan bir satranç programında sabitleri kullanmamaya karar ver" demiyorum
Kaz

1
@Kaz Niçin 8'in üzerindeki tüm kodu okumak zorunda kalmayı ve neden sadece 3 saniye daha anlamlı bir isim vererek ekleyebiliyorken bağlamı yanlış elde etmek istersiniz? Sabitin gerçek değerini bilmek gelince, bir değişkenin kesin değerini bulmak kodda bazı sihirli tamsayıların ne anlama geldiğini geriye doğru mühendislik yapmaya çalışmaktan çok daha kolaydır
Jerfov2
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.