← Back to list

Refactoring — Mevcut Kodun Tasarımını İyileştirme Sanatı — Bölüm 19: Mimari Refactoring — Strangler…

Kısım IV — Büyük Resim: Sistem Ölçeğinde Refactoring

Sahin Yelkenci · 2026-08-01 19:43 · 0 claps · 13.7 min read
#refactoring #architectural-refactoring #strangler-fig-pattern #legacy-modernization #software-architecture
Open on Medium ↗
Wiki topics: 💻 · Programming 🏛️ · Architecture

Refactoring — Mevcut Kodun Tasarımını İyileştirme Sanatı — Bölüm 19: Mimari Refactoring — Strangler Fig ve Modülerleşme

Kısım IV — Büyük Resim: Sistem Ölçeğinde Refactoring

İçindekiler

Mercimizi en büyük ölçeğe — sistem mimarisine — kaldırıyoruz. Şimdiye kadar metotları, sınıfları ve desenleri refactor ettik; ama aynı ilkeler bir bütün sistemin mimarisini dönüştürmek için de geçerlidir: bir monoliti servislere ayırmak, bir katmanlı mimariyi yeniden yapılandırmak, ya da koca bir eski sistemi yenisiyle değiştirmek. Bu bölümde, ↗ Bölüm 16'daki Branch by Abstraction’ın mimari ölçekteki büyük kardeşi olan Strangler Fig desenini göreceğiz: eski sistemi, etrafına yeni sistemi sararak, parça parça, hiç durdurmadan boğan ve sonunda onun yerini alan bir yaklaşım.

» Mimari Ölçek — Aynı İlke, En Büyük Tuval » Strangler Fig — Eski Sistemi Sararak Boğmak » Kesişme Katmanı — Mimari Tutamak » Branch by Abstraction vs Strangler Fig — Hangisi Ne Zaman » Anti-Corruption Layer — Yeniyi Eskinin Modelinden Korumak » Veri Zorluğu — Mimari Göçün En Sert Problemi » Büyük Patlama Yeniden Yazımı — Neden Başarısız Olur » Aileyi Bir Arada Görmek — Mimariyi Evrimleştirmek » Üç Gözlem Sorusu » Felsefi Kapanış » Sonraki Bölüm » *https://gitlab.com/sahin.yelkenci2/refactoring-canli-bahis*

Mimari Ölçek — Aynı İlke, En Büyük Tuval

Bu bölümün en önemli mesajını başta söyleyelim: Mimari refactoring, temelde farklı bir disiplin değildir; aynı felsefenin en büyük tuvalde uygulanmasıdır. ↗ Bölüm 1'deki küçük adım, ↗ Bölüm 4'teki her zaman yeşil, ↗ Bölüm 16'daki soyutlamanın arkasında kademeli göç ve ↗ Bölüm 9'daki tersine çevrilebilirlik — bunların hepsi, bir metodu refactor ederken olduğu kadar, bir monoliti servislere ayırırken de geçerlidir. Sihirli yeni bir teknik yoktur; yalnızca daha büyük tutamaklar ve daha zor problemler vardır.

Bu ölçekte değişen şey, ilkeler değil, onların uygulandığı koşullardır. Tutamaklar (seam’ler) daha zor bulunur ve kurulur: bir Java arayüzü yerine bir API sınırı, bir mesaj veriyolu (message bus) ya da bir HTTP ağ geçidi (gateway). Adımlar daha büyüktür ama yine de kademeli olmalıdır. Veri, en sert problem hâline gelir — eski ve yeni sistem çoğu zaman bir veritabanını paylaşır ya da böler (↗ Bölüm 20'de derinleşeceğiz). Ve yeni bir boyut girer: örgütsel boyut — ekipler, ve Conway Yasası (sistem mimarisinin, onu üreten örgütün iletişim yapısını yansıtması).

Süreklilik nettir: ↗ Bölüm 16'daki Branch by Abstraction bileşen ölçeğindeydi; Strangler Fig sistem ölçeğindedir. Aynı fikir — bir tutamağın arkasında eski ile yeni arasında yönlendirme — yalnızca daha büyük bir ölçekte. Bir bileşeni bir arayüzün arkasında değiştirmekle, bir sistemi bir ağ geçidinin arkasında değiştirmek arasındaki fark, tekniğin doğasında değil, tuvalin büyüklüğündedir.

Ve tam da bu ölçekte, “hepsini sıfırdan yazalım” cazibesi en güçlüdür — çünkü koca bir eski sistem umutsuz görünür. Ama ↗ Bölüm 2 ve 16'da gördüğümüz gibi, bu cazibe en tehlikeli olanıdır; bir bütün sistemi büyük patlamayla yeniden yazmak neredeyse her zaman başarısız olur. Bu bölüm, o cazibeye karşı kademeli alternatifi — sistemi çalışır tutarak, parça parça, hiç durdurmadan dönüştürmeyi — savunur.

Mimari ölçeği bilmenin dersi şudur: Mimari refactoring temelde farklı bir disiplin değil, aynı felsefenin (küçük adım, her zaman yeşil, soyutlama arkasında göç, tersine çevrilebilirlik) en büyük tuvalde uygulanmasıdır; değişen şey ilkeler değil koşullardır — tutamaklar daha zor (API/mesaj veriyolu/gateway), veri en sert problem, ve örgütsel boyut girer — ve Branch by Abstraction’dan Strangler Fig’e süreklilik vardır: aynı fikir, daha büyük ölçekte.

Strangler Fig — Eski Sistemi Sararak Boğmak

Strangler Fig (Boğan İncir), Martin Fowler’ın, adını boğan incir sarmaşığından alan desenidir. Bu sarmaşık bir konak ağacın etrafında büyür, onu yavaş yavaş sarar, ve sonunda konak ölüp yerine yalnızca incir kalır. Yazılımda da öyle: Yeni sistemi eskinin kenarlarında inşa eder, işlevselliği parça parça eskiden yeniye yönlendirir, ve eski “boğulup” kaldırılana kadar bunu sürdürürsünüz.

Mekanizma şöyledir. Önce eski sistemin önüne bir kesişme katmanı (interception layer — bir cephe/yönlendirici/vekil) koyarsınız; tüm istekler ondan geçer. Sonra yeni yetenekleri, yeni sistemde teker teker inşa edersiniz. Her yetenek yeniden inşa edildikçe, onun trafiğini kesişme katmanı üzerinden yeni sisteme yönlendirirsiniz. Eski sistem, daha fazla trafik yeniye taşındıkça küçülür. Ve tüm işlevsellik taşındığında, eski sistem ölmüştür — onu kaldırırsınız.

İşin sırrı, ↗ Bölüm 16'daki Branch by Abstraction ile aynıdır: Her adımda sistem çalışır; eski ve yeni bir arada var olur; yetenek yetenek göç edersiniz; değer kademeli teslim edilir (göç eden her yetenek canlıdır); ve istediğiniz noktada durabilir, duraklatabilir ya da geri alabilirsiniz. Örneğin canlı bir bahis platformu monolitini düşünün: Onu, yeteneklerini — oran gösterimi, kupon yönetimi, ödeme — birer birer yeni servislere, bir HTTP ağ geçidinin arkasında yönlendirerek boğarsınız. En düşük riskli, salt-okunur bir yetenekle (örneğin oran gösterimi) başlar, deseni kanıtlar, sonra genişlersiniz.

Strangler Fig’i bilmenin dersi şudur: Boğan incir gibi, yeni sistemi eskinin kenarlarında inşa eder, işlevselliği bir kesişme katmanı üzerinden parça parça yeniye yönlendirir, ve eski “boğulup” kaldırılana kadar sürdürürsünüz; her adımda sistem çalışır, eski ve yeni bir arada var olur, değer kademeli teslim edilir ve istediğiniz noktada durabilirsiniz — bu, Branch by Abstraction’ın sistem ölçeğindeki kardeşidir, en düşük riskli yetenekle başlanır.

Kesişme Katmanı — Mimari Tutamak

Strangler Fig’in kalbi, kesişme katmanıdır — ve o, mimari ölçekteki tutamaktır (seam). Tıpkı ↗ Bölüm 16'daki Branch by Abstraction’ın soyutlaması ve ↗ Bölüm 17'deki legacy seam’i gibi, kesişme katmanı da eski ile yeni arasında, ikisini de düzenlemeden yönlendirebileceğiniz yerdir.

Kesişme noktalarının türleri vardır. En yaygını HTTP ağ geçidi / ters vekildir (reverse proxy): URL’leri eskiye ya da yeniye yönlendirir. Bir diğeri olay kesişmesidir (event interception): bir mesaj veriyoluna girip olayları yeniden yönlendirebileceğiniz nokta. Bir başkası, bir cephe (facade) ya da API katmanıdır. Hepsinin ortak özelliği, eski ve yeni arasında bir yönlendirme noktası sunmalarıdır.

Neden temiz bir tutamağa ihtiyaç vardır? Boğmak için, istekleri kesip yönlendirebilmeniz gerekir. Eğer eski sistemin temiz bir sınırı yoksa — her şey iç içe geçmiş, net giriş noktaları yoksa — önce bir tane oluşturmanız gerekir: boğmadan önce bir tutamak (bir cephe, bir API ağ geçidi) tanıtmak. Bu, ↗ Bölüm 17'deki “seam tanıtma” hamlesinin mimari ölçekteki hâlidir. Etkinleştirme noktası, yönlendiricinin yapılandırmasıdır — yetenek başına eski mi yeni mi kararını verdiğiniz yer, mimari ölçekte bir Feature Toggle (↗ Bölüm 16) gibi.

# Kesişme katmanı: HTTP gateway yapılandırması (kavramsal)
# oranlar yeni servise GÖÇ ETTİ — geri kalan henüz eski monolitte
location /oranlar/   -> yeni-oran-servisi:8081     # boğuldu
location /kuponlar/  -> eski-monolit:8080          # henüz konak ağaçta
location /odeme/     -> eski-monolit:8080          # henüz konak ağaçta
# her göç, tek bir satırı eskiden yeniye çevirir — kademeli, geri alınabilir

Yapılandırmanın gücünü görün: Her göç, tek bir yönlendirme satırını eskiden yeniye çevirmektir — kademeli ve geri alınabilir. Bir yetenek yeniye taşınıp da sorun çıkarsa, o satırı eskiye geri çevirirsiniz (mimari ölçekte anında geri alma). Bir nüans: Eğer eski sistem temiz bir sınıra sahip değilse, Strangler Fig’in ilk adımı boğmak değil, boğulabilecek bir tutamak yaratmaktır — yani eski sistemin önüne, henüz hiçbir şeyi yönlendirmeyen bir kesişme katmanı koymak. Bu hazırlık adımı olmadan, sistemi parça parça değiştiremezsiniz.

Kesişme katmanını bilmenin dersi şudur: Kesişme katmanı, eski ile yeni arasında ikisini de düzenlemeden yönlendirebileceğiniz mimari tutamaktır (HTTP gateway, olay kesişmesi, cephe); boğmak için istekleri kesebileceğiniz temiz bir sınır şarttır, ve eğer eski sistemin temiz bir sınırı yoksa Strangler Fig’in ilk adımı boğmak değil, boğulabilecek bir tutamak yaratmaktır — yönlendiricinin yapılandırması, mimari ölçekte bir Feature Toggle gibi anında geri alma sağlar.

Branch by Abstraction vs Strangler Fig — Hangisi Ne Zaman

Bu iki teknik aynı işi yapar — bir tutamağın arkasında kademeli değiştirme — ama farklı ölçeklerde ve farklı tutamaklarla. Aralarındaki seçimi netleştirmek, doğru aracı seçmenin anahtarıdır.

Branch by Abstraction (↗ Bölüm 16), bir kod tabanının İÇİNDEKİ bir bileşeni değiştirir. Tutamak, koddaki iç bir soyutlamadır (bir arayüz). Eski ve yeni, aynı kod tabanında, sizin kontrolünüzdedir; istemciler arayüze bağımlıdır; siz arkasındaki gerçeklemeyi değiştirirsiniz. En uygun olduğu yerler: bir kütüphaneyi, bir veritabanı erişim katmanını, bir iç modülü değiştirmek — tek bir dağıtılabilir (deployable) içindeki şeyler.

Strangler Fig ise bir bütün sistemi/alt sistemi DIŞARIDAN değiştirir. Tutamak, sistem sınırındaki bir kesişme katmanıdır (HTTP gateway, mesaj veriyolu). Eski ve yeni çoğu zaman ayrı dağıtılabilirler/servislerdir. En uygun olduğu yerler: bir eski sistemi değiştirmek, bir monoliti servislere ayırmak, yeni bir platforma göç etmek — sistem sınırındaki şeyler.

Karar basittir: Değiştirdiğiniz şey tek bir kod tabanının içinde mi (Branch by Abstraction, iç soyutlama), yoksa bir bütün sistem/dağıtılabilir mi (Strangler Fig, dış kesişme katmanı)? Ölçek ve dağıtım sınırı kararı verir. İkisi birbirini dışlamaz: Büyük bir göç, sistem düzeyinde Strangler Fig, ve her yeni servisin içinde Branch by Abstraction kullanabilir. Temeldeki fikir aynıdır — bir tutamağın arkasında eski ve yeni arasında yönlendirip kademeli göç etmek — yalnızca tutamağın yeri farklıdır.

Branch by Abstraction Strangler Fig Ölçek Kod tabanı içindeki bileşen Bütün sistem/alt sistem Tutamak İç arayüz (kod) Kesişme katmanı (gateway/veriyolu) Eski + yeni Aynı dağıtılabilir Ayrı servisler En uygun Kütüphane, DB katmanı, modül Monolit bölme, platform göçü

Branch by Abstraction ile Strangler Fig’i ayırt etmeyi bilmenin dersi şudur: İkisi de bir tutamağın arkasında kademeli değiştirme yapar ama farklı ölçeklerde — Branch by Abstraction bir kod tabanı içindeki bileşeni iç bir arayüzle, Strangler Fig ise bir bütün sistemi sistem sınırındaki bir kesişme katmanıyla değiştirir; kararı ölçek ve dağıtım sınırı verir, ve ikisi birbirini dışlamaz, çünkü temeldeki fikir aynı, yalnızca tutamağın yeri farklıdır.

Anti-Corruption Layer — Yeniyi Eskinin Modelinden Korumak

Göç boyunca eski ve yeni sistem bir arada yaşar ve birbiriyle konuşur. Bu konuşma bir tehlike taşır: Eski sistemin modeli ve kavramları, yeniye “sızıp” onun temiz tasarımını bozabilir. Anti-Corruption Layer (Yozlaşma Önleme Katmanı; Eric Evans’ın DDD deseni), bu sızmayı engelleyen bir çeviri katmanıdır.

Mantık şudur: Yeni sistem, göç sırasında eski sistemi çağırmak zorunda kalır (eski monolitten veri okumak gibi). Bir Anti-Corruption Layer (ACL) olmadan, eskinin dağınık veri biçimleri ve eski kavramları yeni servislere sızar — ve bu, yeniden yazmanın amacını boşa çıkarır. ACL, eski model ile yeni model arasında çeviri yaparak yeni sistemin domain modelini temiz tutar; yeni sistem, eskinin biçimini hiç görmez. Bu, ↗ Bölüm 11'deki Facade/Adapter’ın model düzeyindeki hâlidir — sadece iletim değil, çeviri.

// Anti-Corruption Layer: eski monolitin dağınık biçimini, temiz Oran nesnesine çevirir
public class EskiOranAcl {
    private final EskiMonolitIstemci eski;
    public Oran oranGetir(Long yarisId) {
        EskiOranKaydi ham = eski.getOranRaw(yarisId);     // eskinin dağınık biçimi
        // ÇEVİRİ: eskinin biçimini yeninin temiz modeline (↗ Bölüm 12 değer nesnesi)
        return new Oran(new BigDecimal(ham.oran_deger_string));
    }
}
// yeni servis, EskiOranKaydi'nı HİÇ görmez — yalnızca temiz Oran'ı

ACL’nin Strangler Fig’teki rolü kritiktir: Göç sırasında yeni servisler eski monoliti çağırır, ve ACL olmadan eskinin karmaşık biçimleri yeniye sızar, böylece yeni servisler de eski kadar dağınık olur. ACL, koruyucu bir sınırdır. Bir maliyeti vardır — ekstra kod ve çeviri yükü — ama bunu yeni modeli korumak için ödersiniz. ACL ya geçici bir iskeledir (eski ölünce kaldırılır) ya da eski sistem kalıcı olarak duruyorsa kalıcı bir entegrasyon sınırı. Her iki durumda da, ↗ Bölüm 12'de inşa ettiğimiz temiz değer nesnelerini, eskinin yozlaşmasından korur.

Anti-Corruption Layer’ı bilmenin dersi şudur: Göç sırasında eski sistemle konuşan yeni sistem, eskinin dağınık modelinin temiz tasarımına sızmasından korunmalıdır; Anti-Corruption Layer, eski model ile yeni model arasında çeviri yaparak (Facade/Adapter’ın model düzeyindeki hâli) yeni sistemin domain modelini temiz tutar — yeni sistem eskinin biçimini hiç görmez; bir çeviri maliyeti vardır ama bu, yeni modeli eskinin yozlaşmasından korumak için ödenir.

Çalışan örnek kodlara erişmek için: » https://gitlab.com/sahin.yelkenci2/refactoring-canli-bahis

Veri Zorluğu — Mimari Göçün En Sert Problemi

Şimdi mimari göçün en sert problemiyle yüzleşelim: veri. Kod yönlendirilebilir ve değiştirilebilir; ama veri öyle kolay değildir — durumludur (stateful), paylaşılır, büyüktür, ve tutarlı kalmak zorundadır. Bir HTTP isteğini bir satır yapılandırmayla yeniye yönlendirebilirsiniz; ama bir terabaytlık canlı veritabanını öyle yönlendiremezsiniz.

Zorluklar katmanlıdır. Birincisi, paylaşılan veritabanı: Eski ve yeni göç sırasında çoğu zaman tek bir veritabanını paylaşır; ikisi de aynı tabloları okuyup yazar, ve şemadaki bir değişiklik ikisini birden etkiler (↗ Bölüm 20'de derinleşeceğiz). İkincisi, veriyi bölmek: Bir monoliti servislere ayırmak için, paylaşılan veritabanını sonunda servis başına veriye bölmeniz gerekir — ama bunu atomik olarak yapamazsınız, çünkü veri canlıdır. Üçüncüsü, göç sırasında tutarlılık: Eski ve yeni bir arada yaşarken, veriyi tutarlı tutmak (kayıp yazma yok, ıraksama yok) zordur, özellikle ayrı veritabanları arasında.

Çözüm, kodla aynı kademeli felsefeyi izler ama daha zordur. ↗ Bölüm 16'daki Parallel Change’i veriye uygularsınız: Genişlet (yeni veri deposunu eskinin yanına kur, senkron tut — örneğin çift yazma ya da olay-temelli senkronizasyon), Göç Et (okuyucuları yeniye taşı), Daralt (eskiyi kaldır). Ama veri durumlu olduğu ve tutarlılık önemli olduğu için, her adım koddan çok daha dikkatli olmalıdır. İşte bu yüzden mimari göç zordur: Kod kısmı çözülebilir (Strangler Fig), asıl meydan okuma veri kısmıdır — ve birçok göç tam burada tıkanır. Bu o kadar merkezi bir problemdir ki, bir sonraki bölümün (↗ Bölüm 20) tamamı buna ayrılmıştır.

Veri zorluğunu bilmenin dersi şudur: Mimari göçün en sert problemi veridir — kod yönlendirilebilir ama veri durumlu, paylaşılan, büyük ve tutarlı kalması gereken bir şeydir; paylaşılan veritabanı, veriyi atomik olmadan bölmek ve göç sırasında tutarlılık başlıca zorluklardır; çözüm Parallel Change’i veriye uygulamaktır (genişlet-senkron, göç et, daralt) ama veri durumlu olduğu için çok daha dikkatli olmalıdır — ve birçok göç tam burada tıkanır.

Büyük Patlama Yeniden Yazımı — Neden Başarısız Olur

Mimari ölçekte, ↗ Bölüm 16'daki uzun ömürlü dalın ve ↗ Bölüm 2'deki yeniden yazma tuzağının en büyük hâliyle karşılaşırız: “Bu eski sistem umutsuz; gelin onu paralelde sıfırdan yazalım, sonra geçiş yapalım.” Bu cazibe en güçlü olanıdır çünkü koca bir eski sistem gerçekten umutsuz görünür — ve en tehlikeli olanıdır çünkü neredeyse her zaman başarısız olur.

Başarısızlık biçimleri bellidir. Birincisi, “ikinci sistem etkisi” (Brooks): Yeniden yazım her şeyi düzeltmeye ve her özelliği eklemeye çalışır, şişer ve aşırı mühendislik ürünü olur. İkincisi, tahminden çok daha uzun sürer; bu sırada eski sistem gelişmeye devam eder (hareketli hedef), ve yeniden yazım onu kovalamak zorunda kalır. Üçüncüsü, kademeli değer yoktur: Tüm yeniden yazım bitene kadar (yıllar) hiçbir şey sevk edilmez, böylece geri bildirim yok, erken değer yok, ve devasa risk geçiş anında yoğunlaşır. Dördüncüsü, geçiş (büyük patlama anahtarı) muazzam risklidir — tüm entegrasyon, tüm hatalar, hepsi bir anda yüzeye çıkar. Beşincisi, gömülü bilgi kaybı: Eski sistem, yıllar içinde biriken sınır durumlarını ve hata düzeltmelerini kodlar; yeniden yazım bunları unutur ve aynı hataları yeniden keşfeder.

Tarih, iptal edilen ya da başarısız olan çok yıllık yeniden yazımlarla doludur. Alternatif, bu bölümün tamamının savunduğu şeydir: Strangler Fig — kademeli, değer üreten, riski azaltılmış. Bir denge notu önemlidir: ↗ Bölüm 2'de gördüğümüz gibi, yeniden yazımın haklı olduğu nadir durumlar vardır (eski platform gerçekten ölmüşse, domain çok küçükse). Ama bunlar nadirdir; varsayılan her zaman kademeli olmalıdır. Bir sistemi yeniden doğurmanın yolu, onu bir gecede yıkmak değil, etrafına yenisini sararak boğmaktır.

Büyük patlama yeniden yazımını bilmenin dersi şudur: Bir bütün sistemi sıfırdan paralelde yazıp sonra geçmek, ikinci sistem etkisi, hareketli hedef, kademeli değer yokluğu, riskli geçiş ve gömülü bilgi kaybı yüzünden neredeyse her zaman başarısız olur; alternatif, kademeli ve değer üreten Strangler Fig’tir — yeniden yazımın haklı olduğu nadir durumlar dışında varsayılan her zaman kademeli olmalı, çünkü bir sistemi yeniden doğurmanın yolu onu yıkmak değil, etrafına yenisini sararak boğmaktır.

Aileyi Bir Arada Görmek — Mimariyi Evrimleştirmek

Bu bölümün tekniklerini tanıdık; şimdi onları birleştiren tek ilkeyi görelim: Mimari, evrimleştirilir, devrimleştirilmez. Bir sistemin mimarisini, tıpkı bir metodu ya da bir sınıfı evrimleştirdiğiniz gibi — küçük adımlarla, her zaman çalışır tutarak, bir tutamağın arkasında, geri alınabilir biçimde — kademeli olarak dönüştürürsünüz. Asla büyük patlamayla değil.

Aşağıdaki tablo, mimari bir göç durumuyla karşılaştığınızda hangi araca uzanacağınızı gösterir:

Bu araçların altında yatan en derin kavrayış şudur: Mimari ölçekte temelde yeni bir teknik yoktur. Aynı refactoring felsefesi — küçük adım, her zaman yeşil, bir tutamağın arkasında, tersine çevrilebilir, kademeli değer — en büyük tuvalde uygulanır. Tutamaklar daha zordur (bir Java arayüzü yerine bir gateway), ve veri bir duvardır (↗ Bölüm 20); ama disiplin birebir aynıdır. Kısım IV boyunca izlediğimiz süreklilik budur: ↗ Bölüm 16'daki kod içi büyük refactoring, ↗ Bölüm 17'deki legacy, ve bu bölümdeki mimari — hepsi aynı fikrin, büyüyen ölçekteki hâlleridir.

Bir boyut, mimari refactoring’i saf kod refactoring’inden ayırır: örgütsel boyut. Conway Yasası’na göre, sistemin mimarisi onu üreten örgütün iletişim yapısını yansıtır; bu yüzden bir monoliti servislere ayırmak, çoğu zaman ekipleri de yeniden yapılandırmayı gerektirir. Mimari göç, yalnızca bir kod değişikliği değil, bir insan ve takım değişikliğidir de. Bu, ↗ Bölüm 2'deki evrimsel tasarımın en büyük ölçekteki hâlidir — ve aynı zamanda en insani olanıdır, çünkü artık yalnızca kodu değil, onu üreten örgütü de evrimleştirirsiniz.

Mimariyi evrimleştirmeyi bilmenin dersi şudur: Mimari evrimleştirilir, devrimleştirilmez — bir sistemi tıpkı bir metodu evrimleştirdiğiniz gibi küçük adımlarla, çalışır tutarak, bir tutamağın arkasında, geri alınabilir biçimde dönüştürürsünüz; en derin kavrayış, mimari ölçekte temelde yeni bir teknik olmadığıdır (aynı felsefe, daha büyük tuval), ve bir ek boyut girer: Conway Yasası gereği mimari göç, yalnızca kod değil, onu üreten örgütün de değişimidir.

Üç Gözlem Sorusu

Bu mimari bölümünü, kendi sisteminizin mimarisini sınayan üç soruyla kapatalım.

Birinci Gözlem Sorusu. Sisteminizde “umutsuz” gördüğünüz, sıfırdan yazmayı hayal ettiğiniz bir eski bileşen ya da monolit var mı? Onun önüne bir kesişme katmanı koyup, en düşük riskli bir yeteneğini yeni bir servise yönlendirmeye başlasaydınız — Strangler Fig’in ilk adımını atsaydınız — büyük patlama riskini almadan ilerleyebilir miydiniz?

İkinci Gözlem Sorusu. Yeni bir servis, eski bir sistemden veri okuyor ya da onunla konuşuyor mu? Eğer öyleyse, aralarında bir Anti-Corruption Layer var mı — yoksa eskinin dağınık veri biçimleri ve eski kavramları, yeni servisin temiz modeline sızıyor mu?

Üçüncü Gözlem Sorusu. Bir mimari göçü düşündüğünüzde, en çok hangi kısım sizi korkutuyor — kodu taşımak mı, yoksa veriyi taşımak mı? Eğer cevabınız veriyse, bu bölümün asıl mesajını sezmişsiniz demektir: Kod kısmı çözülebilir, asıl duvar veridir. Peki o veriyi, Parallel Change’le kademeli göç ettirmenin bir planı var mı?

Felsefi Kapanış

Bu bölümle, refactoring’i en büyük ölçeğine — bir sistemin tüm mimarisine — taşıdık. Ve gördük ki, en büyük ölçekte bile sır aynıdır: Evrim, devrimi yener. Bir sistemi yeniden doğurmanın yolu, onu bir gecede yıkıp yeniden kurmak değil; etrafına yenisini sararak, parça parça, hiç durdurmadan dönüştürmektir. Boğan incir, ağacı bir baltayla devirmez; onu sabırla sarar, ve bir gün konak ağaç gitmiştir ama orman hiç sessizleşmemiştir.

Bu yüzden bölümü, sistemlerin doğasına dair bir düşünceyle kapatalım:

Hiçbir büyük şehir, bir gecede yıkılıp yeniden kurulmaz; şehirler yaşar ve yaşadıkları için de evrimleşirler — eski bir mahalle yıkılırken yenisi yanında yükselir, bir köprü onarılırken trafik başka yoldan akar, ve şehir, kendisi olmaktan hiç çıkmadan, yüzyıllar boyunca tamamen yenilenir. Bir yazılım sistemi de canlı bir şehirdir: onu öldürüp yeniden doğurmaya çalışmak, sakinlerini sokakta bırakmaktır. Usta mimar, sistemi asla durdurmaz; onu, içinde insanlar yaşarken, trafik akarken, ticaret sürerken evrimleştirir. Çünkü gerçek mimarlık, boş bir arsaya mükemmel bir şehir çizmek değil; yaşayan, kusurlu, dolu bir şehri, kimsenin evini başına yıkmadan daha iyiye taşımaktır.

Sonraki Bölüm

***↗ Bölüm 20: Veritabanı Şema Evrimi — Refactoring Databases ve En Sert Problem ile mimari göçün en zorlu kısmına, veriye odaklanıyoruz. ***↗ Bu bölümde defalarca işaret ettiğimiz gibi, kod yönlendirilebilir ama veri durumludur, paylaşılır ve tutarlı kalmak zorundadır — bu yüzden mimari göçün asıl duvarı veritabanıdır. Bu bölüm, Scott Ambler ve Pramod Sadalage’in “Refactoring Databases” çalışmasından ilham alarak, bir veritabanı şemasını canlı sistemi bozmadan nasıl evrimleştireceğimizi gösterecek: Expand-Contract desenini şemaya uygulamak (yeni sütunu ekle, çift yaz, göç et, eskiyi daralt), göç betikleri (migration) yazmak, ve sıfır kesintili (zero-downtime) şema değişiklikleri yapmak. Mimariyi evrimleştirmeyi öğrendik; şimdi onun en sert problemini — verinin kendisini — nasıl evrimleştireceğimizi öğreneceğiz.

**İçindekiler… « Önceki [Bölüm 18: Refactoring to Patterns — Tasarım Desenlerine Doğru Evrim] » Sonraki *[Bölüm 20: Veritabanı Refactoring — Şema Evrimi ve Geçiş Stratejileri]https://gitlab.com/sahin.yelkenci2/refactoring-canli-bahis


메타데이터
post_id
fe1d35edcb18
slug
refactoring-mevcut-kodun-tasarımını-i̇yileştirme-sanatı-bölüm-19-mimari-refactoring-strangler-fe1d35edcb18
url
https://medium.com/@sahinyelkenci/refactoring-mevcut-kodun-tasar%C4%B1m%C4%B1n%C4%B1-i%CC%87yile%C5%9Ftirme-sanat%C4%B1-b%C3%B6l%C3%BCm-19-mimari-refactoring-strangler-fe1d35edcb18
canonical_url
https://medium.com/@sahinyelkenci/refactoring-mevcut-kodun-tasar%C4%B1m%C4%B1n%C4%B1-i%CC%87yile%C5%9Ftirme-sanat%C4%B1-b%C3%B6l%C3%BCm-19-mimari-refactoring-strangler-fe1d35edcb18
author_url
https://medium.com/@sahinyelkenci
status
ok
fetched_at
2026-08-07 04:19:21