“Çivilemek” ve “hardcode yapmak”, değerleri ayarlara veya yapılandırmaya çıkarmak yerine doğrudan program koduna sabit bir şekilde yerleştirmek anlamına gelen argo terimlerdir. Hardcode, geliştirmede en bilinen anti-örüntülerden biridir, çünkü kodun esnekliğini ve yeniden kullanılabilirliğini azaltır. Refactoring Guru'ya göre hardcode, test etmeyi, bakımı ve uygulamanın farklı ortamlara uyarlanmasını zorlaştırır. Hardcode yerine bilinçli olarak sabit kullanmak, olgun bir mimarinin işaretidir.
Ana Noktalar
Hardcode yapmak (çivilemek) — program koduna belirli bir değeri, değiştirmek için kaynak kodu düzenleme ve uygulamayı yeniden derleme gerektirecek şekilde yerleştirmek. “Çivilemek” metaforu özü tam olarak yansıtır: değer kalıcı olarak sabitlenmiştir ve koddan ancak çaba harcayarak ayrılabilir.
Hardcode örneği — bir fonksiyonun gövdesine doğrudan dize olarak yazılmış sunucu URL'si. Sunucu başka bir adrese taşınırsa, geliştiricinin koddaki dizeyi bulması, değiştirmesi, uygulamayı yeniden derlemesi ve bir sürüm yayınlaması gerekir. Doğru mimariye sahip bir uygulamada, böyle bir URL bir yapılandırma dosyasına, ortam değişkenine veya yapılandırma hizmetine çıkarılmış olurdu.
“Çivilemek” terimi daha duygusal bir anlam taşır: değerin kalıcı olarak yerleştirildiğini ve hızlı değiştirme imkanı olmadığını vurgular. Rusça konuşulan ortamda, her iki ifade de olumsuz çağrışımla tam eşanlamlı olarak kullanılır. Bazen hardcode ironik bir şekilde “bir sabitten ayrı bir sabite çıkarılmış sabit” olarak adlandırılır.
Hardcode, kodun bakım yapılabilirliği, test edilebilirliği ve genişletilebilirliği ilkelerini ihlal ettiği için bir anti-örüntüdür. Değerlerin “çivilendiği” kodda, ortam, tasarım veya mantıktaki herhangi bir değişiklik, kaynaklarda manuel arama ve değiştirme gerektirir. Bu, hata riskini artırır ve geliştirmeyi yavaşlatır.
Tipik bir mobil uygulama örneğini kullanarak hardcode'un somut sonuçlarını inceleyelim. Tüm düğmelerin kenar boşluğu, bir kaynak aracılığıyla değil de koddaki bir sayıyla tanımlanmışsa — bir tasarım değişikliği tüm geçişleri bulmayı ve değiştirmeyi gerektirecektir. Uç nokta URL'si sabit şekilde yazılmışsa — ortamlar (dev, stage, prod) arasında geçiş, yeniden derleme olmadan mümkün değildir.
| Sonuç | Açıklama | Kritiklik Seviyesi |
|---|---|---|
| Bakım zorluğu | Değişiklik tüm kodda arama gerektirir | Yüksek |
| Kopyalama hataları | Tüm geçişler bulunup değiştirilemez | Yüksek |
| Test edememe | Test verileri yerleştirilemez | Orta |
| Yerelleştirme sorunları | Koddaki metinler çevrilmez | Orta |
| Kod inceleme karmaşıklığı | Denetçi tüm bağlamları hatırlamalıdır | Düşük |
Sihirli sayılar ve sabit dizeler kullanan bir fonksiyon, hardcode'un klasik örneğidir. Bir ay sonra yazar, 18, 0.07 ve 2.5'in ne anlama geldiğini hatırlamaz. Bir yıl sonra — ekipte kimse, mantığı bozma korkusuyla bu sayıları değiştirmeye cesaret edemez. Değerleri adlandırılmış sabitlere çıkarmak, kodu kendi kendini belgeleyen hale getirir.
// Kötü: sihirli sayılar ve dizeler
fun calculatePrice(base: Double): Double {
val tax = base * 0.07
val tip = base * 0.15
val discount = if (base > 100) 10 else 0
return base + tax + tip - discount
}
Hardcode edilmiş bir veritabanı URL'si, yerel bellek içi veritabanında testlerin çalıştırılmasına izin vermez. Geliştiricinin, testten önce tam bir sunucu başlatması veya kodu düzenlemesi gerekir. Yapılandırmayı koddan çıkarmak sorunu çözer: testler test parametrelerini kullanır, üretim gerçek parametreleri kullanır ve kod değişmeden kalır.
Hardcode bir anti-örüntüdür, ancak sabit bir değerin sadece kabul edilebilir değil, aynı zamanda tercih edildiği meşru istisnalar vardır. Sınır, değişkenlik ekseni boyunca uzanır: değer uygulamanın yaşam döngüsü boyunca hiç veya neredeyse hiç değişmiyorsa, hardcode edilebilir. Potansiyel olarak değişebiliyorsa — yapılandırmaya çıkarın.
Matematiksel ve fiziksel sabitler — Pi sayısı, yerçekimi ivmesi, saniyedeki milisaniye sayısı — hardcode için güvenlidir. Bunlar doğa veya standartlar tarafından tanımlanmıştır ve değişmeyecektir. Spesifikasyonla tanımlanmış sabit dizi boyutları da sabitlenebilir, ancak sayının kökeni hakkında bir yorumla birlikte.
Saniyedeki milisaniye sayısı, zaman standardı tarafından tanımlanmış kararlı bir sabittir. Asla değişmeyeceği için onu bir config dosyasına koymanın bir anlamı yoktur. Ancak, bu tür sabitleri bile kodda “sihirli sayılar” olmaması için anlamlı bir adla bildirmek daha iyidir: 1000 yerine MILLISECONDS_IN_SECOND yazın.
// Haklı hardcode: kararlı sabitler
private const val MILLIS_IN_SECOND = 1000
private const val LOGIN_TIMEOUT_SECONDS = 30
fun formatDuration(ms: Long): String {
val seconds = ms / MILLIS_IN_SECOND
return "${seconds} sec."
}
Hardcode'tan kaçınmanın birkaç kanıtlanmış yolu vardır, her biri kendi değer türü için uygundur. Alternatif seçimi, değerin ne sıklıkta değiştiğine ve onu kimin değiştirdiğine bağlıdır: geliştirici, devops veya son kullanıcı.
Sunucu URL'leri, API anahtarları ve özellik bayrakları için JSON, YAML veya TOML biçimlerinde yapılandırma dosyaları kullanın. Android'de bu, build.gradle içinde buildConfigField veya res/values/config.xml'dir. iOS'te — Info.plist veya xcconfig. Yapılandırmalar uygulamayla birlikte derlenir, ancak farklı derleme şemaları için farklı olabilir.
Sırlar (tokenlar, şifreler) ve ortam parametreleri için ortam değişkenleri kullanın. Bunlar depoya girmez ve dev, stage ve prod sunucularında farklılık gösterebilir. Mobil geliştirmede, ortam değişkenleri genellikle Xcode derleme şemaları veya Gradle'daki build flavors aracılığıyla taklit edilir.
Dizeler, renkler, boyutlar, görseller kaynak dosyalarına çıkarılmalıdır: Android'de strings.xml, iOS'te Localizable.strings, Flutter'da ARB dosyaları. Bu, yerelleştirmeyi, farklı ekranlara uyarlamayı ve koyu temayı kolaylaştırır. Kaynaklardaki bir dizeyi değiştirmek, kodun yeniden yazılmasını gerektirmez.
<!-- Android: res/values/strings.xml -->
<resources>
<string name="app_name">MyApp</string>
<string name="api_base_url">https://api.example.com</string>
</resources>
Hizmetler ve sağlayıcılar için Android'de Dagger, Hilt veya Koin, iOS'te Swinject aracılığıyla Bağımlılık Enjeksiyonu kullanın. DI çerçeveleri, uygulamaları anında değiştirmeye olanak tanır — testler için, farklı ortamlar için, farklı kullanıcılar için. Bu, değerin “çivilenmesinin” dış enjeksiyonla değiştirildiği en yüksek soyutlama seviyesidir.
Hardcode'u yeniden düzenleme, sabit değerleri yapılandırmaya veya kaynaklara çıkarma sürecidir. Yöntemli bir şekilde yapılırsa en güvenli yeniden düzenleme işlemlerinden biridir. Aşağıda açıklanan sıra, herhangi bir dil ve platform için uygundur.
Arama, IDE (Search in Project) veya bir betik aracılığıyla yapılabilir. Dizeleri, URL'leri, sayısal sabitleri, boyutları, zaman aşımlarını arayın. Özellikle dikkat — tekrarlanan değerlere: aynı sayı beş yerde görünüyorsa, bu bir sabite çıkarma adayıdır. grep veya IDEA / Xcode'un yerleşik aramasını kullanın.
Bulunan her değer için anlamlı bir ada sahip bir sabit oluşturun. Sabitleri modüllere veya sınıflara göre gruplayın. Ad, değerin ne anlama geldiğini açıklamalı, nasıl kullanıldığını değil: TIMEOUT_30 değil, API_TIMEOUT. Değiştirmeden sonra kodda açıklamasız hiçbir sayı kalmamalıdır.
// Önce: sihirli sayı 0.4
let cardHeight = screenHeight * 0.4
// Sonra: adlandırılmış sabit
private let cardHeightRatio: CGFloat = 0.4
let cardHeight = screenHeight * cardHeightRatio
Değer derlemeler veya ortamlar arasında değişebiliyorsa — onu bir yapılandırma dosyasına veya uygulama kaynaklarına çıkarın. Dizeler için yerelleştirme dosyalarını kullanın. URL'ler için — build config veya xcconfig. Boyutlar için — kaynak dosyaları (Android'de dimens.xml). Çıkardıktan sonra uygulamanın derlendiğini ve doğru çalıştığını doğrulayın.
Yeniden düzenlemeden sonra, yapılandırmanın doğru yüklendiğini ve değerlerin beklenenlerle eşleştiğini doğrulayan bir test yazın. Gelecekte birisi config dosyasını değiştirirse, test uyumsuzluğu gösterecektir. Yapılandırma testi, gerilemeyi önlemenin hızlı ve güvenilir bir yoludur.
Config dosyasına çıkardıktan sonra, eski değeri kullanan tüm yerlerin tek bir kaynağa başvurduğunu doğrulayın. Yorumlanmış kodu ve artık kullanılmayan eski sabitleri kaldırın. Hangi değerlerin nereye çıkarıldığını açıklayan bir commit mesajıyla yeniden düzenlemeyi tamamlayın.
Sıkça Sorulan Sorular
Hardcode yapmak — bir değeri yapılandırmaya veya kaynaklara çıkarmak yerine doğrudan kaynak koduna yazmak. Bu, kodu daha az esnek ve bakımı daha zor hale getirir.
Hardcode, uygulamanın davranışını değiştirmeyi zorlaştırır, testleri engeller, kopyalama oluşturur ve kopyalama sırasında hata riskini artırır. Hardcode edilmiş bir değeri değiştirmek, uygulamanın yeniden derlenmesini ve yeniden yayınlanmasını gerektirir.
Kabul edilebilir matematiksel sabitler, uygulamanın yaşam döngüsünde değişmeyen kararlı değerler ve geçici prototipler için. Üretimde, sabitler bile adlandırılmış değişkenlere çıkarılmalıdır.
Arama yoluyla tüm sihirli sayıları bulun, bunları adlandırılmış sabitlerle değiştirin veya bir yapılandırma dosyasına çıkarın. Yapılandırma yüklemesini doğrulayan bir test yazın. Kopyaları kaldırın ve değişikliklerin açıklamasıyla bir commit yapın.
Sabit — kodda adlandırılmış değer, tek bir yerde değiştirilebilir. Hardcode — kodda dağınık, adlandırılmamış değerler. İyi uygulama: her zaman anlamlı adlara sahip adlandırılmış sabitler kullanın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun