---
title: "Mimari Kararlar Çürür Çünkü Onları Kimse Çalıştırmaz"
description: "Bir wiki'ye yazılmış mimari karar bir dilektir. Zorlayamadığın sınırlar sessizce aşınır — diyagram kodla örtüşmeyi bırakana dek. Kuralı çalıştırılabilir yap."
url: https://sade.dev/tr/journal/mimari-kararlar-curur/
lang: tr
author: "Muhammet Şafak"
published: 2026-06-18
updated: 2026-09-06
section: Journal
tags: ["architecture","governance","opinion"]
summary: "Bir mimari karar, onu her commit'te kontrol eden bir şey yoksa kural değil dilektir. Kararın iki parçası var: bir aracın tutamayacağı için nesre ait olan gerekçe ve import grafiği üzerinde deterministik olarak değerlendirilip build'i kırabilen kısıt. Gerekçeyi insanlar için yazmaya devam edin; sınırı, onu zorlamaktan asla yorulmayan bir makineye devredin."
---

# Mimari Kararlar Çürür Çünkü Onları Kimse Çalıştırmaz

> Bir mimari karar, onu her commit'te kontrol eden bir şey yoksa kural değil dilektir. Kararın iki parçası var: bir aracın tutamayacağı için nesre ait olan gerekçe ve import grafiği üzerinde deterministik olarak değerlendirilip build'i kırabilen kısıt. Gerekçeyi insanlar için yazmaya devam edin; sınırı, onu zorlamaktan asla yorulmayan bir makineye devredin.

Yeni bir mühendis bana domain katmanının neden database paketini import ettiğini sordu — "bir ADR (mimari karar kaydı) import etmemesi gerektiğini söylemiyor mu?" Söylüyordu. İki yıldır söylüyordu. Ve o iki yılın çoğunda, bir yerlerde, kural sessizce çiğnenmişti: şurada bir helper, burada bir "sadece bu seferlik" import, her biri kendi pull request'inde makul. Karar wiki'de hâlâ doğruydu. Kodda aylar önce doğru olmaktan çıkmıştı ve kimse fark etmedi, çünkü onu izleyen hiçbir şey yoktu.

Yazıp da zorlayamadığın bir karar bir kural değildir. İyi formatlanmış bir dilektir.

## Diyagram ile kod, küçük ve makul adımlarla ayrışır

Kimse mimariyi çiğnemeye karar vermez. Her seferinde savunulabilir bir commit'le aşınır: async yolu yazmak daha yavaş olduğu için eklenen senkron bir çağrı, ihtiyacın olan fonksiyon öbür tarafta olduğu için bir sınırı geçen bir import. Her diff tek başına iyi görünür. Hasar **birikimli ve yapısaldır** — tek bir değişiklik ölçeğinde görünmez, ancak geri çekilip katmanlamanın yok olduğunu bulunca belli olur.

Bu tam da bir insan review'ının çalıştığı ölçek ve tam da kaçırdığı ölçek. Review en iyi bir değişikliğin mimarisinde işler, ama bir reviewer tek bir PR görür, sınırı nihayet eriten bininci import'u değil. Bir insandan her commit'te tüm bağımlılık grafiğini kafasında tutmasını isteyemezsin. Wiki sayfası da tutamaz; o nesirdir ve nesir bir build'i patlatmaz.

## Kısıtı çalıştırılabilir yap

Çözüm daha iyi yazılmış bir ADR değil. Kararın *zorlanabilir kısmını* nesirden çıkarıp çalışan bir şeye taşımak.

"Domain altyapıya bağımlı olmamalı" özünde bir görüş değildir — import grafiği üzerinde bir kısıttır: `domain/` altındaki dosyalar `db/`'yi import edemez. Bu, bir aracın her commit'te deterministik olarak değerlendirebileceği ve çiğnendiğinde build'i kırabileceği bir kural — çiğneyen import `main`'e ulaşmadan, iki yıl sonra değil. Yakalama maliyeti, "bir şey nihayet kırılınca yapılan bir arkeoloji seansı"ndan "onu sokan PR'daki kırmızı bir kontrol"e iner.

Bu, [bir şemayı değiştirmek yerine sürümlemenin](/tr/journal/sema-evrimi-sozlesmeyi-kirmadan) aynı hamlesi: herkesin *üzerinde anlaştığı* bir kural, mekanik bir şey çizgiyi tutana dek hiçbir şey etmez — çünkü insan disiplini, her katkıcının her commit'ine ölçeklenmez.

## Dokümanda ne kalır, ne kod olur

Bu ADR'yi öldürmez — onu ikiye böler. Bir mimari kararın iki parçası vardır: **gerekçe** (hexagonal katmanlamayı niye seçtik, neyi feda ettik, ne zaman yeniden gözden geçiririz) ve **kısıt** (domain hiçbir şey import etmez; API, DB'yle yalnızca bir repository üzerinden konuşur). Gerekçe nesre aittir — bir aracın tutamayacağı, bir insanın ihtiyaç duyduğu bağlam. Kısıt ise koda aittir, kontrol edilebileceği yere.

*Neden*'i yazmaya devam et. *Ne*'yi zorlamak için nesre güvenmeyi bırak.

## Bu ne zaman önemsizleşir?

Tüm sistemin iki katman ve tek bir masanın etrafına sığan bir takımsa, sınırlar herkesin kafasında yaşar ve onlar için bir CI kapısı törendir. Üçüncü bir katkıcı katıldığı ya da kod tabanı tek bir kişinin tutabileceğini aştığı an, zorlanmayan sınır *zaten* aşınıyordur — sadece yeni mühendis domain'in neden database'i import ettiğini sorana dek görmezsin.

---

Bir mimari, karar verdiğin şey değildir; kodunun şu an yaptığı şeydir. Büyüyen bir kod tabanıyla temasta hayatta kalan tek kararlar, bir şeyin her commit'te kontrol ettikleridir. Gerekçeyi insanlar için yaz — ve sınırı, onu zorlamaktan asla yorulmayan bir makineye devret.

---

*İlgili:* [archlint](https://github.com/muhammetsafak/archlint), tam da bunun için yazdığım araç — katman kurallarını okuyup bir ihlalde build'i kıran, deterministik bir import-sınır linter'ı (Go, TypeScript ve Python), paketlenmiş bir CI Action'ıyla.

## Sık sorulanlar

**Bu, mimari karar kaydını (ADR) gereksiz mi kılıyor?**

ADR'yi öldürmez, ikiye böler. Bir kararın gerekçesi vardır — bu katmanlama niye seçildi, ne feda edildi, ne zaman yeniden gözden geçirilir — bir de kısıtı: örneğin domain'in altyapıdan hiçbir şey import etmemesi. Gerekçe, bir aracın tutamayacağı ve bir insanın ihtiyaç duyduğu bağlamdır. Koda taşınan yalnızca kısıttır.

**Code review mimari aşınmayı neden yakalamıyor?**

Çünkü hasar birikimli ve yapısal. Bir reviewer tek bir pull request görür, sınırı nihayet eriten bininci import'u değil; kimse de her commit'te tüm bağımlılık grafiğini kafasında tutamaz. Review en iyi bir değişikliğin mimarisinde işler; aşınma ise review'ın çalışmadığı bir ölçekte olur.

**Bunun için bir CI kapısı ne zaman sadece tören olur?**

Tüm sistem iki katman ve tek bir masanın etrafına sığan bir takımsa — sınırlar herkesin kafasında yaşar. Üçüncü bir katkıcı katıldığı ya da kod tabanı tek bir kişinin tutabileceğini aştığı an, zorlanmayan sınır zaten aşınmaya başlamıştır; siz yalnızca biri domain'in neden database'i import ettiğini sorana kadar görmezsiniz.


## Kaynaklar

- [Documenting Architecture Decisions: the original ADR format — Title, Context, Decision, Status, Consequences](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions) — Michael Nygard
- [ArchUnit user guide: layered-architecture rules checked as ordinary unit tests](https://www.archunit.org/userguide/html/000_Index.html) — ArchUnit
- [dependency-cruiser: validate dependencies against your own forbidden rules and report violations in the build](https://github.com/sverweij/dependency-cruiser) — dependency-cruiser
