İçeriğe geç
academia.sh

Ders 02 / 12

Ürün Olarak Platform

İç müşteri ve geri bildirim döngüsünün ölçülmesi: aynı yirmi dört istek talep üzerine yapan ve ürün gibi yönetilen iki düzende koşturulur; benimseme, hiç kullanılmayan yetenek sayısı, ona harcanan iş, istek ile karşılık arası süre ve ürün yaklaşımının ürün ekiplerinde açtığı boşluk sayılır.

İçindekiler

Önceki ders platformu bir maliyet hesabı olarak kurdu: on sekiz kalem, devir bedeli, ekipte kalan artık ve kendini ödeme eşiği. Hesabın her satırı hangi kalemin devredileceğinin bilindiğini varsayıyordu. Gerçekte platform ekibinin elinde kalem listesi yoktur; istekler vardır ve istek ihtiyaçla aynı şey değildir. İki ekip aynı ihtiyacı iki ayrı istekle söyler; bir ekip istediği şeyi karşılık geldiğinde artık kullanmaz.

Bu ders aynı istek kümesini iki işletme biçiminde koşturur. Talep üzerine yapan düzen isteği geldiği gibi alır ve sırayla karşılar. Ürün gibi yönetilen düzen ekipleri iç müşteri sayar: istekleri arkalarındaki ihtiyaca göre toplar, hangi ihtiyacı kaç ekibin beklediğine bakar, bir ihtiyacı bir kez kurar; bedeli keşif işidir. Sayılanlar: benimseme, hiç kullanılmayan yetenek, ona harcanan iş, istek ile karşılık arasındaki süre ve ürün yaklaşımının ürün ekiplerinde açtığı boşluk. Through-line bölgesel ölçüm ağı ve onun beş ekibidir; ağ da ekipler de kurgudur.

İki İşletme Biçimi

PY7 — beş ekip ilk on iki çeyrekte yirmi dört istek açar; bu isteklerin arkasında on dört ayrı ihtiyaç vardır. Koşum on altı çeyrek sürer, çünkü biriken sıranın boşalması ancak istek akışı kesildikten sonra görülebilir. PY8 — platformun çeyrek başına kapasitesi 26 iş günüdür ve her koşumda aynıdır. Gerekçe: iki düzen ancak aynı kapasiteyle karşılaştırılabilir.

PY9 — talep üzerine düzen istekleri geliş sırasına göre işler ve aynı ihtiyaca gelen her isteği ayrı yetenek olarak kurar. PY10 — ürün gibi yönetilen düzen ilk iki çeyrekte yalnız keşif yapar, sonraki her çeyrekte kapasitenin 4 iş gününü keşfe ayırır, bir ihtiyacı bir kez kurar ve bekleyen ekip sayısı çok olanı öne alır. Gerekçe: ürün yaklaşımının ayırt edici yanı önceliği istek sırasından alıp ihtiyacın genişliğine bağlamasıdır, ve bu bilgi bedavaya gelmez.

PY11 — karşılık istekten dört çeyrekten geç gelirse ekip kendi çözümünü kurmuştur ve o yeteneği hiç kullanmaz. Gerekçe: bekleme yalnız gecikme değildir; belli bir uzunluktan sonra teslim edilen şeyin alıcısı kalmaz. Üçüncü bir koşum, keşifsiz ürün düzeni, keşif işinin bedelini ölçmek için eklenir.

// istek.mjs — ayni istek kumesi iki isletme bicimiyle kosturulur (model)
import { writeFileSync } from "node:fs";

// PY7 — bes ekibin ilk on iki ceyrekte actigi 24 istek ve arkalarindaki 14 ayri ihtiyac;
// kosum on alti ceyrek surer ki birikmis sira bosalsin. Sayilar kurgudur.
const IHTIYAC = {
  "ortam istegi": 28, "gizli deger dagitimi": 22, "hat sablonu": 18, "kanit arsivi": 16,
  "is yuku sablonu": 24, "ag kurali sablonu": 14, "olcek ayari": 12, "durum kaydi devri": 34,
  "surum defteri": 10, "gosterge baglama": 20, "gunluk borusu": 26, "uyari sablonu": 12,
  "imge tarama kapisi": 18, "yetki sablonu": 30,
};
const ISTEK = [
  [1, "sayac", "ortam istegi"], [1, "faturalama", "durum kaydi devri"],
  [2, "dogrulama", "hat sablonu"], [3, "saha", "ortam istegi"],
  [3, "raporlama", "gosterge baglama"], [4, "faturalama", "gizli deger dagitimi"],
  [4, "sayac", "ag kurali sablonu"], [5, "dogrulama", "olcek ayari"],
  [5, "saha", "gunluk borusu"], [6, "raporlama", "hat sablonu"],
  [6, "faturalama", "surum defteri"], [7, "sayac", "gosterge baglama"],
  [7, "dogrulama", "is yuku sablonu"], [8, "saha", "uyari sablonu"],
  [8, "faturalama", "kanit arsivi"], [9, "raporlama", "gunluk borusu"],
  [9, "sayac", "imge tarama kapisi"], [10, "dogrulama", "yetki sablonu"],
  [10, "saha", "gizli deger dagitimi"], [11, "faturalama", "hat sablonu"],
  [11, "raporlama", "ortam istegi"], [12, "sayac", "uyari sablonu"],
  [12, "dogrulama", "durum kaydi devri"], [12, "saha", "yetki sablonu"],
].map(([ceyrek, ekip, ihtiyac]) => ({ ceyrek, ekip, ihtiyac }));

// PY8 kapasite iki kosumda da 26 is gunu/ceyrek. PY9 talep uzerine duzen: gelis sirasi, her
// istek ayri yetenek. PY10 urun duzeni: ilk iki ceyrek yalniz kesif, sonra 4 is gunu/ceyrek
// kesif, bir ihtiyac bir kez, bekleyen ekip sayisina gore siralama. PY11 sabir dort ceyrek.
const KAPASITE = 26, KESIF = 4, CEYREK = 16, SABIR = 4;

function kos(ad, urun, kesifli = urun) {
  const istek = ISTEK.map((r) => ({ ...r, bitis: null }));
  const acik = [], kurulu = new Map();
  let yapim = 0, kesif = 0;
  for (let c = 1; c <= CEYREK; c++) {
    for (const r of istek.filter((x) => x.ceyrek === c)) {
      if (urun && kurulu.has(r.ihtiyac)) { r.bitis = c; continue; }
      const v = urun && acik.find((a) => a.ihtiyac === r.ihtiyac);
      if (v) { v.ekip.add(r.ekip); continue; }
      acik.push({ ihtiyac: r.ihtiyac, ekip: new Set([r.ekip]), kalan: IHTIYAC[r.ihtiyac] });
    }
    let g = KAPASITE;
    if (kesifli) { const k = c <= 2 ? KAPASITE : KESIF; kesif += k; g -= k; }
    if (urun) acik.sort((a, b) => b.ekip.size - a.ekip.size || a.kalan - b.kalan);
    while (g > 0 && acik.length) {
      const it = acik[0], h = Math.min(g, it.kalan);
      it.kalan -= h; g -= h; yapim += h;
      if (it.kalan > 0) break;
      acik.shift();
      if (urun) kurulu.set(it.ihtiyac, c);
      for (const r of istek)
        if (r.ihtiyac === it.ihtiyac && r.ceyrek <= c && r.bitis === null &&
          (urun || it.ekip.has(r.ekip))) { r.bitis = c; if (!urun) break; }
    }
  }
  for (const r of istek) {
    r.bekleme = r.bitis === null ? null : r.bitis - r.ceyrek;
    r.benimser = r.bitis !== null && r.bekleme <= SABIR;
  }
  return { ad, urun, istek, kurulu: [...kurulu], yapim, kesif,
    yetenek: urun ? kurulu.size : istek.filter((r) => r.bitis !== null).length };
}

const D = [kos("talep uzerine", false), kos("urun gibi", true),
  kos("urun, kesifsiz", true, false)];
writeFileSync("kosum.json", JSON.stringify({ IHTIYAC, D, SABIR }));
const ort = (v) => (v.length ? (v.reduce((a, b) => a + b, 0) / v.length).toFixed(1) : "-");
console.log("duzen".padEnd(16) + "yetenek".padStart(8) + "yapim".padStart(7) +
  "kesif".padStart(7) + "karsilanan".padStart(12) + "karsilanmayan".padStart(15) +
  "ort. bekleme".padStart(14) + "benimseyen".padStart(12));
for (const d of D) {
  const b = d.istek.filter((r) => r.bitis !== null);
  console.log(d.ad.padEnd(16) + `${d.yetenek}`.padStart(8) + `${d.yapim}`.padStart(7) +
    `${d.kesif}`.padStart(7) + `${b.length}`.padStart(12) +
    `${d.istek.length - b.length}`.padStart(15) + ort(b.map((r) => r.bekleme)).padStart(14) +
    `${d.istek.filter((r) => r.benimser).length}`.padStart(12));
}

console.log("\n" + "ekip".padEnd(13) + "istek".padStart(6) +
  D.map((d) => d.ad.padStart(16) + "benimsenen".padStart(12)).join(""));
for (const e of [...new Set(ISTEK.map((r) => r.ekip))]) {
  console.log(e.padEnd(13) + `${ISTEK.filter((r) => r.ekip === e).length}`.padStart(6) +
    D.map((d) => {
      const x = d.istek.filter((r) => r.ekip === e);
      return ort(x.filter((r) => r.bitis !== null).map((r) => r.bekleme)).padStart(16) +
        `${x.filter((r) => r.benimser).length}`.padStart(12);
    }).join(""));
}
duzen            yetenek  yapim  kesif  karsilanan  karsilanmayan  ort. bekleme  benimseyen
talep uzerine         20    416      0          20              4           3.2          16
urun gibi             14    284    108          24              0           2.3          20
urun, kesifsiz        14    284      0          24              0           0.7          24

ekip          istek   talep uzerine  benimsenen       urun gibi  benimsenen  urun, kesifsiz  benimsenen
sayac             5             3.0           3             1.0           5             0.4           5
faturalama        5             3.2           4             4.4           3             1.8           5
dogrulama         5             3.3           3             3.4           4             0.2           5
saha              5             3.5           3             1.4           4             0.8           5
raporlama         4             3.0           3             1.3           4             0.0           4

Bekleme ve Benimseme

İlk tablo iki düzeni yan yana koyar. Talep üzerine düzen yirmi yetenek kurar ve 416 iş günü harcar; dört istek on altı çeyrek boyunca sıraya bile giremez. Ürün düzeni aynı yirmi dört isteği on dört yetenekle ve 284 iş günü yapımla karşılar — dört istek daha fazlasını, yüz otuz iki iş günü daha azıyla. Fark yapım hızında değil, yinelemededir: hat sablonu da ortam istegi de üçer kez kurulur, çünkü her istek ayrı bir yetenektir.

Bekleme sayıları bunu yumuşatır. Talep üzerine düzende ortalama bekleme 3,2 çeyrek, ürün düzeninde 2,3 çeyrektir; keşifsiz koşumda 0,7 çeyreğe iner. Aradaki 1,6 çeyrek keşif işinin fiyatıdır: ilk iki çeyreğin tamamı ve sonraki her çeyreğin dört iş günü yapıma gitmemektedir.

İkinci tablo ürün düzeninin kimden aldığını gösterir. sayac beklemesi 3,0’dan 1,0’a, saha 3,5’ten 1,4’e iner. faturalama ise ters yöne gider: beklemesi 3,2’den 4,4 çeyreğe çıkar ve benimsediği istek sayısı dörtten üçe düşer. Nedeni önceliklendirme kuralıdır — surum defteri ve kanit arsivi yalnız faturalamanın istediği ihtiyaçlardır ve bekleyen ekip sayısına göre sıralanan bir kuyruğun sonuna düşerler. Ürün yaklaşımı çoğunluğun ihtiyacını öne alırken azınlığın ihtiyacını geriye atar; bu bir yan etki değil, kuralın kendisidir.

Ölü Yetenek ve Ürün Yaklaşımının Bedeli

PY12 — ürün düzeninin keşif işi platform kapasitesinden düşülür; bunun üstüne her istek için isteyen ekipten 2 iş günü görüşme ve her çeyrek her ekipten 1 iş günü geri bildirim alınır. Bu ikinci kalem ürün ekiplerinde açılan boşluktur ve platformun defterine hiç yazılmaz. Kırk iş günü bir kişi-çeyrek sayılır. Gerekçe: ürün yaklaşımının bedeli platform ekibinde değil, ölçtüğü ekiplerde birikir; aynı birime çevrilmeden iki taraf toplanamaz.

// benimseme.mjs — benimseme dagilimi, olu yetenek ve urun yaklasiminin bedeli
import { readFileSync } from "node:fs";
const { IHTIYAC, D, SABIR } = JSON.parse(readFileSync("kosum.json", "utf8"));
const EKIP = [...new Set(D[0].istek.map((r) => r.ekip))];

// Bir yetenegin benimseyen ekipleri: talep uzerine duzende yetenek istegi acan tek ekibe
// aittir; urun duzeninde ayni ihtiyaci isteyen butun ekipler tek yetenegi paylasir.
function yetenekler(d, sabir = SABIR) {
  const alan = (r) => r.bitis !== null && r.bitis - r.ceyrek <= sabir;
  if (!d.urun)
    return d.istek.filter((r) => r.bitis !== null)
      .map((r) => ({ ihtiyac: r.ihtiyac, is: IHTIYAC[r.ihtiyac], benimseyen: alan(r) ? 1 : 0 }));
  return d.kurulu.map(([ih]) => ({ ihtiyac: ih, is: IHTIYAC[ih],
    benimseyen: d.istek.filter((r) => r.ihtiyac === ih && alan(r)).length }));
}

console.log("duzen".padEnd(16) + "yetenek".padStart(8) + "yinelenen yapim".padStart(17) +
  "olu yetenek".padStart(13) + "olu yetenege giden is".padStart(23) +
  "ekip-yetenek cifti".padStart(20) + "yetenek basina".padStart(16));
for (const d of D) {
  const Y = yetenekler(d), olu = Y.filter((y) => y.benimseyen === 0);
  const tekil = [...new Set(Y.map((y) => y.ihtiyac))].reduce((t, i) => t + IHTIYAC[i], 0);
  const cift = Y.reduce((t, y) => t + y.benimseyen, 0);
  console.log(d.ad.padEnd(16) + `${Y.length}`.padStart(8) + `${d.yapim - tekil}`.padStart(17) +
    `${olu.length}`.padStart(13) + `${olu.reduce((t, y) => t + y.is, 0)}`.padStart(23) +
    `${cift}`.padStart(20) + (cift / Y.length).toFixed(2).padStart(16));
}

const adet = (ih) => new Set(D[0].istek.filter((r) => r.ihtiyac === ih).map((r) => r.ekip)).size;
for (const d of D.slice(0, 2)) {
  const olu = [...new Set(yetenekler(d).filter((y) => y.benimseyen === 0).map((y) => y.ihtiyac))];
  console.log(`${d.ad}: hic kullanilmayan yetenek — ` +
    olu.map((ih) => `${ih} (${IHTIYAC[ih]} is gunu, ${adet(ih)} ekip istedi)`).join("; "));
}

// PY12 — urun duzeninin kesif isi platform kapasitesinden dusuldu; ustune her istek icin
// isteyen ekipten 2 is gunu gorusme ve her ceyrek her ekipten 1 is gunu geri bildirim alinir.
// Bu ikinci kalem urun ekiplerinde acilan bosluktur. 40 is gunu bir kisi-ceyrektir.
const KC = 40, CEYREK = 16;
const gorusme = D[0].istek.length * 2, geri = EKIP.length * CEYREK;
const bosluk = gorusme + geri, kesif = D[1].kesif;
console.log(`\nurun duzeninin bedeli — platformda kesif ${kesif} is gunu ` +
  `(${(kesif / KC).toFixed(1)} kisi-ceyrek); urun ekiplerinde gorusme ${gorusme} + ` +
  `geri bildirim ${geri} = ${bosluk} is gunu (${(bosluk / KC).toFixed(1)} kisi-ceyrek)`);
console.log(`platformun yapim isinde kazanc: ${D[0].yapim} - ${D[1].yapim} = ` +
  `${D[0].yapim - D[1].yapim} is gunu; urun ekiplerine yazilan bosluk ${bosluk} is gunu ` +
  `(kazancin %${(100 * bosluk / (D[0].yapim - D[1].yapim)).toFixed(0)}'i)`);

// Geri bildirim dongusunun uzunlugu tek kaldirac: sabir penceresi taranir.
console.log("\n" + "sabir (ceyrek)".padEnd(16) +
  D.map((d) => d.ad.padStart(17)).join("") + "   (benimsenen istek / olu yetenege giden is)");
for (let s = 2; s <= 6; s++)
  console.log(`${s}`.padEnd(16) + D.map((d) => {
    const Y = yetenekler(d, s);
    const b = d.istek.filter((r) => r.bitis !== null && r.bitis - r.ceyrek <= s).length;
    return `${b} / ${Y.filter((y) => y.benimseyen === 0).reduce((t, y) => t + y.is, 0)}`
      .padStart(17);
  }).join(""));
duzen            yetenek  yinelenen yapim  olu yetenek  olu yetenege giden is  ekip-yetenek cifti  yetenek basina
talep uzerine         20              132            4                     88                  16            0.80
urun gibi             14                0            1                     24                  20            1.43
urun, kesifsiz        14                0            0                      0                  24            1.71
talep uzerine: hic kullanilmayan yetenek — imge tarama kapisi (18 is gunu, 1 ekip istedi); yetki sablonu (30 is gunu, 2 ekip istedi); gizli deger dagitimi (22 is gunu, 2 ekip istedi); hat sablonu (18 is gunu, 3 ekip istedi)
urun gibi: hic kullanilmayan yetenek — is yuku sablonu (24 is gunu, 1 ekip istedi)

urun duzeninin bedeli — platformda kesif 108 is gunu (2.7 kisi-ceyrek); urun ekiplerinde gorusme 48 + geri bildirim 80 = 128 is gunu (3.2 kisi-ceyrek)
platformun yapim isinde kazanc: 416 - 284 = 132 is gunu; urun ekiplerine yazilan bosluk 128 is gunu (kazancin %97'i)

sabir (ceyrek)      talep uzerine        urun gibi   urun, kesifsiz   (benimsenen istek / olu yetenege giden is)
2                         7 / 254          15 / 40           21 / 0
3                        13 / 154          18 / 24           22 / 0
4                         16 / 88          20 / 24           24 / 0
5                         19 / 22          21 / 24           24 / 0
6                          20 / 0          22 / 24           24 / 0

Benimseme sütunu asıl farkı verir. Talep üzerine düzende bir yeteneği ortalama 0,80 ekip kullanır — birden küçüktür, çünkü yeteneklerin dördü hiç kullanılmaz. Ürün düzeninde aynı sayı 1,43, keşifsiz koşumda 1,71’dir. Yirmi yetenek on altı ekip-yetenek çifti üretirken on dört yetenek yirmi çift üretir: daha az yetenek, daha çok kullanım.

Hiç kullanılmayan yetenek satırı iki düzende farklı bir hikâye anlatır. Talep üzerine düzende dört yetenek ölüdür ve 88 iş günü onlara gitmiştir; bunlardan hat sablonu üç ekibin istediği bir ihtiyaçtır — istek geldiğinde önemliydi, karşılık geldiğinde geç kalmıştı. Ürün düzeninde tek bir ölü yetenek vardır: is yuku sablonu, 24 iş günü, tek ekibin istediği ihtiyaç. Ölü işin kaynağı karşıttır: birinde sıranın uzunluğu, diğerinde önceliklendirmenin kendisi.

Bedel satırı ürün yaklaşımının faturasını keser. Platformda keşfe giden iş 108 iş günü, yani 2,7 kişi-çeyrektir. Ürün ekiplerinde açılan boşluk 128 iş günü, 3,2 kişi-çeyrektir. Platformun yapım işinde kazandığı 132 iş günüdür ve ürün ekiplerine yazılan boşluk bunun %97’sidir. Platformun defterinde görünen kazancın neredeyse tamamı, görünmeyen bir defterde geri ödenir.

Son tarama sabır penceresini değiştirir. İki çeyreklik sabırda talep üzerine düzen yirmi dört isteğin yalnız yedisini zamanında karşılar ve 254 iş günü ölü işe gider; ürün düzeninde aynı sayı 15 ve 40’tır. Pencere altı çeyreğe açıldığında talep üzerine düzenin ölü işi sıfıra iner, ürün düzeninde ise 24 iş günü olarak kalır. Sabırlı ekiplerde sıra beklemek işe yarar; sıralamanın geriye attığı ihtiyaç ise beklemekle gelmez.

Özet

  • Aynı 24 istek (14 ayrı ihtiyaç, 5 ekip, 16 çeyrek, çeyrek başına 26 iş günü kapasite) iki düzende koşturuldu: talep üzerine 20 yetenek ve 416 iş günü, ürün gibi 14 yetenek ve 284 iş günü.
  • Talep üzerine düzende yinelenen yapım 132 iş günüdür; dört istek hiç karşılanmaz. Ürün düzeni yirmi dört isteğin hepsini karşılar.
  • Ortalama bekleme talep üzerine 3,2, ürün gibi 2,3, keşifsiz ürün koşumunda 0,7 çeyrektir; aradaki 1,6 çeyrek keşif işinin fiyatıdır.
  • Yetenek başına benimseme 0,80’den 1,43’e çıkar; hiç kullanılmayan yetenek dörtten (88 iş günü) bire (is yuku sablonu, 24 iş günü) iner. Ölü işin kaynağı birinde sıra, diğerinde önceliktir.
  • faturalama ekibinin beklemesi ürün düzeninde 3,2’den 4,4 çeyreğe çıkar ve benimsediği istek dörtten üçe iner: tek ekibin istediği ihtiyaç kuyruğun sonuna düşer.
  • Ürün yaklaşımının bedeli platformda 108, ürün ekiplerinde 128 iş günüdür; ikincisi platformun yapım işinde kazandığı 132 iş gününün %97’sine denktir.

Sonraki Adım

İki düzen de aynı sorunun iki yanıtıdır: platform neyi yapsın. Ürün düzeni yanıtı ihtiyacın genişliğine bağladı ve azınlığın ihtiyacını geriye attı; talep üzerine düzen sırayı korudu ve 132 iş günü yinelenen yapım ödedi. İkisinin de söylemediği şey sınırdır: platformun neyi kapsayıp neyi kapsamadığı hiçbir yerde yazılı değildi. Sonraki ders bu sınırı tanımlar — bir yol kapsam olarak yazılır, beş ekibin gereksinimine uygulanır, kaç ekibin sığdığı ve dışına çıkanın kalem kalem neyi kaybettiği sayılır, sonra yolu genişletmenin bakım yüküne ne yaptığı taranır.

İ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