TERRA RPC

กำลังเตรียมกระดาน…

Agent Dev Thai Academyprinciples · patterns · architecture
หลักสูตร · Clean Architecture ในโค้ดจริง
0/5
Clean Architecture ในโค้ดจริง · ร้านเดียว สี่กระดาน

กฎของระบบอยู่ไฟล์ไหน

ร้านขายคอร์สออนไลน์ร้านหนึ่ง ให้สมาชิก Gold ลด 10% ไม่เกิน 500 บาท สัปดาห์นี้ร้านจะเพิ่มขายผ่าน LINE อัปเกรด Next.js เปลี่ยนชื่อคอลัมน์ใน DB และย้ายฐานข้อมูล ทุกงานเริ่มด้วยคำถามเดียวกัน กฎส่วนลดอยู่ไฟล์ไหน และ AI จะหาเจอไหม

SOLID ตอบว่าอะไรใช้แทนกันได้ Clean Architecture ตอบว่ากฎของระบบควรอยู่ตรงไหน อะไรส่งเข้าไปหามันได้ คุณเช็กมันได้โดยไม่เปิดเบราว์เซอร์ไหม และไฟล์ไหนเป็นคนต่อทุกอย่างเข้าด้วยกัน สำหรับคนที่ให้ AI เขียนโค้ด นี่คือเรื่องของ context: AI ต้องเปิดกี่ไฟล์เพื่อหากฎข้อเดียว ถ้าหาไม่เจอ มันจะเขียนใหม่จากความจำ แล้วร้านจะมีกฎส่วนลดสองเวอร์ชัน ร้านเดียวกันทั้งสี่กระดาน กดถัดไปแล้วนับว่าไฟล์ไหนต้องแก้ตาม และอะไรพังเงียบ ๆ บทจะถูกนับว่าเรียนจบเมื่อคุณไปถึงขั้นสุดท้ายของรูป

1
ตอนที่ 1 · กฎส่วนลดอยู่ที่เดียวเพิ่มขายผ่าน LINE bot แล้วส่วนลด Gold ลืมเพดาน 500 บาท
เรื่องย่อ

ร้านขายคอร์สออนไลน์ของคุณให้ส่วนลดสมาชิก Gold 10% สูงสุด 500 บาท ตอนนี้ขายผ่านหน้าเว็บอย่างเดียว แล้วคุณอยากขายผ่าน LINE bot ด้วย คุณสั่ง AI เขียนบอท

บนฝั่งขวาไม่มีชั้นกฎ AI หากฎส่วนลดไม่เจอ เพราะมันซ่อนอยู่ในหน้าจอ มันเลยเขียนกฎใหม่จากความจำ แล้วลืมเพดาน 500 ใน diff มันดูเหมือนโค้ดที่ถูก เพราะไม่มีอะไรให้เทียบ

ทั้งสองฝั่งขายคอร์สให้สมาชิก Gold ลด 10% แต่ไม่เกิน 500 บาท ซ้ายเก็บกฎไว้ในไฟล์กฎส่วนลดไฟล์เดียว แล้วหน้าจอแค่เรียก ขวาเก็บกฎไว้ในหน้าชำระเงินบนเว็บ เราจะเพิ่มช่องทางขายทาง LINE แล้วดูว่ากฎไปอยู่ที่ไหน

กล่องบนกระดานนี้ · 3
ส่วนทำอะไรทำไม
กฎส่วนลดคิดส่วนลด Gold 10% ไม่เกิน 500ไม่รู้จักหน้าจอ DB หรือ LINE
หน้าชำระเงินบนเว็บวาดยอดที่ต้องจ่ายขวา กฎซ่อนอยู่ในไฟล์นี้
ขายผ่าน LINEช่องทางขายใหม่ซ้ายเรียกกฎเดิม ขวาเขียนกฎใหม่เอง
1
The Dependency Rule · กฎส่วนลดอยู่ที่เดียวคุณจะสั่ง AI ว่าอะไร
1
The Dependency Rule · กฎส่วนลดอยู่ที่เดียว
ตอนที่ 1 · สถานการณ์

ร้านขายคอร์สออนไลน์ของคุณให้ส่วนลดสมาชิก Gold 10% สูงสุด 500 บาท ตอนนี้ขายผ่านหน้าเว็บอย่างเดียว แล้วคุณอยากขายผ่าน LINE bot ด้วย คุณสั่ง AI เขียนบอท

เพิ่มขายผ่าน LINE bot แล้วส่วนลด Gold ลืมเพดาน 500 บาท

กฎส่วนลดอยู่ที่เดียว · ไฟล์กฎ
กฎส่วนลดฝังอยู่ในหน้าเว็บ

ลูกศร = ไฟล์ไหนพึ่งไฟล์ไหน · เขียว ถูกทิศ · แดง ชี้ผิดทาง · แตะกล่องเพื่อหาไฟล์บนกระดาน

กฎส่วนลดอยู่ที่เดียว · ไฟล์กฎ
กฎส่วนลดฝังอยู่ในหน้าเว็บ
กฎส่วนลดอยู่ที่เดียว · ไฟล์กฎ
ชั้นใน · กฎ
กฎส่วนลดกฎมีที่อยู่ที่เดียว
คิดส่วนลด Gold 10% ไม่เกิน 500
ชั้นนอก · หน้าจอ บอท DB
หน้าชำระเงินบนเว็บแค่เรียกกฎ
ใช้ ← กฎส่วนลด
วาดยอดที่ต้องจ่าย
กฎส่วนลดฝังอยู่ในหน้าเว็บ
ชั้นใน · กฎ
ไม่มีชั้นกฎ · กฎไม่มีที่อยู่
ชั้นนอก · หน้าจอ บอท DB
หน้าชำระเงินบนเว็บกฎอยู่ในหน้าจอ
คิดส่วนลดเองในหน้าจอวาดยอดที่ต้องจ่าย
ขั้นสุดท้าย · ลากขั้นตอนมาแยกเป็นไฟล์ใหม่ตรงนี้+ ไฟล์ใหม่ลากการคิดส่วนลดทั้งสองตัว ไปรวมเป็นกฎเดียวในไฟล์กฎส่วนลด

กล่อง = ไฟล์หนึ่งไฟล์ ที่ AI ต้องเปิดเมื่อแก้เรื่องในนั้นขั้นตอนชิ้น = สิ่งที่โค้ดทำ หนึ่งขั้น= ชิ้นที่ลากไปไฟล์ใหม่ได้ ในขั้นสุดท้าย

เขียว: ที่แก้หรือเพิ่มประ: ต้องทดสอบซ้ำแดง: สำเนากฎที่ต่างกัน

บนมือถือ: แตะที่กระดานเพื่อไปขั้นถัดไป ขั้นสุดท้ายแตะชิ้นที่ลากได้ แล้วแตะกล่องที่มันควรอยู่

0 / 3
ก่อนเริ่มก่อนแตะอะไร

ซ้าย มีไฟล์กฎส่วนลด และหน้าชำระเงินที่เรียกมัน ขวา ไม่มีชั้นกฎเลย กฎส่วนลดอยู่ในหน้าชำระเงินบนเว็บ ปนกับโค้ดที่วาดหน้าจอ

ขั้นที่ 1Gold ซื้อ 15,000 บนเว็บ

ซ้าย ลด 500 ตามกฎ ขวา ลด 500 เท่ากัน ตอนนี้กฎมีสำเนาเดียว เลยยังไม่มีอะไรต่างกัน

ขั้นที่ 2เพิ่มช่องทาง LINE

ซ้าย AI เพิ่มไฟล์บอท LINE ที่เรียกกฎส่วนลดเดิม ขวา AI เพิ่มไฟล์บอทเหมือนกัน แต่หากฎไม่เจอ เลยคิดส่วนลดใหม่จากความจำ ลืมเพดาน 500

ขั้นสุดท้ายGold ซื้อ 15,000 ผ่าน LINE

ซ้าย ลด 500 เท่าเว็บ เพราะเรียกกฎเดียวกัน ขวา บอทลด 1,500 แต่เว็บลด 500 ขาดทุน 1,000 บาทต่อออเดอร์ และไม่มี test ไหนเทียบสองช่องทาง

หลักการ ในภาษาของโค้ด

กฎธุรกิจต้องอยู่ชั้นใน และไม่รู้จักอะไรจากชั้นนอก หน้าจอ บอท และ DB เป็นฝ่ายเรียกกฎ ไม่ใช่ที่เก็บกฎ

ถามก่อนรับ diffกฎในไฟล์นี้มีอยู่แล้วที่อื่นไหม ถ้ามี ทำไม AI ไม่เรียกของเดิม

The Dependency Rule (Martin, Clean Architecture 2017): source code dependencies must point only inward, toward higher-level policies
2
ตอนที่ 2 · แปลงของนอกก่อนส่งเข้าเปลี่ยนชื่อคอลัมน์ใน DB แล้ว Gold ทุกคนจ่ายเต็มราคา โดยไม่มี error
เรื่องย่อ

ร้านเดิม ระบบจองที่นั่งคอร์ส สัปดาห์นี้มีสามงาน อัปเกรด Next.js รุ่นใหม่ที่เปลี่ยนวิธีอ่านหัวคำขอ เพิ่มการจองผ่าน LINE และเปลี่ยนชื่อคอลัมน์ระดับสมาชิกใน DB

บนฝั่งขวา ชั้นในพูดภาษาของเว็บและ DB ทุกการเปลี่ยนข้างนอกเลยไหลเข้าไปถึงกฎทั้ง 6 เรื่อง รอบเปลี่ยนชื่อคอลัมน์ไม่มี error สักบรรทัด Gold ทุกคนแค่จ่ายเต็มราคา

ซ้าย กฎการจองที่นั่งรับคำขอธรรมดา ส่วนตัวรับคำขอจากเว็บกับตัวอ่าน DB คอยแปลงข้อมูลจากข้างนอกให้ก่อน ขวา กฎทั้ง 6 เรื่องรับคำขอของเว็บมาทั้งก้อน และอ่านชื่อคอลัมน์ใน DB เอง เราจะอัปเกรด Next.js เพิ่มช่องทาง LINE แล้วเปลี่ยนชื่อคอลัมน์

กล่องบนกระดานนี้ · 4
ส่วนทำอะไรทำไม
กฎการจองที่นั่งรับเลขสมาชิก คอร์ส จำนวนที่นั่ง แล้วจองไม่รู้จักเว็บ ไม่รู้จัก DB
รับคำขอจองจากเว็บแปลงคำขอจากเว็บเป็นคำขอธรรมดาNext.js เปลี่ยน แก้ที่ไฟล์นี้ไฟล์เดียว
อ่านข้อมูลสมาชิกจาก DBแปลงแถวใน DB เป็นสมาชิกคอลัมน์เปลี่ยนชื่อ แก้ที่ตัวแปลงที่เดียว
รับคำขอจองจาก LINEแปลงข้อความ LINE เป็นคำขอธรรมดาไม่ต้องปั้นคำขอเว็บปลอม
2
Crossing Boundaries · แปลงของนอกก่อนส่งเข้าคุณจะสั่ง AI ว่าอะไร
2
Crossing Boundaries · แปลงของนอกก่อนส่งเข้า
ตอนที่ 2 · สถานการณ์

ร้านเดิม ระบบจองที่นั่งคอร์ส สัปดาห์นี้มีสามงาน อัปเกรด Next.js รุ่นใหม่ที่เปลี่ยนวิธีอ่านหัวคำขอ เพิ่มการจองผ่าน LINE และเปลี่ยนชื่อคอลัมน์ระดับสมาชิกใน DB

เปลี่ยนชื่อคอลัมน์ใน DB แล้ว Gold ทุกคนจ่ายเต็มราคา โดยไม่มี error

แปลงข้อมูลก่อนส่งเข้ากฎ
กฎรับของจากเว็บกับ DB ตรง ๆ

ลูกศร = ไฟล์ไหนพึ่งไฟล์ไหน · เขียว ถูกทิศ · แดง ชี้ผิดทาง · แตะกล่องเพื่อหาไฟล์บนกระดาน

แปลงข้อมูลก่อนส่งเข้ากฎ
กฎรับของจากเว็บกับ DB ตรง ๆ
แปลงข้อมูลก่อนส่งเข้ากฎ
ชั้นใน · กฎ
กฎการจองที่นั่งรับคำขอธรรมดา
จองที่นั่ง จากคำขอธรรมดา
ชั้นนอก · หน้าจอ บอท DB
รับคำขอจองจากเว็บแปลงคำขอเว็บก่อนส่งเข้า
ใช้ ← Next.js
แปลงคำขอจากเว็บ เป็นคำขอธรรมดา
อ่านข้อมูลสมาชิกจาก DBแปลงแถว DB ก่อนส่งเข้า
ใช้ ← Prisma
แปลงแถวใน DB เป็นสมาชิก
กฎรับของจากเว็บกับ DB ตรง ๆ
ชั้นใน · กฎ
กฎการจองที่นั่งรับของจากเว็บกับ DB ตรง ๆ
ใช้ ← Next.js, Prisma
จองที่นั่งอ่านคำขอของเว็บเองทั้งก้อนเปิด DB เองอ่านชื่อคอลัมน์ระดับสมาชิกเอง
กฎอีก 5 เรื่องรับแบบเดียวกัน
ใช้ ← Next.js, Prisma
กฎอีก 5 เรื่อง รับแบบเดียวกัน
ชั้นนอก · หน้าจอ บอท DB
รับคำขอจองจากเว็บส่งคำขอเข้าไปทั้งก้อน
ส่งคำขอของเว็บเข้าไปทั้งก้อน
ขั้นสุดท้าย · ลากขั้นตอนมาแยกเป็นไฟล์ใหม่ตรงนี้+ ไฟล์ใหม่ลาก อ่านคำขอของเว็บ ไปไว้ที่ตัวรับคำขอจากเว็บ ส่วน เปิด DB เอง กับ อ่านชื่อคอลัมน์เอง ไปไว้ที่ตัวอ่านข้อมูลสมาชิก

กล่อง = ไฟล์หนึ่งไฟล์ ที่ AI ต้องเปิดเมื่อแก้เรื่องในนั้นขั้นตอนชิ้น = สิ่งที่โค้ดทำ หนึ่งขั้น= ชิ้นที่ลากไปไฟล์ใหม่ได้ ในขั้นสุดท้าย

เขียว: ที่แก้หรือเพิ่มประ: ต้องแก้ตาม เพราะชั้นในรู้จักชั้นนอกแดง: พังเงียบ ๆ ไม่มี error

บนมือถือ: แตะที่กระดานเพื่อไปขั้นถัดไป ขั้นสุดท้ายแตะชิ้นที่ลากได้ แล้วแตะกล่องที่มันควรอยู่

0 / 3
ก่อนเริ่มก่อนแตะอะไร

ซ้าย กฎการจองที่นั่งรับคำขอธรรมดา และมีตัวแปลงสองไฟล์อยู่ชั้นนอก ขวา กฎการจองกับกฎอีก 5 เรื่อง รับคำขอของเว็บมาทั้งก้อน เปิด DB เอง แล้วอ่านชื่อคอลัมน์เอง

ขั้นที่ 1อัปเกรด Next.js รุ่นใหม่

ซ้าย AI แก้ตัวรับคำขอจากเว็บบรรทัดเดียว เพราะวิธีอ่านหัวคำขอเปลี่ยน ชั้นกฎไม่รู้เรื่อง ขวา AI แก้กฎทั้ง 6 เรื่อง แล้วต้องทดสอบซ้ำทุกตัว

ขั้นที่ 2เพิ่มการจองผ่าน LINE

ซ้าย AI เพิ่มตัวรับคำขอจาก LINE ที่แปลงข้อความเป็นคำขอธรรมดาเอง ขวา LINE ไม่มีคำขอแบบเว็บให้ส่ง AI เลยปั้นคำขอเว็บปลอมขึ้นมา ไม่มีเลขสมาชิกอยู่ในนั้น จองได้แต่ไม่รู้ว่าใคร

ขั้นสุดท้ายเปลี่ยนชื่อคอลัมน์ระดับสมาชิก

ซ้าย AI แก้ตัวอ่านข้อมูลสมาชิกจาก DB ที่เดียว ขวา ชื่อคอลัมน์เก่าอ่านไม่เจอในกฎทั้ง 6 ไฟล์ Gold ทุกคนจ่ายเต็ม และไม่มี error สักบรรทัด

หลักการ ในภาษาของโค้ด

ของที่ข้ามเข้าไปหาชั้นใน ต้องเป็นข้อมูลธรรมดาในภาษาของเรา ชั้นนอกเป็นคนแปลงคำขอและแถวใน DB ให้ก่อน

ถามก่อนรับ diffกฎเรื่องนี้รับคำขอของเว็บ หรือแถวจาก DB เข้ามาตรง ๆ หรือเปล่า

Crossing boundaries (Martin 2017, ch. 22 “The Clean Architecture”): the data that crosses the boundaries is simple data structures; don't pass Entities or database rows across
3
ตอนที่ 3 · เช็กกฎได้โดยไม่เปิดเบราว์เซอร์ขยายเพดานส่วนลดเป็น 800 แต่ต้องรอ test ผ่านเบราว์เซอร์ 95 วินาทีถึงจะรู้ว่าถูก
เรื่องย่อ

ร้านของคุณจะขยายเพดานส่วนลด Gold จาก 500 เป็น 800 บาท AI แก้กฎแล้วต้องเช็กว่ายังถูก บนฝั่งขวา การเช็กหมายถึงเปิดเบราว์เซอร์ ล็อกอิน ใส่ของลงตะกร้า แล้วรอ Stripe โหมดทดสอบ

test ที่ช้าและแพงจะถูกข้าม สัปดาห์นี้ test ผ่านเบราว์เซอร์หมดเวลาสามรอบ AI เลยข้าม แล้วปล่อยขึ้นระบบ ถ้าคุณรีวิว diff สิ่งที่ต้องเห็นคือเพดานถูกกลับด้าน จากไม่เกิน 800 กลายเป็นอย่างน้อย 800 ต่างกันแค่สามตัวอักษร

ซ้ายแยกกฎส่วนลดไว้ไฟล์เดียว มี test ของมันเอง 12 เคส เช็กได้ใน 8 ms หน้าจอเหลือแค่วาดตัวเลข ขวากฎอยู่ในหน้าชำระเงิน ทางเดียวที่เช็กได้คือ test ผ่านเบราว์เซอร์ที่ใช้ 95 วินาที เราจะรัน test แก้เพดานจาก 500 เป็น 800 แล้วดูว่าอะไรจับความผิดของ AI ได้

กล่องบนกระดานนี้ · 4
ส่วนทำอะไรทำไม
กฎส่วนลดรับตัวเลข คืนตัวเลขทดสอบได้โดยไม่ต้องมีเบราว์เซอร์หรือ DB
test ของกฎส่วนลด12 เคส รันใน 8 msเร็วพอที่ AI จะรันทุกรอบ
หน้าชำระเงินบนเว็บแค่วาดตัวเลขส่วนที่ทดสอบยาก ให้มันโง่ที่สุด
test ผ่านเบราว์เซอร์ล็อกอิน ใส่ตะกร้า แล้วเช็กส่วนลด95 วินาที ไม่มีใครอยากรันซ้ำ
3
Humble Object · เช็กกฎได้โดยไม่เปิดเบราว์เซอร์คุณจะสั่ง AI ว่าอะไร
3
Humble Object · เช็กกฎได้โดยไม่เปิดเบราว์เซอร์
ตอนที่ 3 · สถานการณ์

ร้านของคุณจะขยายเพดานส่วนลด Gold จาก 500 เป็น 800 บาท AI แก้กฎแล้วต้องเช็กว่ายังถูก บนฝั่งขวา การเช็กหมายถึงเปิดเบราว์เซอร์ ล็อกอิน ใส่ของลงตะกร้า แล้วรอ Stripe โหมดทดสอบ

ขยายเพดานส่วนลดเป็น 800 แต่ต้องรอ test ผ่านเบราว์เซอร์ 95 วินาทีถึงจะรู้ว่าถูก

เช็กกฎได้ใน 8 ms · หน้าจอแค่วาด
เช็กกฎได้ทางเดียว · ผ่านเบราว์เซอร์ 95 วินาที

ลูกศร = ไฟล์ไหนพึ่งไฟล์ไหน · เขียว ถูกทิศ · แดง ชี้ผิดทาง · แตะกล่องเพื่อหาไฟล์บนกระดาน

เช็กกฎได้ใน 8 ms · หน้าจอแค่วาด
เช็กกฎได้ทางเดียว · ผ่านเบราว์เซอร์ 95 วินาที
เช็กกฎได้ใน 8 ms · หน้าจอแค่วาด
ชั้นใน · กฎ
กฎส่วนลดรับตัวเลข คืนตัวเลข
คิดส่วนลด รับตัวเลข คืนตัวเลข
test ของกฎส่วนลด8 msไม่มีเบราว์เซอร์ ไม่มี DB
Gold ลด 10%ไม่เกิน 500…อีก 10 เคส
ชั้นนอก · หน้าจอ บอท DB
หน้าชำระเงินบนเว็บแค่วาด
ใช้ ← กฎส่วนลด
วาดยอดที่ต้องจ่าย
เช็กกฎได้ทางเดียว · ผ่านเบราว์เซอร์ 95 วินาที
ชั้นใน · กฎ
ไม่มีชั้นกฎ · กฎเช็กได้แค่ผ่านเบราว์เซอร์
ชั้นนอก · หน้าจอ บอท DB
หน้าชำระเงินบนเว็บกฎกับหน้าจออยู่ด้วยกัน
คิดส่วนลดเองในหน้าจอวาดยอดที่ต้องจ่าย
test ผ่านเบราว์เซอร์95 วิต้องล็อกอิน ต้องต่อ Stripe โหมดทดสอบ
ล็อกอิน 20 วิใส่ของลงตะกร้า 15 วิเช็กตัวเลขส่วนลด
ขั้นสุดท้าย · ลากขั้นตอนมาแยกเป็นไฟล์ใหม่ตรงนี้+ ไฟล์ใหม่ลาก คิดส่วนลดเองในหน้าจอ ไปไว้ในไฟล์กฎส่วนลด ให้หน้าจอเหลือแค่วาด

กล่อง = ไฟล์หนึ่งไฟล์ ที่ AI ต้องเปิดเมื่อแก้เรื่องในนั้นขั้นตอนชิ้น = สิ่งที่โค้ดทำ หนึ่งขั้น= ชิ้นที่ลากไปไฟล์ใหม่ได้ ในขั้นสุดท้าย

เขียว: ที่แก้ และ test ที่ผ่านประแดง: test ไม่ผ่าน · ไม่ mergeแดง: หลุดขึ้นระบบจริง

บนมือถือ: แตะที่กระดานเพื่อไปขั้นถัดไป ขั้นสุดท้ายแตะชิ้นที่ลากได้ แล้วแตะกล่องที่มันควรอยู่

0 / 3
ก่อนเริ่มก่อนแตะอะไร

ซ้าย กฎส่วนลดอยู่ไฟล์เดียว มี test ของตัวเอง 12 เคส หน้าชำระเงินแค่วาดตัวเลข ขวา กฎอยู่ในหน้าชำระเงิน และเช็กได้ผ่านเบราว์เซอร์ทางเดียว

ขั้นที่ 1รัน test กับกฎเดิม ดูว่าใช้เวลาเท่าไร

ซ้าย ผ่าน 12/12 ใน 8 ms AI รันทุกรอบเพราะมันเร็ว ขวา test ผ่านเบราว์เซอร์ผ่านใน 95 วินาที รันครั้งเดียว แล้วไม่มีใครรันอีก

ขั้นที่ 2แก้เพดานจาก 500 เป็น 800

ซ้าย AI แก้กฎกับเคสเพดานใน test แล้วทดสอบซ้ำ ผ่าน 12/12 ใน 8 ms ขวา AI แก้ในหน้าชำระเงิน แล้ว test ผ่านเบราว์เซอร์ต้องใช้ 95 วินาที AI รันหรือยัง ไม่มีใครรู้

ขั้นสุดท้ายAI แก้กฎอีกรอบ แล้วกลับด้านเพดาน

ซ้าย AI พิมพ์เพดานกลับด้าน test ไม่ผ่าน 1 เคสภายใน 8 ms เลยไม่ได้ merge ขวา test ผ่านเบราว์เซอร์หมดเวลาแล้วถูกข้ามเป็นครั้งที่ 3 ของสัปดาห์ กฎที่ผิดขึ้นระบบไป Gold ลด 1,500 ทุกออเดอร์อยู่สามวัน

หลักการ ในภาษาของโค้ด

ส่วนที่ทดสอบยาก ให้มันโง่ที่สุด แล้วย้ายกฎไปอยู่ในส่วนที่ test ได้เร็ว test ที่เร็วพอ AI จะรันทุกรอบ

ถามก่อนรับ diffกฎที่ diff นี้แก้ มี test ที่รันเสร็จในไม่กี่ ms หรือต้องรอเปิดเบราว์เซอร์

Humble Object (Martin 2017, ch. 23; Meszaros, xUnit Test Patterns 2007): split behaviour into a hard-to-test humble part and a testable part
4
ตอนที่ 4 · สร้างของทุกอย่างที่เดียวย้ายจาก Prisma ไป Drizzle ต้องไล่แก้ 23 ที่ ลืมที่เดียวก็พัง
เรื่องย่อ

ร้านของคุณกำลังโต สัปดาห์นี้มีสามงาน เขียน test ให้การจองที่นั่ง ย้าย DB จาก Prisma ไป Drizzle และเพิ่มอีเมลต้อนรับ ทุกงานเริ่มที่คำถามเดียว คือของพวกนี้ถูกสร้างที่ไหน

บนฝั่งขวา คำตอบคือ 23 ที่ AI ต้องหาให้ครบทุกที่ diff ที่ยาว 22 ไฟล์ดูครบในสายตาคนรีวิว ไฟล์ที่ลืมคือไฟล์ที่ไม่อยู่ใน diff เลย

ซ้าย มีจุดเริ่มแอปที่เดียวที่เปิด DB และต่อ vendor แล้วส่งของพวกนั้นให้ทั้งแอป ไฟล์ที่เหลือรับมาใช้ ขวา ทุกไฟล์เปิด DB เอง รวม 23 ไฟล์ เราจะเขียน test ย้ายจาก Prisma ไป Drizzle แล้วเพิ่มอีเมลต้อนรับ

กล่องบนกระดานนี้ · 4
ส่วนทำอะไรทำไม
จุดเริ่มแอป ต่อสายทุกอย่างเปิด DB ต่อ vendor แล้วส่งให้ทั้งแอปไฟล์เดียวที่รู้ว่าอะไรต่อกับอะไร
จุดเริ่มตอน testส่งของปลอมให้ทั้งแอปแทนtest ไม่ต้อง mock อะไร
กฎส่วนลดรับของที่ต่อแล้วมาใช้ขวา กฎส่วนลดเปิด DB เอง
อีเมลต้อนรับไฟล์ใหม่ทางขวาอ่านค่าลับตอนโหลดไฟล์ แอปเลยเปิดไม่ขึ้น
4
The Main Component · สร้างของทุกอย่างที่เดียวคุณจะสั่ง AI ว่าอะไร
4
The Main Component · สร้างของทุกอย่างที่เดียว
ตอนที่ 4 · สถานการณ์

ร้านของคุณกำลังโต สัปดาห์นี้มีสามงาน เขียน test ให้การจองที่นั่ง ย้าย DB จาก Prisma ไป Drizzle และเพิ่มอีเมลต้อนรับ ทุกงานเริ่มที่คำถามเดียว คือของพวกนี้ถูกสร้างที่ไหน

ย้ายจาก Prisma ไป Drizzle ต้องไล่แก้ 23 ที่ ลืมที่เดียวก็พัง

สร้างของที่จุดเริ่มแอปที่เดียว
23 ไฟล์ ต่างคนต่างเปิด DB เอง

ลูกศร = ไฟล์ไหนพึ่งไฟล์ไหน · เขียว ถูกทิศ · แดง ชี้ผิดทาง · แตะกล่องเพื่อหาไฟล์บนกระดาน

สร้างของที่จุดเริ่มแอปที่เดียว
23 ไฟล์ ต่างคนต่างเปิด DB เอง
สร้างของที่จุดเริ่มแอปที่เดียว
จุดเริ่ม · ต่อสาย
จุดเริ่มแอป ต่อสายทุกอย่างที่เดียวที่รู้ว่าอะไรต่อกับอะไร
เปิด DB หนึ่งครั้งต่อ Omise หนึ่งครั้งส่งของที่ต่อแล้วให้ทั้งแอป
จุดเริ่มตอน testส่งของปลอมเข้าไปแทน
ส่งของปลอมให้ทั้งแอปแทน
ไฟล์ที่เหลือ · รับของมาใช้
กฎการจองที่นั่งรับของที่ต่อแล้วมาใช้
จองที่นั่ง ด้วยของที่ได้รับมา
กฎส่วนลดรับของที่ต่อแล้วมาใช้
คิดส่วนลด
บอท LINEรับของที่ต่อแล้วมาใช้
ตอบใน LINE ด้วยของที่ได้รับมา
23 ไฟล์ ต่างคนต่างเปิด DB เอง
จุดเริ่ม · ต่อสาย
ไม่มีจุดเริ่ม · ทุกไฟล์ต่อสายเอง
23 ไฟล์ · ต่อสายเองทุกไฟล์
กฎการจองที่นั่งเปิด DB เอง
ใช้ ← Prisma
เปิด DB เองจองที่นั่ง
กฎส่วนลดกฎส่วนลดเปิด DB เอง
ใช้ ← Prisma
เปิด DB เองคิดส่วนลด
บอท LINEเปิด DB เอง
ใช้ ← Prisma
เปิด DB เองตอบใน LINE
…อีก 20 ไฟล์เปิด DB เอง
ใช้ ← Prisma
เปิด DB เอง อีก 20 ที่
ขั้นสุดท้าย · ลากขั้นตอนมาแยกเป็นไฟล์ใหม่ตรงนี้+ ไฟล์ใหม่ลาก เปิด DB เอง จากสามไฟล์นี้ ไปรวมไว้ที่จุดเริ่มแอป

กล่อง = ไฟล์หนึ่งไฟล์ ที่ AI ต้องเปิดเมื่อแก้เรื่องในนั้นขั้นตอนชิ้น = สิ่งที่โค้ดทำ หนึ่งขั้น= ชิ้นที่ลากไปไฟล์ใหม่ได้ ในขั้นสุดท้าย

เขียว: ที่แก้หรือเพิ่มประ: ต้องแก้ตาม ทุกไฟล์ที่ต่อสายเองแดง: ไฟล์ที่ลืม หรือล้มตั้งแต่โหลดไฟล์

บนมือถือ: แตะที่กระดานเพื่อไปขั้นถัดไป ขั้นสุดท้ายแตะชิ้นที่ลากได้ แล้วแตะกล่องที่มันควรอยู่

0 / 3
ก่อนเริ่มก่อนแตะอะไร

ซ้าย จุดเริ่มแอปเปิด DB ต่อ Omise แล้วส่งให้ทั้งแอป ส่วนกฎการจอง กฎส่วนลด และบอท LINE รับของพวกนั้นมาใช้ ขวา ทั้ง 23 ไฟล์เปิด DB เอง รวมกฎส่วนลดด้วย

ขั้นที่ 1เขียน test ให้การจองที่นั่ง

ซ้าย AI แก้จุดเริ่มตอน test บรรทัดเดียว ส่งของปลอมเข้าไปแทน ไม่ต้อง mock อะไร ขวา AI ต้อง mock DB ใน test ทั้ง 23 ไฟล์ ได้ของปลอม 23 ชุดที่ไม่มีชุดไหนเหมือนกัน

ขั้นที่ 2ย้าย Prisma ไป Drizzle

ซ้าย AI แก้จุดเริ่มแอปกับตัวต่อ DB ชั้นกฎไม่ถูกแตะ ขวา AI แก้ไป 22 ไฟล์ แต่ลืมบอท LINE การเชื่อมต่อ DB เก่าค้าง บอทตายอยู่สองวัน

ขั้นสุดท้ายเพิ่มอีเมลต้อนรับ

ซ้าย AI เพิ่มการต่อบริการอีเมลที่จุดเริ่มแอปบรรทัดเดียว ขวา AI เพิ่มไฟล์อีเมลต้อนรับที่อ่านกุญแจตอนโหลดไฟล์ เครื่องทดสอบไม่มีกุญแจนั้น แอปเลยล้มตั้งแต่เปิด

หลักการ ในภาษาของโค้ด

ให้มีที่เดียวที่สร้างของและต่อทุกอย่างเข้าด้วยกัน ไฟล์อื่นรับของที่ต่อแล้วมาใช้ ไม่สร้างเอง

ถามก่อนรับ diffdiff นี้เปิด DB หรืออ่านค่าลับในไฟล์ที่ไม่ใช่จุดเริ่มแอปหรือเปล่า

The Main Component (Martin 2017, ch. 26): Main is the ultimate detail, the dirtiest component; it creates everything and hands it to the clean parts
ครบสี่รูปแล้ว? ทายว่ากฎอยู่ชั้นไหนแบบทดสอบแปดข้อ ทุกข้อคือ diff ที่ AI กำลังจะส่งมาให้รีวิว
ทำแบบทดสอบ →

ทั้งสี่ข้อคือรูปเดียวกัน มองจากไฟล์

พูดแบบคนสั่งงาน: กฎส่วนลดมีที่อยู่ที่เดียว ทุกช่องทางมาเรียก ไม่ใช่ต่างคนต่างเขียน (1) หน้าเว็บ บอท และ DB ต้องแปลงของตัวเองเป็นข้อมูลธรรมดาก่อนส่งเข้าหากฎ (2) กฎต้องเช็กได้ในไม่กี่ ms โดยไม่เปิดเบราว์เซอร์ ไม่งั้นไม่มีใครเช็ก (3) และมีไฟล์เดียวที่สร้างฐานข้อมูลกับ vendor แล้วส่งให้คนอื่นใช้ (4) Martin วาดเป็นวงกลมซ้อนกัน ลูกศรชี้เข้าหากฎเสมอ บนกระดาน: ไฟล์ที่เก็บกฎต้องไม่รู้จักชื่อของเฟรมเวิร์ก DB หรือ vendor เลย

สี่กระดานคือร้านขายคอร์สออนไลน์ร้านเดียว: เพิ่มขายผ่าน LINE · เปลี่ยนชื่อคอลัมน์ใน DB · ขยายเพดานส่วนลด · ย้ายฐานข้อมูล · โค้ดเป็น TypeScriptคีย์บนกระดาน: Enter / คลิก = ขั้นถัดไป · ⌫ = รีเซ็ต