İçeriğe geç
academia.sh

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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat