Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Kuralları Otomatikleştirmek: Pre-commit Hook, CI Kapısı, Legacy Kod Tabanına Kademeli Geçiş ve .git-blame-ignore-revs
Pre-commit hook hızlı geri bildirim verir ama --no-verify ile atlanır; convention'ı main'e girmeden durduran tek yer zorunlu bir CI kontrolüdür. Yazı Husky.Net ve lint-staged ile yalnız staged dosyaları formatlamayı, düzeltme komutunu söyleyen CI adımlarını, legacy kodda dokunulan dosyalar ile big bang arasındaki seçimi, .git-blame-ignore-revs'i, açık PR'ları çatışmasız güncellemeyi ve suppression politikasını gerçek çıktılarla anlatıyor.
Angular ve TypeScript'te Convention: Style Guide, Prettier ve ESLint'in Sorumluluk Paylaşımı
Angular projesinde biçim Prettier'ın, adlandırma ve selector kuralları ESLint'in olmalı ve ikisinin arasındaki sınırı eslint-config-prettier çizer: o olmadan kopyalanmış iki @stylistic kuralı Prettier'dan geçmiş kodda 110 hata üretti. Yazı Angular 22 Style Guide'ın kararlarını, eski projelerde tip son ekli adlandırmayı, yeni projede Prettier'ın 7 dosya bulmasını, naming-convention kuralını ve ESLint 10'un .eslintrc'yi yok saymasını gösteriyor.
C# Formatter Seçimi: dotnet format mı, CSharpier mı? Kuralı Tek Sahibe Vermek
İki formatter aynı kuralın sahibi olursa döngü hiç bitmez: 1.000 dosyalık Bookstore çözümünde dotnet format CSharpier çıktısında 6.002 sorun, CSharpier de dotnet format çıktısında 1.001 formatlanmamış dosya buldu. Çözüm whitespace'i CSharpier'a, stili analyzer'a vermek; yazı iki aracın çıktısını, süre ölçümünü, IDE0055'i kapatmanın neden yetmediğini ve sürümü dotnet tool manifest'iyle sabitlemeyi gösteriyor.
C# Convention'larını .editorconfig ile Kodlamak: Code-style Option'ları, Naming Rule'lar ve Build'de Zorlamak
Naming rule'un kendi severity satırı build'de okunmaz; kuralları dotnet build'de zorlamak için EnforceCodeStyleInBuild ile birlikte dotnet_diagnostic.IDE1006.severity gerekir. Yazı .editorconfig hiyerarşisini, code-style option'larının IDE kural ID'lerini, naming rule'ların symbols-style-severity üçlüsünü, test klasörü override'ını, category-Style'ın seçmediğin varsayılanları zorlamasını ve yalnız IDE'de çalışan kuralları gerçek build çıktılarıyla anlatıyor.
Coding Convention Nedir, Neden İnsana Değil Araca Bırakılır? Kaynaklar, Seviyeler ve Ekip Kararı
Coding convention'ın değeri kuralın kendisinden değil, tartışılmaz ve araçla uygulanır olmasından gelir: Bookstore'da tek satırlık bir indirim değişikliği editör ayarları yüzünden 55 satırlık diff'e gömüldü, .editorconfig ve dotnet format onu tekrar tek satıra indirdi. Yazı formatting, stil, naming ve mimari kural seviyelerini, kaynak seçimini ve ekipte kararı bir kez verip kayda geçirmeyi anlatıyor.
Teknik Borcu Önceliklendirmek ve Refactoring'i Savunmak: Hotspot Analizi, Ölçüm ve Product Owner ile Konuşmak
Refactoring yatırımı en çirkin koda değil, en sık değişen karmaşık koda, yani hotspot'lara yapılır ve Product Owner'a değişim maliyeti, lead time ve hata oranı üzerinden anlatılır. Yazıda git log ve Roslyn ile Cognitive Complexity hesaplayan küçük bir C# script'i Bookstore repo'sunda çalıştırılıyor; PricingEngine'in birinci hotspot çıkması, InvoiceRenderer ile yüzde 59'luk change coupling ve sekiz fatura hatası gerçek çıktılarla gösteriliyor.
Angular Kodunu Refactor Etmek: NgModule'den Standalone'a, Constructor Injection'dan inject()'e, RxJS'ten Signal'lere
Eski bir Angular component'ini modernleştirmenin güvenli yolu, davranışı testle sabitlemek, resmi migration schematic'lerini --path ile feature feature, her birini ayrı commit'te çalıştırmak, schematic'lerin yapamadığı veri akışını ise testlerin gözetiminde elle dönüştürmektir. Yazıda bir CheckoutComponent sekiz schematic ve elle yapılan switchMap ve signal geçişiyle taşınıyor: prune-ng-modules'ın build'i kırması, hatadan sonra biten akış ve iki katına çıkan istek gerçek çıktılarla görülüyor.
Veri ve Contract Değişirken Refactoring: API Alanını, EF Core Property'sini ve Angular Modelini Birlikte Yeniden Adlandırmak
Bir property'nin adı değişirken dış contract'lar (JSON alanı, veritabanı kolonu, CSV başlığı, cache'teki şekil) koddan ayrılmalı ve expand-contract ile adım adım taşınmalıdır. Yazıda Book.Price'ın ListPrice'a dönüşmesi ve DiscountRate'in ayrı tabloya taşınması .NET, EF Core, SQL Server ve Angular'da yürütülüyor; kırılan view, sıfır okunan cache, tolerant reader ve dual write'ı atlayan script gerçek çıktılarla gösteriliyor.
Büyük Refactoring'i Planlamak: Mikado Method, Branch by Abstraction ve Parallel Run
Tek PR'a sığmayan bir refactoring, Mikado Method ile deneyip geri alarak çıkarılan bir ön koşul graph'ıyla planlanır ve branch by abstraction ile ana branch'te küçük, her biri yeşil commit'lerle yürütülür. Yazıda static LegacyShippingClient typed HttpClient tabanlı bir client'la 13 commit'te değiştiriliyor; parallel run testlerde olmayan iki farkı yakalıyor, static state'in paralel testleri nasıl bozduğu da gerçek çıktılarla gösteriliyor.
Legacy Kodda Dependency Kırmak: Sprout, Wrap, Extract Interface ve Static Bağımlılıklar
Testi olmayan legacy bir class'a yeni davranış eklemenin güvenli yolu, önce değişiklik noktası ile test noktasını bulup yalnız aradaki engeller için seam açmaktır: yeni kural sprout ile ayrı yerde test edilir, constructor parametrelenir, static çağrı ince bir wrapper'a, zaman TimeProvider'a alınır. Yazıda SQL Server'a takılan bir OrderImportJob'da bu adımlar uygulanıyor; testler job'un bilinmeyen bir varsayımını ve sprout'u bağlayan satırdaki hatayı gerçek çıktılarla yakalıyor.
Koşul Yığınından Okunur Tasarıma: Switch, Flag Parametreleri ve Kural Tabloları
İç içe koşulları dönüştürmenin tek doğru hedefi yoktur: yeni tipler sık geliyorsa polymorphism, yeni işlemler sık geliyorsa switch expression, kurallar sık değişiyor ve aynı biçimdeyse kural tablosu daha ucuzdur. Yazıda PricingEngine'in indirim koşulları üç hedefe de aynı 144 kombinasyonluk snapshot'tan geçerek dönüştürülüyor; enum, guard clause, bayrak parametresini bölmek ve Percentage tipi ile CS8509, CS0535 ve eksik kural testinin gerçek çıktıları gösteriliyor.
Küçük ve Güvenli Adımlar: IDE Refactoring'leri, Parallel Change ve Toplu Otomatik Düzeltmeler
Büyük bir method'u açmanın güvenli yolu, her biri derlenip test edilen ve ayrı commit'e giren küçük adımlardır; imza değişikliği ise parallel change ile genişlet, taşı, daralt diye yürütülür. Yazıda PricingEngine.Calculate 14 commit'te hiç kırmızı commit olmadan açılıyor, dotnet format ile toplu düzeltme ayrı commit'e alınıyor, decimal scale farkını yakalayan snapshot ve rename'in JSON contract'ını ve convention tabanlı DI kaydını sessizce bozduğu durumlar gerçek çıktılarla gösteriliyor.