it-swarm-tr.com

Değerleri uygulamalarımıza sabitlemek hiç iyi bir fikir değil mi?

Değerleri uygulamalarımıza sabitlemek hiç iyi bir fikir değil mi? Ya da değişmeleri gerektiğinde bu tür değerleri dinamik olarak çağırmak her zaman doğru bir şey midir?

45
Edward

Evet, ama yap açık.

Yapmak:

  • sabitler kullanın
  • a açıklayıcı değişken adı kullan

Yapma:

64
J.K.

Şimdiye kadar bu soru-cevap hakkında garip bulduğum hiç kimse aslında açıkça "sabit kod" veya daha da önemlisi alternatifleri tanımlamak için girişimde bulunmamıştır.

tl; dr: Evet, is bazen sabit kod değerleri için iyi bir fikir, ancak ne zaman; tamamen bağlama bağlıdır.

Soru bunu değerler olarak daraltıyor --- sihirli sayılar , ama iyi bir fikir olup olmadıklarının cevabı = aslında ne için kullanılıyorlar !

"Sabit kodlanmış" değerlere birkaç örnek:

  • Yapılandırma değerleri

    command.Timeout = 600 Gibi ifadeler gördüğümde küfrediyorum. Neden 600? Buna kim karar verdi? Daha önce zaman aşımına uğradı mı ve birisi, altta yatan performans sorununu düzeltmek yerine zaman aşımını bir saldırı olarak yükseltti mi? Yoksa aslında işlem süresi için bilinen ve belgelenmiş bir beklentidir?

    Bunlar sihirli sayılar olmamalı veya sabitler, anlamlı bir adla bir yerde bir yapılandırma dosyasında veya veritabanında dışsallaştırılmalıdır, çünkü optimal değerleri büyük ölçüde veya tamamen uygulamanın bulunduğu ortam tarafından belirlenir içeri giriyor.

  • Matematiksel formüller

    Formüller genellikle oldukça statik olma eğilimindedir, böylece içindeki sabit değerlerin doğası gerçekten önemli değildir. Bir piramidin hacmi (1/3) b * h'dir. 1 veya 3'ün nereden geldiğini önemsiyor muyuz? Pek sayılmaz. Önceki bir yorumcu haklı olarak diameter = radius * 2 'Un muhtemelen diameter = radius * RADIUS_TO_DIAMETER_CONVERSION_FACTOR' Dan daha iyi olduğuna dikkat çekti - ama bu yanlış bir ikilik.

    Bu tür bir senaryo için yapmanız gereken şey bir fonksiyon oluşturmaktır. Formül ile nasıl geldi bilmek zorunda değilim ama yine de ne için olduğunu bilmem gerekiyor. Yukarıda yazılı saçmalıklardan herhangi biri yerine, volume = GetVolumeOfPyramid(base, height) yazarsam aniden her şey çok daha net hale gelir ve sihirli sayılara sahip olmak inside işlevi (return base * height / 3) Çünkü formülün sadece bir parçası oldukları açıktır.

    Buradaki anahtar elbette kısa ve basit işlevlere sahip olmaktır. Bu, 10 bağımsız değişken ve 30 satır hesaplama içeren işlevler için çalışmaz. Bu durumda işlev kompozisyonunu veya sabitleri kullanın.

  • Alan adı/işletme kuralları

    Bu her zaman gri alandır, çünkü değerin tam olarak ne olduğuna bağlıdır. Çoğu zaman, sabitlere dönüşmeye aday olan bu sihirli sayılardır, çünkü bu program mantığını zorlaştırmadan anlaşılmasını kolaylaştırır. if Age < 19 İle if Age < LegalDrinkingAge Testini düşünün; muhtemelen can sabit olmadan neler olup bittiğini anlayabilirsiniz, ancak açıklayıcı başlık ile daha kolaydır.

    Bunlar ayrıca fonksiyon soyutlaması için aday olabilir, örneğin function isLegalDrinkingAge(age) { return age >= 19 }. Tek şey, iş mantığınızın bundan çok daha kıvrımlı olması ve her biri 20-30 parametre ile düzinelerce işlev yazmaya başlamak mantıklı olmayabilir. Nesneleri ve/veya işlevleri temel alan net bir soyutlama yoksa sabitlere başvurmak sorun olmaz.

    Eğer vergi departmanı için çalışıyorsanız, gerçekten, gerçekten külfetli ve dürüstçe AttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR) yazmak anlamsız olur. Bunu yapmayacaksınız, AttachForm("B-46") olacaksınız çünkü orada çalışmış veya çalışmış olan her bir geliştirici, "B-46" nın bir tek mükellef dosya falan filan filan filan - form kodları alan adının kendisinin bir parçasıdır, asla değişmezler, bu yüzden gerçekten sihirli sayılar değildir.

    Bu nedenle, iş mantığında sabitleri az miktarda kullanmalısınız; temel olarak, bu "sihirli numara" nın aslında sihirli bir sayı olup olmadığını veya alan adının iyi bilinen bir yönünün olup olmadığını anlamalısınız. Etki alanı ise, değişmesi için gerçekten iyi bir şans olmadığı sürece bunu yumuşak kodlarla kodlamazsınız.

  • Hata kodları ve durum bayrakları

    Bunlar neverPrevious action failed due to error code 46 İle vurulmuş herhangi bir zavallı piç size söyleyebileceği gibi, sabit kod için uygundur. Diliniz destekliyorsa, bir numaralandırma türü kullanıyor olmalısınız. Aksi takdirde, genellikle belirli bir hata türü için geçerli değerleri belirten sabitlerle dolu bir dosya/modülünüz olur.

    Bir hata işleyicide return 42 İfadesini görmeme izin verme, capiche? Bahane yok.

Muhtemelen birkaç senaryoyu bıraktım ama bence bunların çoğunu kapsıyor.

Yani, evet, zor kodlu şeyler için bazen kabul edilebilir bir uygulamadır. Sadece tembel olmayın; düz eski özensiz kodlardan ziyade bilinçli bir karar olmalıdır.

27
Aaronaught

Bir sayıya tanımlayıcı atamanın çeşitli nedenleri vardır.

  • Sayı değişebilirse, bir tanımlayıcıya sahip olmalıdır. NUMBER_OF_PLANETS öğesini bulmak, her 9 örneğini aramak ve 8 olarak değiştirilip değiştirilmemesi gerektiğini düşünmekten çok daha kolaydır. yazılımın farklı bir dilde kullanılması gerekiyorsa değişmesi gerekebilir ve bu önceden tahmin edilmesi zor bir şeydir.)
  • Rakamın herhangi bir şekilde yazılması zorsa. Pi gibi sabitler için, büyük olasılıkla yanlış bir şekilde birkaç yerde yeniden yazmaktan ziyade bir maksimum kesinlik tanımı vermek daha iyidir.
  • Sayı farklı yerlerde ortaya çıkarsa. Bitişik işlevlerde 45'in iki kullanımına bakmanız ve aynı anlama gelip gelmediklerini merak etmemeniz gerekir.
  • Anlamı anında tanınamıyorsa. Herkesin 3.14159265 ... 'in ne olduğunu bildiğini varsaymak güvenlidir. Herkesin yerçekimi sabitini, hatta pi/2'yi tanıyacağını varsaymak güvenli değildir. ("Herkes" burada yazılımın doğasına bağlıdır. Sistem programcılarının Unix izin bitlerinin veya benzerlerinin sekizlik temsilini bilmesi beklenebilir. Deniz/deniz mimarisi yazılımında, önerilen bir gövdenin Froude sayısını ve hızını 1.1 veya daha yüksek bir sürüm olup olmadığına bakın, üzerinde çalışması gereken herkes için mükemmel bir şekilde açıklayıcı olabilir.)
  • Bağlam tanınabilir değilse. Herkes bir saatte 60 dakika olduğunu bilir, ancak miktarın bir zaman değeri veya bir oran değeri olduğuna dair herhangi bir belirti yoksa, çarpma veya 60'a bölme belirsiz olabilir. .

Bu bize zor kodlayan değişmez değerler için kriterler verir. Değişmez olmalılar, yazmaları zor olmamalı, sadece tek bir yerde veya bağlamda olmalı ve tanınabilir bir anlam taşımalıdırlar. Örneğin 0'ı ARRAY_BEGINNING veya 1'i ARRAY_INCREMENT olarak tanımlamanın bir anlamı yoktur.

7
David Thornley

Diğer cevaplara ek olarak. Mümkün olduğunda dizeler için sabitler kullanın. Tabii ki, sahip olmak istemiyorsun

const string server_var="server_var";

ama sahip olmalısın

const string MySelectQuery="select * from mytable;";

(her zaman belirli bir tablodan tüm sonuçları almak istediğiniz bir sorgunuz olduğunu varsayarsak)

Bunun dışında 0 dışında herhangi bir sayı için sabitler kullanın (genellikle). 255 izin bit maskesine ihtiyacınız varsa,

const int 8th_bit=255; //or some other obscure naming scheme that equates to 255.

onun yerine kullan

const int AllowGlobalRead=255;

Tabii ki, sabitlerle birlikte, numaralandırıcıların ne zaman kullanılacağını bilir. Yukarıdaki dava muhtemelen bir tanesine uygundur.

5
Earlz

Değerleri uygulamalarımıza sabitlemek hiç iyi bir fikir değil mi?

Ben sabit kod değerleri sadece değerleri belirtimi belirtilmiş ise (belirtimin son sürümünde), ör. HTTP OK yanıtı her zaman 200 (RFC'de değişmedikçe), bu nedenle, (bazı kodlarımda) aşağıdaki gibi sabitleri göreceksiniz:

public static final int HTTP_OK = 200;

Aksi takdirde, sabitleri özellikler dosyasında saklarım.

Spesifikasyonları belirtmemizin nedeni, spesifikasyonlardaki sabitleri değiştirmenin, paydaşların değişikliği gözden geçireceği ve onaylayacağı/onaylayamayacağı değişiklik yönetimi gerektirmesidir. Hiçbir zaman bir gecede olmaz ve onay için aylar/yıllar alır. Birçok geliştiricinin spesifikasyonlar (örn. HTTP) kullandığını unutmayın, bu yüzden değiştirmek milyonlarca sistemi kırmak anlamına gelir.

4
Buhake Sindi

Sabit kodlamayı düşündüğünüz şeye bağlıdır. Herhangi bir ve tüm kodlanmış şeylerden kaçınmaya çalışırsanız, softcoding bölge ile sonuçlanır ve yalnızca içerik oluşturucunun yönetebileceği bir sistem yaparsınız (ve bu nihai sabit koddur)

Birçok şey makul bir çerçevede kodlanmıştır ve çalışır. yani bir C # uygulamasının giriş noktasını değiştirememem için teknik bir neden yok (statik boşluk Ana), ancak herhangi bir kullanıcı için herhangi bir sorun yaratmayan sabit kodlama (ara sıra SO sor =)

Kullandığım temel kural, tüm sistemin durumunu etkilemeden değişebilen ve değişecek her şeyin uygun olması gerektiğidir.

Yani, IMHO, hiç değişmeyen şeyleri (pi, yerçekimi sabiti, matematiksel bir formülde sabit - bir kürenin hacmini düşün) sabit kodlamak değil.

Ayrıca, sisteminizde herhangi bir durumda programlama gerektirecek şeyleri veya süreçleri sabit kodlamamak saçmadır, yani eklenen herhangi bir alan bakım geliştiricisinin gerektirmesi durumunda kullanıcının bir forma dinamik alanlar eklemesine izin vermek zahmetlidir içeri gir ve o şeyin çalışmasını sağlayacak bir senaryo yaz Ayrıca, bazı yapılandırma aracı oluşturmak aptalca (ve kurumsal ortamlarda birkaç kez gördüm), bu nedenle hiçbir şey sabit kodlanmamıştır, ancak, yalnızca BT departmanındaki geliştiriciler bunu kullanabilir ve kullanmaktan biraz daha kolaydır. Visual Studio'da yapın.

Sonuç olarak, bir şeyin sabit kodlanıp kodlanmayacağı iki değişkenin bir fonksiyonudur:

  • değer değişecek mi
  • değerdeki bir değişiklik sistemi nasıl etkiler?
4
SWeko
  • değer değişebiliyorsa ve gerçekten değişebiliyorsa, söz konusu çaba beklenen getiriyi aşmadığı sürece mümkün olduğunca yumuşak kodlayın
  • bazı değerler olamaz yumuşak kodlanabilir; bu (nadir) vakalarda Jonathan'ın kurallarına uyun
3
Steven A. Lowe

Kodunuzdan veri çıkarabildiğinizde, geriye kalanları geliştirdiğini fark ettim. Yeni düzenlemeler fark etmeye ve kodunuzun tüm bölümlerini geliştirmeye başlarsınız.

Sabitleri çıkarmak için çalışmak iyi bir fikirdir, aptalca bir kural olarak düşünmeyin, daha iyi kodlama fırsatı olarak düşünün.

En büyük avantaj, benzer sabitleri kod gruplarındaki tek fark olarak bulabilmenizdir - bunları dizilere ayırmak, bazı dosyaları boyutlarının% 90'ını azaltmama ve bu arada birkaç kopyala ve yapıştır hatasını düzeltmeme yardımcı oldu. .

Henüz veri çekmemenin tek bir avantajı görmedim.

3
Bill K

Son zamanlarda iki lat/uzun çift arasındaki mesafeyi doğru bir şekilde hesaplamak için bir MySQL fonksiyonunu kodladım. Sadece pisagor yapamazsınız; boylam çizgileri kutuplara doğru enlem arttıkça birbirine yaklaşıyor, bu yüzden biraz kıllı trig var. Mesele şu ki, dünyanın yarıçapını temsil eden değeri mil olarak sabit kodlayıp kodlamamak konusunda oldukça yırtılmıştım.

Aslında, lat/lng çizgileri, örneğin ay üzerinde birbirine çok daha yakın olmasına rağmen bunu yaptım. Ve benim fonksiyonum, Jüpiter'deki noktalar arasındaki mesafeleri büyük ölçüde düşük raporlayacaktı. Dünya dışı bir yere girmiş olduğum web sitesinin oranlarının oldukça ince olduğunu düşündüm.

2
Dan Ray

Bu sizin dilinizin derlenip derlenmediğine bağlıdır. Derlenmiş değilse, büyük bir anlaşma değildir, programcı olmayan biri için biraz hassas olsa bile, kaynak kodu düzenlersiniz.

Derlenmiş bir dille programlama yapıyorsanız, bu kesinlikle iyi bir fikir değildir, çünkü değişkenler değişirse, yeniden derlemeniz gerekir, bu da bu değişkeni ayarlamak istiyorsanız büyük bir zaman kaybıdır.

Değişkenini dinamik olarak değiştirmek için biraz kaydırıcı veya arayüz yapmanız gerekmez, ancak yapabileceğiniz en az şey bir metin dosyasıdır.

Örneğin benim dev projemle, her zaman bir config dosyasına yazdığım bir değişkeni yüklemek için ConfigFile sınıfını kullanıyorum.

1
jokoon

Sabitlerin olduğu iki durum (en azından bence):

  1. Başka hiçbir şeyle ilgili sabitler; bu sabitleri istediğiniz zaman, başka bir şey değiştirmek zorunda kalmadan değiştirebilirsiniz. Örnek: Izgara sütununun varsayılan genişliği.

  2. Kesinlikle değişmez, hassas, bariz sabitler, "haftadaki gün sayısı" gibi. days = weeks * 7 Değiştiriliyor 7 sabiti ile DAYS_PER_WEEK neredeyse hiç değer sağlamaz.

1
user281377

Jonathan'la tamamen aynı fikirdeyim ama tüm kurallarda istisnalar var ...

"Spesifikasyondaki sihirli sayı: Koddaki sihirli sayı"

Temel olarak, onlar için açıklayıcı bağlam elde etmek için makul denemelerden sonra spesifikasyonda kalan sihirli sayıların koda olduğu gibi yansıtılması gerektiğini belirtir. Kodda sihirli sayılar kalırsa, onları izole etmek ve Kökeni ile açıkça bağlantılı hale getirmek için her türlü çaba gösterilmelidir.

Veritabanından eşlenen değerlerle iletileri doldurmak için gerekli olan birkaç arabirim sözleşmesi yaptım. Çoğu durumda, eşleme oldukça basittir ve Jonathan'ın genel kılavuz çizgilerine sığar, ancak hedef mesaj yapısının sadece berbat olduğu durumlarla karşılaştım. Yapıda aktarılması gereken değerlerin% 80'inden fazlası, uzak sistemin özellikleri ile uygulanan sabitlerdi. bu, mesaj yapısının devasa olmasıyla birleşti ve bu tür sabitlerin bir sürü'sinin doldurulması gerektiğini söyledi. Çoğu durumda bir anlam veya neden sağlamadılar, sadece "M'yi buraya koy" veya "4.10.53.10100.889450.4452'yi buraya koy" dediler. Ben de sonuç kodu okunamaz hale getirecek tüm yanına bir yorum koymak için girişimde bulunmadı. Ancak bu sihirli değerlerin göründüğü kod bölümlerinin düzgün bir şekilde izole edildiğinden ve kaplarının (sınıflar, paketler) doğrudan onları uygulayan spesifikasyona işaret edecek şekilde adlandırıldığından emin oldum.

Bununla birlikte, düşündüğünüzde ... hemen hemen onu açık hale getirmekle ilgili ...

0
Newtopian

Dünyanın yerçekimi sabitinin değerini zor kodluyorsanız, kimse umursamaz. Proxy sunucunuzun IP adresini sabit kodluyorsanız, sorun yaşarsınız.

0
jwenting

Çoğunlukla hayır, ancak sabit kodlanmış değeri çoğaltmaya başladığınızda en çok sorun yaşayacağınızı belirtmek gerekir. Eğer çoğaltmazsanız (örneğin, bir sınıfın uygulanmasında sadece bir kez kullanın), o zaman sabit kullanmamak sorun yaratabilir.

0
user22908