Ders 04 / 10
Yetenek Haritalama
İş yeteneğinden onu karşılayan sisteme ve o sistemin yazdığı veriye uzanan izlenebilirlik zincirinin kurulması: bir yetenek değiştiğinde dokunulacak sistem ve sahip sayısı, kısa zincirle tam zincirin farkı ve zincirin koptuğu noktalar — izlenemeyen yetenek, yetim sistem, sahipsiz veri, okunmayan veri.
İçindekiler
Önceki ders tek bir yeteneğin tek bir sürecini açtı ve o sürecin sekiz aktör ile beş sahip dolaştığını saydı. Kurumda on üç yetenek var ve her birinin arkasında benzer bir zincir duruyor. Bir yetenek değiştiğinde — ödünç süresi kuralı yenilendiğinde, üyelik koşulu değiştiğinde — kimlerin haberdar edileceği soruldu mu diye bakılınca ortada bir liste yok: envanter hangi sistemin hangi yeteneği karşıladığını söylüyor, ama o sistemin yazdığı veriyi kimin okuduğunu söylemiyor. Bu ders o eksik halkayı ekler.
İzlenebilirlik Zinciri
İzlenebilirlik, bir iş yeteneğinden başlayıp onu gerçekleştiren yazılım parçalarına ve o parçaların ürettiği veriye kesintisiz gidebilmektir. Zincir üç halkadan kurulur (KM12): yetenek, o yeteneği karşıladığını iddia eden sistemler, o sistemlerin yazdığı veri varlıkları. Bir halka daha eklenir: yazılan veriyi okuyan sistemler. Bu son halka tek sıçramayla sınırlı tutuluyor; okuyanların yazdığı verilere kadar açılmıyor.
Zincirin ölçtüğü şey şudur: bir yeteneğin tanımı değiştiğinde dokunulacak sistemlerin kümesi. Doğrudan halka o yeteneği karşılayan sistemlerdir; değişikliği onlar gerçekleştirir. Dolaylı halka, değişen verinin okuyucularıdır; onlar kod değiştirmeyebilir ama değişikliği görmeleri gerekir, çünkü okudukları alan başkalaşır. Koordinasyon turu, etkilenen ayrı sahip sayısının bir eksiği alınıyor (KM13): bir sahip kendi içinde konuşmaz, her ek sahip bir uzlaşma turu ekler.
// 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 her yetenek için zinciri kurar, iki zincir biçimini karşılaştırır ve kopma noktalarını sayar.
// kurum/izleme.mjs — yetenek -> sistem -> veri -> okuyan zinciri; degisimin dokundugu sistem sayisi import { SISTEM, YETENEK, KARSILAMA, VERI, SISTEMLER, sahibi } from "./model.mjs"; const sut = (s, n) => String(s).padEnd(n); const karsilayan = (y) => SISTEMLER.filter((s) => KARSILAMA[s].includes(y)); const yazdigi = (s) => Object.entries(VERI).filter(([, d]) => d.yazan.includes(s)).map(([v]) => v); const sahipKumesi = (l) => new Set(l.map(sahibi).filter((o) => o !== "yok")); function zincir(y) { const dogrudan = karsilayan(y); const veri = [...new Set(dogrudan.flatMap(yazdigi))]; const dolayli = [...new Set(veri.flatMap((v) => VERI[v].okuyan))].filter((s) => !dogrudan.includes(s)); return { dogrudan, veri, dolayli, tum: [...dogrudan, ...dolayli] }; } console.log(sut("is yetenegi", 24) + sut("sistem", 8) + sut("veri", 6) + sut("okuyan", 8) + sut("dokunulan", 11) + sut("sahip", 7) + "koordinasyon turu"); console.log("-".repeat(88)); let kisaSistem = 0, tamSistem = 0, kisaTur = 0, tamTur = 0; const izlenemeyen = []; for (const y of YETENEK) { const z = zincir(y); if (z.dogrudan.length === 0) { izlenemeyen.push(y); continue; } const sahipTam = sahipKumesi(z.tum).size, sahipKisa = sahipKumesi(z.dogrudan).size; kisaSistem += z.dogrudan.length; tamSistem += z.tum.length; kisaTur += Math.max(0, sahipKisa - 1); tamTur += Math.max(0, sahipTam - 1); console.log(sut(y, 24) + sut(z.dogrudan.length, 8) + sut(z.veri.length, 6) + sut(z.dolayli.length, 8) + sut(z.tum.length, 11) + sut(sahipTam, 7) + (sahipTam - 1)); } const izlenen = YETENEK.length - izlenemeyen.length; console.log(`\n${izlenen}/${YETENEK.length} yetenek izlenebiliyor; izlenemeyen: ${izlenemeyen.join(", ")}`); console.log(sut("zincir bicimi", 26) + sut("dokunulan sistem", 18) + sut("yetenek basina", 16) + "koordinasyon turu"); console.log("-".repeat(80)); console.log(sut("kisa (yetenek->sistem)", 26) + sut(kisaSistem, 18) + sut((kisaSistem / izlenen).toFixed(2), 16) + kisaTur); console.log(sut("tam (->veri->okuyan)", 26) + sut(tamSistem, 18) + sut((tamSistem / izlenen).toFixed(2), 16) + tamTur); console.log(`fark: ${tamSistem - kisaSistem} sistem ve ${tamTur - kisaTur} koordinasyon turu ` + `kisa zincirde gorunmuyor (${((tamSistem - kisaSistem) / tamSistem * 100).toFixed(0)}%)`); const enGenis = YETENEK.filter((y) => karsilayan(y).length) .map((y) => [y, zincir(y).tum.length]).sort((a, b) => b[1] - a[1])[0]; console.log(`en genis zincir: ${enGenis[0]} -> ${enGenis[1]} sistem`); // ---- zincirin koptugu yerler ---- const kopma = [ ["izlenemeyen yetenek", izlenemeyen], ["yetim sistem (yetenege baglanamiyor)", SISTEMLER.filter((s) => KARSILAMA[s].length === 0)], ["sahipsiz sistem", SISTEMLER.filter((s) => SISTEM[s].sahip === "yok")], ["sahipsiz veri (yazani yok)", Object.keys(VERI).filter((v) => VERI[v].yazan.length === 0)], ["okunmayan veri", Object.keys(VERI).filter((v) => VERI[v].okuyan.length === 0)], ]; console.log(""); console.log(sut("kopma turu", 38) + sut("sayi", 6) + "kalem"); console.log("-".repeat(78)); for (const [t, l] of kopma) console.log(sut(t, 38) + sut(l.length, 6) + (l.join(", ") || "-")); const toplam = kopma.reduce((t, [, l]) => t + l.length, 0); const erisilen = new Set(YETENEK.filter((y) => karsilayan(y).length).flatMap((y) => zincir(y).veri)); console.log(`\ntoplam ${toplam} kopma noktasi; ` + `${Object.keys(VERI).length} veri varliginin ${erisilen.size}'ine bir yetenekten erisilebiliyor`);
is yetenegi sistem veri okuyan dokunulan sahip koordinasyon turu ---------------------------------------------------------------------------------------- materyal-arama 2 3 4 6 4 3 odunc-verme 2 2 2 4 3 2 iade-alma 2 4 4 6 4 3 ayirtma 1 2 3 4 3 2 uyelik-acma 1 2 4 5 4 3 uye-dogrulama 2 2 4 6 5 4 ucret-hesaplama 1 2 4 5 4 3 subeler-arasi-aktarim 1 3 4 5 4 3 demirbas-sayimi 2 4 3 5 4 3 kullanim-raporlama 1 0 0 1 1 0 gecikme-bildirimi 2 4 3 5 4 3 11/13 yetenek izlenebiliyor; izlenemeyen: ucret-tahsilati, satin-alma-onerisi zincir bicimi dokunulan sistem yetenek basina koordinasyon turu -------------------------------------------------------------------------------- kisa (yetenek->sistem) 17 1.55 5 tam (->veri->okuyan) 52 4.73 29 fark: 35 sistem ve 24 koordinasyon turu kisa zincirde gorunmuyor (67%) en genis zincir: materyal-arama -> 6 sistem kopma turu sayi kalem ------------------------------------------------------------------------------ izlenemeyen yetenek 2 ucret-tahsilati, satin-alma-onerisi yetim sistem (yetenege baglanamiyor) 1 arsiv sahipsiz sistem 1 arsiv sahipsiz veri (yazani yok) 1 eski-kayit okunmayan veri 1 sayim-farki toplam 6 kopma noktasi; 10 veri varliginin 9'ine bir yetenekten erisilebiliyor
Değişimin Dokunduğu Sistem Sayısı
Kısa zincir yalnız karşılayan sistemleri gösteriyor: on bir izlenebilir yetenek için toplam 17 sistem, yetenek başına 1,55. Tam zincir veriyi ve okuyucuları da katıyor: 52 sistem, yetenek başına 4,73. Aradaki 35 sistem, kısa zincire bakan birinin haberdar etmeyi hiç düşünmeyeceği sistemlerdir — dokunulacak sistemlerin %67’si ilk halkada görünmüyor.
Koordinasyon turu farkı daha keskin: kısa zincirde toplam 5, tam zincirde 29. Kurum ölçeğinde maliyeti üreten şey kod değişikliğinin büyüklüğü değil, bu 24 fazla turdur; her tur ayrı bir bütçenin sahibiyle yapılan bir uzlaşmadır.
Tablonun iki satırı sınırı gösteriyor. Üye doğrulama yeteneği iki sistemle karşılanıyor ama zinciri altı sisteme ve beş sahibe yayılıyor; bu kurumdaki en pahalı değişiklik odur, çünkü karşılayan iki sistemin sahibi bile farklı. Karşı uçta kullanım raporlaması var: tek sistem, sıfır veri, sıfır okuyan, sıfır koordinasyon turu. Raporlama hiçbir veri yazmıyor, yalnız okuyor; bu yüzden onda yapılan değişiklik hiçbir yere yayılmıyor. Bir sistemin değişim maliyetini belirleyen şey büyüklüğü değil, yazdığı verinin kaç okuyucusu olduğudur.
Zincirin Koptuğu Yerler
Zincir her yerde kurulamıyor; altı kopma noktası var ve her birinin farklı bir sonucu var.
İzlenemeyen yetenek iki tane: ücret tahsilatı ve satın alma önerisi. İkisi de yapılıyor ama hiçbir sisteme bağlanamıyor, dolayısıyla değiştiklerinde dokunulacak sistem listesi boş çıkıyor. Bu, değişikliğin bedava olduğu anlamına gelmez; bedelin sistem dışında, bankoda ve elde tutulan çizelgelerde ödendiği anlamına gelir.
Yetim sistem ve sahipsiz sistem aynı kaleme, arşive denk geliyor: hiçbir yeteneğe bağlanamıyor ve sahibi yazılı değil. Böyle bir sistem izlenebilirlik tablosunda hiç görünmez; kapatma kararı da, sürdürme kararı da savunmasız kalır.
Sahipsiz veri eski kayıttır — okunuyor ama yazanı yok; on veri varlığının dokuzuna bir yetenekten erişilebiliyor, erişilemeyen tek varlık budur. Önceki derste görüldüğü gibi bu boşluk süreçte bir insan kararı olarak geri döndü. Okunmayan veri ise sayım farkıdır: yazılıyor, kimse okumuyor. İkisi zincirin iki ucundaki kopmalardır ve ikisi de aynı şeyi söyler — bir veri varlığının değeri, iki ucunun da bağlı olmasındadır.
Özet
- İzlenebilirlik zinciri dört halkadır: yetenek, karşılayan sistemler, o sistemlerin yazdığı veri, o veriyi okuyan sistemler; koordinasyon turu etkilenen ayrı sahip sayısının bir eksiğidir.
- Model kurumdaki 13 yeteneğin 11’i izlenebiliyor; kalan ikisi hiçbir sisteme bağlanamıyor.
- Kısa zincir yetenek başına 1,55 sistem gösterirken tam zincir 4,73 gösteriyor; dokunulacak sistemlerin %67’si ilk halkada görünmüyor ve koordinasyon turu 5’ten 29’a çıkıyor.
- En geniş zincir üye doğrulamadır: 6 sistem, 5 sahip, 4 koordinasyon turu. En dar zincir kullanım raporlamasıdır: 1 sistem, 0 okuyan, 0 tur — çünkü hiçbir veri yazmıyor.
- Zincir 6 noktada kopuyor: 2 izlenemeyen yetenek, 1 yetim sistem, 1 sahipsiz sistem, 1 sahipsiz veri, 1 okunmayan veri; 10 veri varlığının 9’una bir yetenekten erişilebiliyor.
Sonraki Adım
Bu konu kurumu dört adımda modelledi: sistemler ile yetenekler eşlendi, aynı model iki çerçeve biçiminde belgelendi, bir iş süreci adım adım sınıflandırıldı ve yetenekten veriye izlenebilirlik kuruldu. Artık hangi yeteneğin hangi sistemde durduğu ve bir değişikliğin kaç sistemi ilgilendirdiği görünür. Görünmeyen tek şey kaldı ve bu kursun ikinci yarısının konusu odur: sistemlerin birbirine nasıl bağlandığı. Zincirde “şu sistem şu veriyi okuyor” diye geçen her halkanın arkasında bir taşıma biçimi var — verinin hangi yoldan geçtiği, ne sıklıkta yenilendiği, kopmasından kimin sorumlu olduğu. Çerçeve dersinde iki sorunun hiçbir biçimde yanıtlanamaması boşuna değildi: model bu alanları hiç taşımıyordu. Sonraki ders bağın kendisini bir seçim nesnesine çevirir ve aynı bağ kümesini farklı taşıma biçimleriyle kurup maliyetini sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.