Ders 02 / 10
Çerçeveler
Kurumsal mimari çerçevelerinin ortak yapısı — katman ayrımı, görünüm kümesi, yönetişim döngüsü ve olgunluk basamağı — ile aynı kurum modelinin ayrıntılı katmanlı ve hafif biçimde belgelenmesi: her biçimin yanıtladığı soru sayısı, taşıdığı kalem sayısı, değişiklik başına dokunulan kalem ve çerçevenin hiçbir biçimde yanıtlamadığı sorular.
İçindekiler
Önceki ders kurum modelini kurdu ve hizalamayı üç sayıya bağladı. Model bir kez çıkarıldı, ama nereye yazılacağı hiç konuşulmadı: hangi katmanlara ayrılacağı, kaç ayrı görünümle tutulacağı, kimin ne sıklıkta gözden geçireceği belirsiz. Kurumsal mimari çerçeveleri (framework) bu boşluğu doldurma iddiasındadır ve iddia genellikle tartışma konusu olur — hangi çerçevenin seçileceği, ağırın mı hafifin mi doğru olduğu. Bu ders tartışmayı bir ölçüme çevirir. Marka ve çerçeve adı yazılmaz; çerçeveler ortak yapılarıyla anılır.
Çerçevelerin Ortak Yapısı
Adları ve ayrıntıları ne olursa olsun, kurumsal mimari çerçeveleri dört parçadan kurulur.
Katman ayrımı, kurumu birbirinden ayrı ama birbirine eşlenen düzlemlere böler: iş yetenekleri ve sahipleri, sistemler, veri varlıkları, sistemleri taşıyan altyapı. Görünüm kümesi, aynı modelin farklı okuyucular için hazırlanmış kesitleridir. Yönetişim döngüsü, hangi kaydın kim tarafından ne sıklıkta gözden geçirileceğini bağlar. Olgunluk basamağı, kurumun bu kayıtların ne kadarını tuttuğunu sıralayan bir merdivendir.
Bu dört parçanın ortak yanı şudur: hiçbiri bilgi üretmez, bilginin nereye yazılacağını söyler. Bu yüzden bir çerçeve, ancak taşıdığı kayıt türleri üzerinden ölçülebilir. Ölçüm için üç tanım gerekir. Kalem, bağımsız olarak bakılan bir kayıt satırıdır; aynı satıra düşen alanlar ayrı kalem sayılmaz (KM5). Soru kümesi, sonradan gelen birinin sorduğu on iki sorudur; ölçü biçimi Mimari Karar ve Dokümantasyon kursundan ödünç alınmıştır — bir belgenin değeri yanıtladığı soru sayısıdır (KM6). Olgunluk basamağı, unvan değil, belirli kayıt türlerinin varlığına bağlı bir yüklemdir (KM7).
İlk dosya önceki dersin kurum modelini yeniden verir; blok kendi başına çalışsın diye tekrarlanıyor.
// kurum/model.mjs — MODEL bolgesel kutuphane agi: sistemler, sahipler, yetenekler, veri. // Kurgudur; gercek bir kurum, satici, urun ya da kisi anlatilmaz. export const SISTEM = { katalog: { sahip: "dis-saglayici", butce: "hizmet-bedeli" }, odunc: { sahip: "bt-birimi", butce: "ic-gelistirme" }, ucretlendirme: { sahip: "bt-birimi", butce: "ic-gelistirme" }, uyelik: { sahip: "uye-hizmetleri", butce: "uye-hizmetleri" }, kimlik: { sahip: "belediye-bt", butce: "belediye" }, "sube-yerel": { sahip: "sube-yonetimi", butce: "sube" }, kiosk: { sahip: "sube-yonetimi", butce: "sube" }, raporlama: { sahip: "yonetim-birimi", butce: "yonetim" }, arsiv: { sahip: "yok", butce: "yok" }, }; // YETENEK — kurumun karsilamak zorunda oldugu is yetenekleri (sistemden bagimsiz liste) export const YETENEK = ["materyal-arama", "odunc-verme", "iade-alma", "ayirtma", "uyelik-acma", "uye-dogrulama", "ucret-hesaplama", "ucret-tahsilati", "subeler-arasi-aktarim", "demirbas-sayimi", "kullanim-raporlama", "satin-alma-onerisi", "gecikme-bildirimi"]; // KARSILAMA[s] = s sisteminin karsiladigini iddia ettigi yetenekler export const KARSILAMA = { katalog: ["materyal-arama", "demirbas-sayimi"], odunc: ["odunc-verme", "iade-alma", "ayirtma", "gecikme-bildirimi"], ucretlendirme: ["ucret-hesaplama", "gecikme-bildirimi"], uyelik: ["uyelik-acma", "uye-dogrulama"], kimlik: ["uye-dogrulama"], "sube-yerel": ["iade-alma", "subeler-arasi-aktarim", "demirbas-sayimi"], kiosk: ["odunc-verme", "materyal-arama"], raporlama: ["kullanim-raporlama"], arsiv: [], }; // VERI[v] = veri varligi; hangi sistem yaziyor, hangileri okuyor export const VERI = { "uye-kaydi": { yazan: ["uyelik"], okuyan: ["odunc", "ucretlendirme", "kiosk", "raporlama"] }, "kimlik-eslesmesi": { yazan: ["kimlik", "uyelik"], okuyan: ["odunc", "kiosk"] }, "materyal-kaydi": { yazan: ["katalog"], okuyan: ["odunc", "kiosk", "sube-yerel", "raporlama"] }, "nusha-durumu": { yazan: ["katalog", "odunc", "sube-yerel"], okuyan: ["kiosk", "raporlama"] }, "odunc-hareketi": { yazan: ["odunc", "kiosk"], okuyan: ["ucretlendirme", "raporlama"] }, "ucret-kaydi": { yazan: ["ucretlendirme"], okuyan: ["uyelik", "raporlama", "kiosk"] }, "ceza-kurali": { yazan: ["ucretlendirme"], okuyan: ["odunc", "kiosk"] }, "aktarim-istegi": { yazan: ["sube-yerel"], okuyan: ["odunc", "katalog"] }, "eski-kayit": { yazan: [], okuyan: ["arsiv", "raporlama"] }, "sayim-farki": { yazan: ["sube-yerel"], okuyan: [] }, }; export const SISTEMLER = Object.keys(SISTEM); export const sahibi = (s) => SISTEM[s].sahip; // bag = ayni veri varligi uzerinden yazan sistemden okuyan sisteme giden yonlu cift export function baglar() { const b = new Map(); for (const [v, d] of Object.entries(VERI)) for (const y of d.yazan) for (const o of d.okuyan) if (y !== o) b.set(`${y}->${o}`, [...(b.get(`${y}->${o}`) ?? []), v]); return b; }
Ölçüm
İkinci dosya iki biçimi tanımlar. Ayrıntılı katmanlı biçim her kayıt türünü kendi katmanında ayrı kalem olarak tutar; hafif biçim tek bir sistem tablosu ile bir yetenek listesinden ibarettir ve sahip, bütçe, karşılama bilgisini sistem satırının sütunlarına katlar.
// kurum/cerceve.mjs — ayni kurum modeli iki cerceve biciminde: yanit, kalem, bakim import { SISTEM, YETENEK, KARSILAMA, VERI, SISTEMLER, sahibi, baglar } from "./model.mjs"; const sut = (s, n) => String(s).padEnd(n); const B = baglar(); // KALEM[tur] = o kayit turunun model kurumdaki satir sayisi const KALEM = { yetenek: YETENEK.length, sahip: new Set(SISTEMLER.map(sahibi)).size - 1, butce: new Set(SISTEMLER.map((s) => SISTEM[s].butce)).size - 1, sistem: SISTEMLER.length, "yetenek-eslemesi": Object.values(KARSILAMA).flat().length, veri: Object.keys(VERI).length, bag: B.size, tasiyici: 4, "sistem-tasiyici": SISTEMLER.length, gorunum: 4, yonetisim: 4, olgunluk: 1, }; // BICIM[b].tasiyici[tur] = o kayit turunu tasiyan bagimsiz kalem; null ise bicim tutmaz. // Ayni kaleme dusen kayitlar ayri bakim istemez (marka degil, ortak yapi anlatiliyor). const kendi = (l) => Object.fromEntries(l.map((k) => [k, k])); const BICIM = { "ayrintili katmanli": kendi(Object.keys(KALEM)), hafif: { sistem: "sistem", sahip: "sistem", butce: "sistem", "yetenek-eslemesi": "sistem", yetenek: "yetenek" }, }; const tutar = (b, tur) => Boolean(BICIM[b][tur]); const kalemSayisi = (b) => [...new Set(Object.values(BICIM[b]))].reduce((t, k) => t + KALEM[k], 0); // SORU[i] = sonradan gelen birinin sordugu soru; gerek = yanit icin gereken kayit turleri const SORU = [ ["hangi sistem hangi yetenegi karsiliyor", ["yetenek-eslemesi"]], ["bir sistemin sahibi kim", ["sahip"]], ["hangi yetenek hicbir sistemde karsilanmiyor", ["yetenek", "yetenek-eslemesi"]], ["bir sistem kapatilsa hangi yetenek bosta kalir", ["yetenek-eslemesi"]], ["bir sistemin gideri hangi butceden odeniyor", ["butce"]], ["bir veriyi hangi sistem yaziyor", ["veri"]], ["iki sistem arasinda hangi veri geciyor", ["bag"]], ["bir sistem hangi tasiyicida kosuyor", ["sistem-tasiyici"]], ["belgenin hangi bolumu ne zaman gozden gecirildi", ["yonetisim"]], ["bir konu hangi gorunumde belgelenmis", ["gorunum"]], ["bir veri hangi siklikta geciyor", ["bag-sikligi"]], ["bir bag koparsa kim haberdar edilir", ["bag-sorumlusu"]], ]; const yanitlar = (b, gerek) => gerek.every((g) => tutar(b, g)); // DEGISIKLIK[i][1] = degisiklik gerceklestiginde guncellenmesi gereken kayitlar const DEGISIKLIK = [ ["yeni sistem devreye alinir", { sistem: 1, "yetenek-eslemesi": 1, bag: 2, tasiyici: 1, "sistem-tasiyici": 1, gorunum: 2, yonetisim: 1 }], ["sistem baska birime devredilir", { sistem: 1, sahip: 1, butce: 1, gorunum: 1, yonetisim: 1 }], ["veri varligina yeni okuyan eklenir", { veri: 1, bag: 1, gorunum: 1, yonetisim: 1 }], ]; function dokunulan(b, d) { const grup = new Map(); // ayni kaleme dusen kayitlar tek bakim sayilir for (const [tur, n] of Object.entries(d)) { const k = BICIM[b][tur]; if (k) grup.set(k, Math.max(grup.get(k) ?? 0, n)); } return [...grup.values()].reduce((t, n) => t + n, 0); } // OLGUNLUK — basamaklar; her basamak belirli kayit turlerini ister const OLGUNLUK = [ ["sistem envanteri var", ["sistem"]], ["her sistemin sahibi yazili", ["sistem", "sahip"]], ["yetenek eslemesi var", ["yetenek", "yetenek-eslemesi"]], ["veri sahipligi yazili", ["veri"]], ["degisimin etkisi hesaplanabilir", ["veri", "bag"]], ]; const basamak = (b) => { let n = 0; for (const [, gerek] of OLGUNLUK) { if (!gerek.every((g) => tutar(b, g))) break; n++; } return n; }; const bicimler = Object.keys(BICIM); console.log(`MODEL kurum: ${SISTEMLER.length} sistem, ${YETENEK.length} yetenek, ` + `${Object.keys(VERI).length} veri, ${B.size} bag; soru kumesi ${SORU.length} soru\n`); console.log(sut("soru", 50) + bicimler.map((b) => sut(b, 20)).join("")); console.log("-".repeat(88)); for (const [s, gerek] of SORU) console.log(sut(s, 50) + bicimler.map((b) => sut(yanitlar(b, gerek) ? "yanit" : "-", 20)).join("")); console.log(""); console.log(sut("bicim", 20) + sut("yanit", 8) + sut("kalem", 8) + sut("basamak", 9) + sut("kalem/yanit", 13) + "degisiklik basina dokunulan kalem"); console.log("-".repeat(100)); for (const b of bicimler) { const y = SORU.filter(([, g]) => yanitlar(b, g)).length; const k = kalemSayisi(b); const d = DEGISIKLIK.map(([, o]) => dokunulan(b, o)); console.log(sut(b, 20) + sut(`${y}/${SORU.length}`, 8) + sut(k, 8) + sut(`${basamak(b)}/5`, 9) + sut((k / y).toFixed(1), 13) + d.join(" + ") + ` = ${d.reduce((t, n) => t + n, 0)}`); } const [a, h] = bicimler; const yA = SORU.filter(([, g]) => yanitlar(a, g)).length; const yH = SORU.filter(([, g]) => yanitlar(h, g)).length; console.log(`\nfark: ${kalemSayisi(a) - kalemSayisi(h)} fazla kalem -> ${yA - yH} fazla yanit = ` + `${((kalemSayisi(a) - kalemSayisi(h)) / (yA - yH)).toFixed(1)} kalem/ek yanit`); const gorulmeyen = DEGISIKLIK.filter(([, o]) => dokunulan(h, o) === 0); console.log(`hafif bicimde hic kalem dokunmayan degisiklik: ${gorulmeyen.length} ` + `(${gorulmeyen.map(([ad]) => ad).join("; ")})`); const hicbiri = SORU.filter(([, g]) => bicimler.every((b) => !yanitlar(b, g))); console.log(`hicbir bicimin yanitlamadigi soru: ${hicbiri.length} -> ` + hicbiri.map(([s]) => s).join(" / ")); console.log("yillik gozden gecirme turu (kapasite duyarliligi):"); for (const kap of [20, 40, 60]) console.log(" tur basina " + sut(kap, 4) + "kalem -> " + bicimler.map((b) => `${b}=${Math.ceil(kalemSayisi(b) / kap)}`).join(", "));
MODEL kurum: 9 sistem, 13 yetenek, 10 veri, 23 bag; soru kumesi 12 soru soru ayrintili katmanli hafif ---------------------------------------------------------------------------------------- hangi sistem hangi yetenegi karsiliyor yanit yanit bir sistemin sahibi kim yanit yanit hangi yetenek hicbir sistemde karsilanmiyor yanit yanit bir sistem kapatilsa hangi yetenek bosta kalir yanit yanit bir sistemin gideri hangi butceden odeniyor yanit yanit bir veriyi hangi sistem yaziyor yanit - iki sistem arasinda hangi veri geciyor yanit - bir sistem hangi tasiyicida kosuyor yanit - belgenin hangi bolumu ne zaman gozden gecirildi yanit - bir konu hangi gorunumde belgelenmis yanit - bir veri hangi siklikta geciyor - - bir bag koparsa kim haberdar edilir - - bicim yanit kalem basamak kalem/yanit degisiklik basina dokunulan kalem ---------------------------------------------------------------------------------------------------- ayrintili katmanli 10/12 106 5/5 10.6 9 + 5 + 4 = 18 hafif 5/12 22 3/5 4.4 1 + 1 + 0 = 2 fark: 84 fazla kalem -> 5 fazla yanit = 16.8 kalem/ek yanit hafif bicimde hic kalem dokunmayan degisiklik: 1 (veri varligina yeni okuyan eklenir) hicbir bicimin yanitlamadigi soru: 2 -> bir veri hangi siklikta geciyor / bir bag koparsa kim haberdar edilir yillik gozden gecirme turu (kapasite duyarliligi): tur basina 20 kalem -> ayrintili katmanli=6, hafif=2 tur basina 40 kalem -> ayrintili katmanli=3, hafif=1 tur basina 60 kalem -> ayrintili katmanli=2, hafif=1
İki Biçimin Farkı
Ayrıntılı katmanlı biçim on iki sorunun onunu yanıtlıyor ve 106 kalem taşıyor. Hafif biçim beşini yanıtlıyor ve 22 kalem taşıyor. Fark tek bir sayıya iner: 84 fazla kalem, 5 fazla yanıt — ek yanıt başına 16,8 kalem. Çerçeve seçimi bu oranın karşılığında verilir. Bir kurum “bir veriyi hangi sistem yazıyor” sorusunun yanıtını 16,8 kalemin sürekli bakımına değer buluyorsa ayrıntılı biçim kazanır; bulmuyorsa hafif biçim kazanır. Bu bir tercih değil bir hesaptır ve sayılar kurum modelinin büyüklüğüne bağlıdır: bağ sayısı arttıkça ayrıntılı biçimin kalem sayısı hızla büyür, çünkü 106 kalemin 23’ü bağdır.
Değişiklik başına maliyet farkı daha keskin: aynı üç değişiklik ayrıntılı biçimde 18, hafif biçimde 2 kalem güncelletiyor. Bunun içinde bir uyarı var. “Bir sistem başka birime devredilir” değişikliği ayrıntılı biçimde beş kalem dokunduruyor; sistemin kendisi değişmiyor, yalnız sahibi ve bütçesi değişiyor. Kurum ölçeğinde bakımın büyük bölümü teknik değişiklikten değil, sahiplik değişikliğinden gelir.
Üçüncü değişiklik ayrımı görünür kılıyor: bir veri varlığına yeni bir okuyan eklendiğinde hafif biçimde hiçbir kalem dokunmuyor. Bu, hafif biçimin ucuzluğunun kaynağıdır ve aynı zamanda sınırıdır. Belge yanlış duruma düşmez, çünkü o konuda hiçbir iddiada bulunmamıştır; sessiz kalır. Kurumda yeni bir bağ oluşur ve belgeye bakan kimse bunu göremez.
Olgunluk basamağı aynı farkın kısaltmasıdır: ayrıntılı biçim beş basamağın beşini, hafif biçim üçünü karşılıyor. Basamak bir başarı sıralaması değildir; hangi soruların yanıtlanabilir olduğunun tek sayıya indirgenmiş halidir. Hafif biçim dördüncü basamakta duruyor, çünkü veri sahipliğini hiç tutmuyor — ve beşinci basamak, yani değişimin etkisinin hesaplanabilmesi, tam olarak bu kursun ölçü birimine bağlıdır.
Çerçevenin Yanıtlamadığı Soru
İki soru hiçbir biçimde yanıtsız kalıyor: bir verinin hangi sıklıkta geçtiği ve bir bağ koptuğunda kimin haberdar edileceği. Bunun nedeni çerçevenin seçimi değildir. Model bu alanları hiç taşımıyor; taşımadığı için hiçbir katman ayrımı, hiçbir görünüm kümesi bunları üretemez. Çerçeve tartışması bilgi üretmez, var olan bilgiyi düzenler — ve düzenlenecek bilgi yoksa daha ayrıntılı bir çerçeve yalnız daha çok boş kalem üretir.
Yönetişim döngüsünün maliyeti de buradan okunur. Tur başına elden geçirilebilen kalem sayısı bir eşiktir ve eşiğin kaynağı yazılmalıdır: bu modelde tur başına kırk kalem seçildi (KM8). Bu eşikte ayrıntılı biçim üç turda, hafif biçim tek turda gözden geçirilir. Eşik yirmiye indiğinde ayrıntılı biçim altı tura çıkar; altmışa çıktığında ikiye iner. Gözden geçirme kapasitesi kalem sayısının altında kalırsa belge güncelliğini kaybeder, yani çerçevenin kendisi ölçtüğü sapmanın kaynağı olur.
Özet
- Kurumsal mimari çerçeveleri marka farklarından bağımsız olarak dört parçadan kurulur: katman ayrımı, görünüm kümesi, yönetişim döngüsü ve olgunluk basamağı; hiçbiri bilgi üretmez, bilginin yerini belirler.
- Aynı kurum modeli ayrıntılı katmanlı biçimde 12 sorunun 10’unu yanıtlar ve 106 kalem taşır; hafif biçimde 5’ini yanıtlar ve 22 kalem taşır.
- Kararın sayısı ek yanıt başına düşen kalemdir: 84 fazla kalem karşılığında 5 fazla yanıt, yani 16,8 kalem/ek yanıt; değişiklik başına bakım 18’e karşı 2 kalem.
- Hafif biçimde bir değişiklik hiçbir kaleme dokunmuyor — yeni bir okuyanın eklenmesi. Ucuzluğun kaynağı budur ve belgenin sessiz kaldığı yer de burasıdır.
- İki soru hiçbir biçimde yanıtlanmıyor (verinin sıklığı ve bağın sorumlusu), çünkü model o alanları hiç taşımıyor; çerçeve seçmek eksik alanı doldurmaz.
Sonraki Adım
İki ders de kurumu duran bir yapı olarak ele aldı: sistemler, sahipler, yetenekler, kayıtlar. Oysa bir iş yeteneği bir liste satırı değil, adım adım işleyen bir süreçtir; üyenin kapıdan girmesiyle materyali eline alması arasında sırayla gerçekleşen işlemler vardır ve bu adımların hepsi yazılımın içinde geçmez. Sonraki ders bir iş sürecini adım adım modeller ve her adımı üç sınıfa ayırır — tümüyle otomatik, insan kararı gerektiren, sistem dışı. Ölçülecek olan şudur: otomasyon sınırının nereden geçtiği ve sınırı zorlamanın, yani insan kararı gerektiren bir adımı otomatikleştirmenin ürettiği geri dönüş sayısı.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.