ข้าม​ไป​ยัง​เนื้อหา

Mushroom Management

เลี้ยง​นัก​พัฒนา​เหมือน​เห็ด — ขัง​ไว้​ใน​ที่​มืด​และ​ป้อน​แต่​เรื่อง​ไร้​สาระ

Mushroom Management คือ​การ​ปฏิบัติ​ต่อ​นัก​พัฒนา​เหมือน​เห็ด — “ขัง​ไว้​ใน​ที่​มืด​และ​ป้อน​แต่​ปุ๋ยคอก” เป็น​สำนวน​เก่า​แก่​ที่​ปรากฏ​ใน​แวดวง​องค์กร​อเมริกัน​มา​นาน (มี​การ​อ้าง​ถึง​ตั้งแต่​หนังสือ The Soul of a New Machine ของ Tracy Kidder ปี 1981) ก่อน​จะ​ถูก​นำ​มา​ใช้​บรรยาย​วัฒนธรรม​การ​ทำงาน​ใน​ทีม​ซอฟต์แวร์​ที่​สร้าง​กำแพง​ระหว่าง​คน​พัฒนา​กับ​คนใช้งาน​จริง

แก่น​ของ​ปัญหา​คือ ช่อง​ทาง​สื่อสาร​ระหว่าง​ฝ่าย​บริหาร/ลูกค้า​กับ​นัก​พัฒนา​ใช้งาน​ไม่​ได้​ผล นัก​พัฒนา​ไม่รู้​ทิศทาง​ธุรกิจ ไม่รู้​ว่า feature ที่​กำลัง​เขียน​แก้​ปัญหา​อะไร​ให้​ใคร ได้​รับ​แต่ requirement เป็น​ชิ้น​เล็ก​ชิ้น​น้อย​ที่​ถูก​กรอง​ผ่าน​คนกลาง​หลาย​ชั้น (ผู้จัดการ → team lead → นัก​พัฒนา) โดย​ไม่มี​บริบท​ว่า “ทำไม” ต้อง​ทำ​สิ่ง​นี้ ผล​คือ feedback loop ระหว่าง​คน​สร้าง​ซอฟต์แวร์​กับ​คนใช้​มัน​ยืดยาว​ออก​ไป​มาก — หรือ​ขาด​หาย​ไป​เลย — เปิด​ช่อง​ให้​เกิด​การ​สื่อสาร​ผิดพลาด ตีความ​สมมติฐาน​ผิด และ​สร้าง​ของ​ผิด​ตัว​ไป​เรื่อย ๆ โดย​ไม่มี​ใคร​รู้​จน​สาย​เกิน​แก้

  • ดูเหมือน​มี​ประสิทธิภาพ — ผู้จัดการ​รู้สึก​ว่าการ​กรอง​ข้อมูล​ก่อน​ส่ง​ต่อ​ช่วย​ไม่​ให้​นัก​พัฒนา “เสีย​เวลา” กับ​รายละเอียด​ธุรกิจ​ที่​ไม่​เกี่ยว​กับ code โดยตรง
  • ควบคุม​ง่าย​กว่า — ข้อมูล​คือ​อำนาจ การ​เป็น​จุด​เดียว​ที่​ถือ​ข้อมูล​ครบ​ทำให้​ผู้จัดการ​รู้สึก​จำเป็น​และ​มี​สถานะ​สูง​กว่า​ใน​ทีม
  • ปกป้อง​ความ​ลับ​ทาง​ธุรกิจ — มี​เหตุผล​ที่​ฟัง​ขึ้น​บาง​ส่วน​ว่า​ไม่​อยาก​ให้​ข้อมูล​ลูกค้า สัญญา หรือ​แผน​กลยุทธ์​รั่วไหล​ผ่าน​คน​จำนวน​มาก
  • ลด​การ​ประชุม/สื่อสาร​ที่​ผู้จัดการ​มอง​ว่า “รบกวน” — ตัด​นัก​พัฒนา​ออก​จาก​ที่​ประชุม​กับ​ลูกค้า​เพื่อ​ไม่​ให้ “เสีย​สมาธิ” จาก​งาน​เขียน code
  • สืบทอด​มา​จาก​โครงสร้าง​องค์กร​แบบ​ลำดับ​ชั้น — ใน​องค์กร​ที่​ยึด​สาย​บังคับบัญชา​เข้มงวด การ​ส่ง​ข้อมูล​ผ่าน​ชั้น​บริหาร​ดู​เป็น “ระเบียบ​ที่​ถูกต้อง” อยู่​แล้ว

เหตุผล​เหล่า​นี้​ฟัง​ดู​มี​เหตุผล​ใน​ระยะ​สั้น แต่​ล้วน​แลก​มา​ด้วย​คุณภาพ​ของ​งาน​และ​แรง​จูงใจ​ของ​ทีม​ใน​ระยะ​ยาว

  • feedback loop ยาว​หรือ​ขาด​หาย — ยิ่ง​ข้อมูล​เดิน​ทางผ่าน​คนกลาง​มาก​เท่าไร ยิ่ง​ใช้​เวลา​นาน​กว่า​จะ​รู้​ว่า​สิ่ง​ที่​สร้าง​ถูก​หรือ​ผิด bug เชิง​ความ​ต้องการ (requirement bug) จะ​ถูก​พบ​ช้า​ที่สุด​เท่า​ที่​จะ​ช้า​ได้ — มัก​จะ​หลัง deploy ไป​แล้ว
  • เอฟเฟกต์โทรศัพท์​เสีย (telephone game) — requirement ที่​ผ่าน​คนกลาง​หลาย​ชั้น​มัก​ถูก​บิดเบือน สรุป​ย่อ​จน​ขาด​บริบท หรือ​ถูก​ตีความ​ใหม่​ตาม​ความ​เข้าใจ​ของ​แต่ละ​คน ทำให้​สิ่ง​ที่​นัก​พัฒนา​สร้าง​ไม่​ตรง​กับ​สิ่ง​ที่​ลูกค้า​ต้องการ​จริง
  • นัก​พัฒนา​เดา​แทนที่​จะ​รู้ — เมื่อ​ไม่มี​บริบท นัก​พัฒนา​ต้อง​เติม​ช่องว่าง​ด้วย​สมมติฐาน​ของ​ตัวเอง ซึ่ง​มัก​ผิด และ​ผิด​แบบ​เงียบ ๆ ไม่มี​ใคร​ทักท้วง​จนกว่า​จะ​สาย (ดู Assumption-Driven Development)
  • ไม่มี​ความ​เป็น​เจ้าของ​งาน (ownership) — คน​ที่​ไม่รู้ “ทำไม” ยาก​ที่​จะ​รู้สึก​รับผิดชอบ​ต่อ “ผลลัพธ์” มัก​ทำ​แค่​ตาม spec ให้​ผ่าน ไม่​คิด​ต่อยอด​หรือ​ทักท้วง​เมื่อ​เห็น spec ไม่​สม​เหตุผล
  • ขวัญ​กำลังใจ​ตกต่ำ — การ​ถูกกัน​ออก​จาก​บริบท​ซ้ำ ๆ ทำให้​นัก​พัฒนา​รู้สึก​ไม่​ได้​รับ​ความ​ไว้​วางใจ ไม่​ถูก​มอง​ว่า​มี​ความ​สามารถ​พอ​จะ​เข้าใจ​ภาพ​รวม สะสม​ความเฉื่อยชา​และ cynicism ใน​ทีม
  • ตอบ​สนอง​สถานการณ์​เร่งด่วน​ไม่ทัน — เมื่อ​ธุรกิจ​ต้องการ​การ​ตัดสิน​ใจ​ไว ทีม​ที่​ไม่มี​บริบท​จะ​ตัดสิน​ใจ​เอง​ไม่​ได้ ต้อง​รอ​ผ่าน​คนกลาง​ทุก​ครั้ง ทำให้​ทีม​ช้า​ลง​เป็น​ระบบ
  • สอดคล้อง​กับ Conway’s Law ใน​ทาง​ลบ — โครงสร้าง​การ​สื่อสาร​ที่​ตัดขาด​กัน​จะ​สะท้อน​ออก​มา​เป็น​สถาปัตยกรรม​ซอฟต์แวร์​ที่​แตก​กระจาย ไม่​ประสาน​กัน (ดู Conway’s Law)

สมมติ​มี ticket สั้น ๆ ว่า “ลูกค้า VIP ควร​ได้​ส่วนลด” ส่ง​ผ่าน​มา​จาก​ฝ่าย​ขาย​ถึง​ผู้จัดการ ถึง team lead แล้ว​มา​ถึง​นัก​พัฒนา โดย​ไม่มี​ใคร​อธิบาย​ว่า “VIP” หมาย​ถึง​อะไร นัก​พัฒนา​ที่​ถูกกัน​ออก​จาก​การ​พูด​คุย​กับ​ฝ่าย​ขาย​หรือ​ลูกค้า​โดยตรง​จึง​ต้อง​เดา​เอง:

// Ticket: "ลูกค้า VIP ควรได้ส่วนลด" — ไม่มีรายละเอียดเพิ่มเติม
// นักพัฒนาไม่เคยได้คุยกับฝ่ายขายหรือลูกค้าเลย ต้องเดาเอาเอง
public decimal CalculateDiscount(Order order, Customer customer)
{
// เดาว่า VIP คือคนที่ยอดสั่งซื้อครั้งนี้เกิน 1000 บาท เพราะฟังดูมีเหตุผล
if (order.Total > 1000m)
{
return order.Total * 0.1m; // เดาว่าน่าจะลด 10%
}
return 0m;
}

code นี้ compile ผ่าน test เอง (แบบ​เดา ๆ) ก็​ผ่าน แต่​เมื่อ​ขึ้น production ฝ่าย​ขาย​กลับ​พบ​ว่า​ลูกค้า VIP ตัว​จริง (สมาชิก​ระดับ Gold ที่​สั่ง​ของ​ชิ้น​เล็ก​ราคา​ต่ำ​กว่า 1000 บาท) ไม่​ได้​ส่วนลด​เลย ใน​ขณะ​ที่​ลูกค้า​ทั่วไป​ที่​บังเอิญ​สั่ง​ของ​ชิ้น​ใหญ่​ครั้ง​เดียว​กลับ​ได้​ส่วนลด​ไป​ฟรี ๆ — เป็น​ความ​เสียหาย​ทาง​ธุรกิจ​ที่​ตรวจ​พบ​ช้า​ไป​หลาย​สัปดาห์

หลัง​จาก​นัก​พัฒนา​ได้​พูด​คุย​ตรง​กับ Product Owner (ปิด feedback loop ให้​สั้น​ลง) ก็​พบ​ว่า “VIP” อ้างอิง​จาก​ระดับ​สมาชิก (membership tier) ไม่​เกี่ยว​กับ​ยอด​คำ​สั่ง​ซื้อ​ครั้ง​นี้​เลย และ​อัตราส่วนลด​ก็​ถูก​กำหนด​ไว้​เป็น​ตาราง​ธุรกิจ​ที่​ชัดเจน:

// หลังคุยตรงกับ Product Owner: VIP = สมาชิกระดับ Gold ขึ้นไป
// ไม่เกี่ยวกับยอดสั่งซื้อครั้งนี้ และอัตราส่วนลดขึ้นกับ MembershipTier ของลูกค้า
public enum MembershipTier
{
Standard,
Silver,
Gold,
Platinum
}
public class Membership
{
public MembershipTier Tier { get; init; }
public bool IsEligibleForDiscount => Tier >= MembershipTier.Gold;
public decimal DiscountRate => Tier switch
{
MembershipTier.Gold => 0.10m,
MembershipTier.Platinum => 0.15m,
_ => 0m,
};
}
public decimal CalculateDiscount(Order order, Customer customer)
{
if (!customer.Membership.IsEligibleForDiscount)
{
return 0m;
}
return order.Total * customer.Membership.DiscountRate;
}

ชื่อ MembershipTier, IsEligibleForDiscount และ​คอมเมนต์​ที่​อ้างอิง​บทสนทนา​จริง​กับ Product Owner ทำให้ code สื่อ “ทำไม” ไม่ใช่​แค่ “ทำ​อะไร” — คน​อ่าน code ใน​อนาคต​เข้าใจ​กฎ​ธุรกิจ​ได้​ทันที​โดย​ไม่​ต้อง​เดา

แผนภาพ​ด้าน​ล่าง​เทียบ​โครงสร้าง​การ​สื่อสาร​สอง​แบบ:

flowchart LR
    subgraph MushroomManagement
        Customer1[Customer] --> Manager1[Manager]
        Manager1 --> Lead1[TeamLead]
        Lead1 --> Dev1[Developer]
        Dev1 -.guess.-> Code1[Code]
    end
    subgraph WholeTeam
        Customer2[Customer] --> Dev2[Developer]
        Dev2 --> Code2[Code]
    end
  • ทำงาน​แบบ Whole Team — ให้​ตัวแทน​ลูกค้า (product owner, domain expert) นั่ง​ทำงาน​ร่วม​กับ​ทีม​พัฒนา​โดยตรง แทนที่​จะ​ส่ง​ข้อมูล​ผ่าน​คนกลาง​หลาย​ชั้น (ดู Whole Team และ Whole Team Activity)
  • ทำให้ “เป้าหมาย” ชัดเจน​ตั้งแต่​ต้น — ทุก​คนใน​ทีม​ควร​รู้​ว่า​กำลัง​มุ่ง​ไป​ทาง​ไหน​และ​ทำไม ไม่ใช่​แค่​ได้​รับ task แยก​ส่วน (ดู Know Where You Are Going)
  • สั้น feedback loop ให้​มาก​ที่สุด — เดโม​บ่อย ๆ ให้​ลูกค้า​ดู​ของ​จริง​เร็ว​ที่สุด แทนที่​จะ​รอ​จน​จบ sprint หรือ​จบ project
  • บันทึก “ทำไม” ไว้​ใน​ที่​ที่​นัก​พัฒนา​เข้าถึง​ได้ — ใช้ ADR, ticket ที่​มี​บริบท​ครบ, หรือ ubiquitous language ที่​สะท้อน​กฎ​ธุรกิจ​จริง​ใน code แทน​คำ​สั่ง​ดิบ ๆ ที่​ถูก​ตัดทอน
  • ทำ prototype หรือ walking skeleton ให้​ลูกค้า​ตรวจสอบ​ไว — เพื่อ​จับ​ความ​เข้าใจ​ผิด​ตั้งแต่​เนิ่น ๆ ก่อน​ลงมือ​สร้าง​เต็ม​รูปแบบ
  • ผู้จัดการ​เปลี่ยน​บทบาท​จาก “ผู้​กรอง​ข้อมูล” เป็น “ผู้​เปิด​ช่อง​ทาง​สื่อสาร” — ความ​โปร่งใส​คือ​ทาง​แก้​หลัก​ตาม​ที่ Wikipedia สรุป​ไว้: ผู้​บริหาร​ต้อง​ฝึก​ทักษะ​สื่อสาร​และ​กระจาย​ข้อมูล​ให้​ทีม ไม่ใช่​กั้น​มัน​ไว้