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

Collective Code Ownership

ไม่มี​ใคร “เป็น​เจ้าของ” code ส่วน​ใด​ส่วน​หนึ่ง — ทั้ง​ทีม​รับผิดชอบ​ร่วม​กัน

Collective code ownership เป็น​แนว​ปฏิบัติ​จาก Extreme Programming (XP) ที่ Kent Beck วาง​ไว้​เป็น​หนึ่ง​ใน core practices ตั้งแต่​ยุค​แรก​ของ XP โดย​มี​ข้อ​ตกลง​ชัดเจน​ว่า สมาชิก​ทุก​คนใน​ทีม “ไม่​เพียง​ได้​รับ​อนุญาต” แต่​ยัง​มี “หน้าที่” ที่​จะ​แก้ไข file code ใด​ก็ได้​เมื่อ​จำเป็น — ไม่มี​ใคร​เป็น​เจ้าของ module class หรือ layer ใด​โดย​เฉพาะ ทั้ง codebase เป็น​ของ​ทีม​ทั้ง​ทีม

Martin Fowler อธิบาย​ไว้​ว่า model code ownership มี​อยู่​สาม​แบบ​บน spec ต​รัม​เดียวกัน:

  • Strong ownership — แต่ละ module มี​เจ้าของ​คน​เดียว คน​อื่น​ต้อง​ขอ​อนุญาต​หรือ​ส่ง patch ให้​เจ้าของ​อนุมัติ​ก่อน
  • Weak ownership — module ยัง​มี “เจ้าของ” ที่​กำกับ​ดูแล แต่​ใคร​ใน​ทีม​ก็​แก้ไข​ได้ โดย​ควร​ปรึกษา​เจ้าของ​ก่อน​เปลี่ยนแปลง​ใหญ่
  • Collective (no) ownership — ทั้ง​ทีม​เป็น​เจ้าของ​ทุก​อย่าง​ร่วม​กัน ใคร​ก็​แก้​ตรง​ไหน​ก็ได้​โดย​ไม่​ต้อง​ขอ​อนุญาต​ใคร

Fowler เอง​บอกว่า​ส่วนตัว​ชอบ dynamics ของ​ทีม​แบบ collective ownership มากกว่า โดย​เฉพาะ​ใน​บริบท​ของ XP เพราะ​มัน​ลด​อุปสรรค​เทียม (artificial barriers) ที่​เกิด​จาก strong ownership เช่น การ​ที่​งาน​หนึ่ง​ต้อง​รอ​คน​อื่น​แก้ code ของ​เขา​ให้​ก่อน หรือ​การ​ที่​แม้แต่​การ rename method สาธารณะ​เล็ก ๆ ก็​กลาย​เป็น​เรื่อง​ใหญ่​เพราะ​ข้าม module boundary — ราวกับ​ทุก interface ภายใน​ถูก​ปฏิบัติ​เป็น published interface ที่​แก้​ไม่​ได้

หลักการ​เบื้องหลัง​คือ: เมื่อ​ไม่มี​ใคร​ผูกขาด​ความ​รู้​เกี่ยว​กับ​ส่วน​ใด​ส่วน​หนึ่ง​ของ​ระบบ ทีม​จะ​ไม่มี “อาณาจักร​ส่วนตัว” (fiefdoms) และ​ไม่มี single point of failure ด้าน knowledge สิ่ง​นี้​เปิด​ทาง​ให้ pair programming และ refactoring เกิด​ขึ้น​ได้​ทั่ว​ทั้ง codebase และ​เพิ่ม bus factor ของ project อย่าง​มี​นัย​สำคัญ

สิ่ง​นี้​สวน​ทาง​กับ​คำ​แนะนำ​เชิง​ถากถาง​แบบ​ดั้งเดิม​เรื่อง​ความ​มั่นคง​ใน​งาน — การ​เขียน code ลึกลับ​ที่​มี​แต่​คุณ​เข้าใจ​ดูเหมือน​จะ​ทำให้​คุณ​แทนที่​ได้​ยาก​และ​มั่นคง​ใน​ตำแหน่ง​ขึ้น แต่​แนว​ปฏิบัติ​เช่น​นั้น​เป็น​ผล​เสีย​ต่อ​ทั้ง project และ​ทีม นัก​พัฒนา​ที่​ทำงาน​ร่วม​กับ​ผู้​อื่น​ได้​อย่าง​มี​ประสิทธิภาพ​และ​ส่ง​มอบ​ผล​งาน​คุณภาพ​ได้ ย่อม​เป็น​ที่​ต้องการ​มากกว่า​คน​ที่​เขียน code กำกวม​และ​เข้าใจ​ยาก​เพียง​เพื่อ​ให้​ดู​ยาก (หรือ​ดู​ฉลาด)

Collective code ownership ไม่ใช่​แค่ “ประกาศ​ว่า​ใคร​แก้​อะไร​ก็ได้” แล้ว​จบ — Agile Alliance และ​แหล่ง​ข้อมูล​จาก XP community ระบุ​ตรง​กัน​ว่า​มัน​ต้อง​มี safety net รองรับ ไม่​งั้น​จะ​กลาย​เป็น​ความ​โกลาหล แนวทาง​ที่​ใช้​ร่วม​กัน​ได้แก่

  1. ตกลง coding standard ร่วม​กัน​ก่อน — ชื่อ file ชื่อ​ตัวแปร รูปแบบ​การ​จัด layer ต้อง​สอดคล้อง​กัน​ทั้ง codebase เพื่อ​ให้​ใคร​ก็ตาม​ที่​เข้า​มา​แก้ไข​ไม่รู้สึก​แปลก​แยก​กับ​สไตล์​ของ​คน​อื่น (ดู Naming Things)
  2. มี automated test suite ที่​หนาแน่น​เป็น safety netTest-Driven Development และ​ชุด​ทดสอบ​อัตโนมัติ​ทำ​หน้าที่​เป็น “รั้ว​กัน” ไม่​ให้​ใคร​แก้ code แล้ว​พัง​ส่วน​อื่น​โดย​ไม่รู้ตัว นี่​คือ​เงื่อนไข​ที่​ทำให้ “ใคร​แก้​ตรง​ไหน​ก็ได้” ปลอดภัย​พอที่​จะ​ทำ​จริง
  3. Pair programming เพื่อ​กระจาย​ความ​รู้​แบบ real-time — เมื่อ​สลับ​คู่​ทำงาน​เรื่อย ๆ ความ​รู้​เกี่ยว​กับ​ทุก​ส่วน​ของ​ระบบ​จะ​ไหล​ไป​ทั่ว​ทีม​โดย​ธรรมชาติ ไม่​กระจุก​อยู่​ที่​คน​ใด​คน​หนึ่ง
  4. Continuous Integration รวม code จาก​ทุก​คน​บ่อย ๆ — เมื่อ​หลาย​คน​แก้ file เดียวกัน​ใน​เวลา​ใกล้​กัน CI ช่วย​จับ conflict และ regression ได้​เร็ว ก่อน​ที่​ปัญหา​จะ​สะสม
  5. Refactor อย่าง​ต่อ​เนื่อง​แทน​การ​เขียน​ซ้ำ — เมื่อ​เห็น code ที่​ควร​ปรับปรุง ทุก​คน​มี​สิทธิ์ (และ​ควร) refactor ตรง​นั้น​ทันที ไม่​ต้อง​รอ “เจ้าของ” อนุมัติ
  6. Code review เป็น​กลไก​ตรวจสอบ​คุณภาพ ไม่ใช่ gatekeeping — แม้​ไม่มี​เจ้าของ แต่​ยัง​ต้อง​มี​คน​อ่าน​ทวน​เพื่อ​รักษา​คุณภาพ​และ​ความ​สอดคล้อง​ของ​สถาปัตยกรรม

ข้อ​สำคัญ​คือ​ทีม​ที่​ยัง​ไม่มี​วินัย​พอ (ยัง​ไม่มี test suite แน่น ยัง​ไม่​คุ้น​กับ pairing หรือ CI) อาจ​ไม่​พร้อม​กระโดด​เข้า​สู่ collective ownership เต็ม​รูปแบบ​ทันที — บาง​ทีม​เลือก​เริ่ม​จาก weak ownership แล้ว​ค่อย​ขยับ​ไป​สู่ collective ownership เมื่อ​ทีม​เติบโต​ด้าน​วินัย​และ​ความ​ไว้​วางใจ​มาก​ขึ้น

flowchart LR
    Dev[Developer คนใดก็ได้] --> Change[แก้ไข code ส่วนใดก็ได้]
    Change --> Tests[รัน automated tests]
    Tests -->|ผ่าน| CI[Continuous Integration]
    Tests -->|ไม่ผ่าน| Fix[แก้ไขทันที]
    Fix --> Tests
    CI --> Review[Code review โดยเพื่อนร่วมทีม]
    Review --> Shared[ความรู้กระจายทั่วทีม]
    Shared --> Dev

สมมติ​ทีม​กำลัง​พัฒนา​ระบบ e-commerce ด้วย C# นัก​พัฒนา A ปกติ​ทำงาน​ฝั่ง OrderService ส่วน​นัก​พัฒนา B ทำ​ฝั่ง InventoryService วัน1 A พบ​ว่าการ​จอง stock ใน InventoryService มี​ปัญหา concurrency ที่​กระทบ flow การ​สั่ง​ซื้อ​ของ​ตัวเอง ใน​ทีม​แบบ strong ownership เขา​ต้อง​รอ B ว่าง​มา​แก้ แต่​ใน​ทีม​แบบ collective ownership เขา​สามารถ​แก้​ได้​เอง เพียง​มั่นใจ​ว่า​มี test คุ้มครอง​อยู่

// InventoryService.cs — module ที่ปกติทีม B ดูแล
// แต่ A (จากทีม Orders) พบ bug และแก้ได้ทันที เพราะเป็น collective ownership
public class InventoryService
{
private readonly object _stockLock = new();
private readonly Dictionary<string, int> _stockLevels = new();
// เดิม: ไม่มี lock ทำให้เกิด race condition เมื่อสองคำสั่งซื้อจองสต็อกพร้อมกัน
// แก้ไข: ใส่ lock ครอบ critical section เพื่อกันการจองสต็อกเกิน (oversell)
public bool TryReserveStock(string sku, int quantity)
{
lock (_stockLock)
{
if (!_stockLevels.TryGetValue(sku, out var available) || available < quantity)
{
return false;
}
_stockLevels[sku] = available - quantity;
return true;
}
}
}
// InventoryServiceTests.cs — ชุดทดสอบที่เป็น safety net
// ทำให้ A มั่นใจได้ว่าการแก้ไข code ของ B ไม่พังพฤติกรรมเดิม
public class InventoryServiceTests
{
[Fact]
public void TryReserveStock_ConcurrentRequests_ShouldNotOversell()
{
var service = new InventoryService();
service.Seed("SKU-1", 5);
var results = Enumerable.Range(0, 10)
.AsParallel()
.Select(_ => service.TryReserveStock("SKU-1", 1))
.ToList();
// ต้องมีคำขอที่สำเร็จไม่เกินจำนวนสต็อกที่มีจริง
Assert.Equal(5, results.Count(success => success));
}
}

จาก​นั้น A เปิด pull request เพื่อ​ให้ B (และ​คน​อื่น​ใน​ทีม) review ตาม coding standard และ​รูปแบบ​ที่​ทีม​ตกลง​กัน​ไว้ — B ได้​เรียนรู้​เทคนิค​การ​ทำ lock แบบ​นี้​ไป​ด้วย ส่วน A ก็​เข้าใจ domain ของ inventory ลึก​ขึ้น นี่​คือ knowledge diffusion ที่ collective ownership ตั้งใจ​ให้​เกิด​ขึ้น

ใน​ระดับ​ทีม แนว​ปฏิบัติ​นี้​มัก​ถูก​กำหนด​เป็น​ข้อ​ตกลง​ลายลักษณ์​อักษร​ใน team charter หรือ CONTRIBUTING.md เช่น “ทุก​คน​มี​สิทธิ​และ​หน้าที่​แก้ code ส่วน​ใด​ก็ได้​ใน codebase หาก​พบ​ปัญหา​ให้​แก้ไข​ทันที​พร้อม​เพิ่ม test คุ้มครอง แล้ว​เปิด PR ให้​เจ้าของ area เดิม review”

ประโยชน์

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

ข้อ​ควร​ระวัง

  • ต้อง​มี​วินัย​รองรับ ไม่ใช่​แค่​ประกาศ​นโยบาย — บทความ​จาก InfoQ ชี้​ว่า​ทีม​ที่​ยัง​ไม่มี​วินัย​เพียงพอ (ไม่มี test suite แน่นหนา ไม่มี CI ที่​เชื่อถือ​ได้) จะ​พบ​ว่า collective ownership “เป็น​ปัญหา” มากกว่า​เป็น​ประโยชน์ บาง​ทีม​ถึง​ขั้น​ต้อง​ถอย​กลับ​ไป​ใช้ strong ownership ชั่วคราว​เพื่อ​ฝึก​วินัย​ก่อน​กลับ​มา​ใช้ collective ownership อีก​ครั้ง
  • ความ​เสี่ยง​ด้าน​คุณภาพ​และ​ความ​สอดคล้อง​ของ​สถาปัตยกรรม — ถ้า​ไม่มี coding standard, code review, และ test ที่​ดี​พอ การ​ที่​ใคร​ก็​แก้​ตรง​ไหน​ก็ได้​อาจ​ทำให้ codebase ไม่​สอดคล้อง​กัน หรือ​มี​คน​เขียน code คุณภาพ​ต่ำ​แทรก​เข้า​มา​โดย​ไม่มี​ใคร​ตรวจ​จับ
  • ความ​รับผิดชอบ​ที่​กระจาย​เกิน​ไป​อาจ​กลาย​เป็น “ไม่มี​ใคร​รับผิดชอบ” — Agile Alliance เตือน​ว่า​ความ​รับผิดชอบ​ที่​กระจาย​ออก​ไป​อาจ​นำ​ไป​สู่​ผล​ตรง​ข้าม คือ​ไม่มี​ใคร​รู้สึก​เป็น​เจ้าของ​จริง ๆ เลย​สัก​คน ต้อง​อาศัย interface และ boundary ที่​ชัดเจน​ช่วย​ประคอง
  • norm ที่​ไม่​เป็น​ทางการ​อาจ​ขัด​กับ​นโยบาย​ที่​ประกาศ​ไว้ — แม้​ทีม​จะ​ประกาศ collective ownership แต่​ถ้า​วัฒนธรรม​จริง​ยัง​กดดัน​ให้​คน​ไม่​กล้า​แตะ code ของ​คน​อื่น (เช่น เกรงใจ หรือ​กลัว​โดน​ตำหนิ) นโยบาย​ก็​ไม่​เกิด​ผล​จริง
  • ไม่​เหมาะ​กับ​ทุก​บริบท​เสมอ​ไป — Fowler เอง​บอกว่า​ความ​สำเร็จ​ของ​ทั้ง weak และ collective ownership ขึ้น​อยู่​กับ dynamics ของ​ทีม​มากกว่า​ตัว model เอง ทีม​ขนาด​ใหญ่​มาก​หรือ​ทีม​กระจาย​ตัว​ข้าม timezone อาจ​ต้อง​ปรับ​ใช้ weak ownership แทน