Google แนะนำแนวทาง “Functional Core, Imperative Shell” เพื่อเขียนโค้ดให้สะอาด ทดสอบง่าย และปรับขยายได้
บทความจาก Google Testing Blog เสนอแนวคิดการแยกโค้ดออกเป็นสองส่วน: Functional Core ที่เป็นฟังก์ชันบริสุทธิ์ (pure functions) และ Imperative Shell ที่จัดการ side effects เช่น I/O, database, หรือ network — เพื่อให้โค้ดมีความสามารถในการทดสอบและดูแลรักษาได้ดีขึ้น.
แนวคิดหลักจากบทความ
Functional Core คือส่วนที่ไม่มี side effects
ประกอบด้วยฟังก์ชันที่รับข้อมูลเข้าและคืนผลลัพธ์โดยไม่เปลี่ยนแปลงสถานะภายนอก
สามารถทดสอบได้ง่ายและนำกลับมาใช้ซ้ำได้
Imperative Shell คือส่วนที่จัดการกับโลกภายนอก
เช่น การส่งอีเมล, อ่านข้อมูลจาก database, หรือเขียนไฟล์
ใช้ผลลัพธ์จาก Functional Core เพื่อดำเนินการจริง
ตัวอย่างจากบทความ: การส่งอีเมลแจ้งเตือนผู้ใช้หมดอายุ
โค้ดเดิมผสม logic กับ side effects ทำให้ทดสอบยาก
โค้ดใหม่แยก logic ออกมาเป็นฟังก์ชัน getExpiredUsers() และ generateExpiryEmails()
Shell ใช้ฟังก์ชันเหล่านี้เพื่อส่งอีเมลจริงผ่าน email.bulkSend(...)
ข้อดีของแนวทางนี้
ทดสอบง่าย: ไม่ต้อง mock database หรือ network
ปรับขยายง่าย: เพิ่มฟีเจอร์ใหม่โดยเขียนฟังก์ชันใหม่ใน core
ดูแลรักษาง่าย
ตัวอย่างโค้ดเปรียบเทียบ
ก่อน (ผสม logic กับ side effects):
function sendUserExpiryEmail() {
for (const user of db.getUsers()) {
if (user.subscriptionEndDate > Date.now()) continue;
if (user.isFreeTrial) continue;
email.send(user.email, "Your account has expired " + user.name + ".");
}
}
หลัง (แยก core และ shell):
function getExpiredUsers(users, cutoff) {
return users.filter(user => user.subscriptionEndDate <= cutoff && !user.isFreeTrial);
}
function generateExpiryEmails(users) {
return users.map(user => [user.email, "Your account has expired " + user.name + "."]);
}
email.bulkSend(generateExpiryEmails(getExpiredUsers(db.getUsers(), Date.now())));
การใช้แนวทาง Functional Core, Imperative Shell ช่วยให้โค้ดมีโครงสร้างที่ชัดเจนและยืดหยุ่น — เหมาะสำหรับทีมที่ต้องการลดความซับซ้อนและเพิ่มคุณภาพในการทดสอบและดูแลระบบในระยะยาว
สาระเพิ่มเติมจากแนวทาง functional programming
แนวคิดนี้คล้ายกับ “Hexagonal Architecture” หรือ “Clean Architecture” ที่แยก domain logic ออกจาก infrastructure
ภาษา functional เช่น Haskell, F#, หรือ Elm ใช้แนวทางนี้เป็นหลัก
ใน JavaScript/TypeScript ก็สามารถนำไปใช้ได้ โดยใช้ pure functions ร่วมกับ async shell
ช่วยลดการใช้ mock ใน unit test เพราะ core ไม่ต้องพึ่ง database หรือ network
https://testing.googleblog.com/2025/10/simplify-your-code-functional-core.html
บทความจาก Google Testing Blog เสนอแนวคิดการแยกโค้ดออกเป็นสองส่วน: Functional Core ที่เป็นฟังก์ชันบริสุทธิ์ (pure functions) และ Imperative Shell ที่จัดการ side effects เช่น I/O, database, หรือ network — เพื่อให้โค้ดมีความสามารถในการทดสอบและดูแลรักษาได้ดีขึ้น.
แนวคิดหลักจากบทความ
Functional Core คือส่วนที่ไม่มี side effects
ประกอบด้วยฟังก์ชันที่รับข้อมูลเข้าและคืนผลลัพธ์โดยไม่เปลี่ยนแปลงสถานะภายนอก
สามารถทดสอบได้ง่ายและนำกลับมาใช้ซ้ำได้
Imperative Shell คือส่วนที่จัดการกับโลกภายนอก
เช่น การส่งอีเมล, อ่านข้อมูลจาก database, หรือเขียนไฟล์
ใช้ผลลัพธ์จาก Functional Core เพื่อดำเนินการจริง
ตัวอย่างจากบทความ: การส่งอีเมลแจ้งเตือนผู้ใช้หมดอายุ
โค้ดเดิมผสม logic กับ side effects ทำให้ทดสอบยาก
โค้ดใหม่แยก logic ออกมาเป็นฟังก์ชัน getExpiredUsers() และ generateExpiryEmails()
Shell ใช้ฟังก์ชันเหล่านี้เพื่อส่งอีเมลจริงผ่าน email.bulkSend(...)
ข้อดีของแนวทางนี้
ทดสอบง่าย: ไม่ต้อง mock database หรือ network
ปรับขยายง่าย: เพิ่มฟีเจอร์ใหม่โดยเขียนฟังก์ชันใหม่ใน core
ดูแลรักษาง่าย
ตัวอย่างโค้ดเปรียบเทียบ
ก่อน (ผสม logic กับ side effects):
function sendUserExpiryEmail() {
for (const user of db.getUsers()) {
if (user.subscriptionEndDate > Date.now()) continue;
if (user.isFreeTrial) continue;
email.send(user.email, "Your account has expired " + user.name + ".");
}
}
หลัง (แยก core และ shell):
function getExpiredUsers(users, cutoff) {
return users.filter(user => user.subscriptionEndDate <= cutoff && !user.isFreeTrial);
}
function generateExpiryEmails(users) {
return users.map(user => [user.email, "Your account has expired " + user.name + "."]);
}
email.bulkSend(generateExpiryEmails(getExpiredUsers(db.getUsers(), Date.now())));
การใช้แนวทาง Functional Core, Imperative Shell ช่วยให้โค้ดมีโครงสร้างที่ชัดเจนและยืดหยุ่น — เหมาะสำหรับทีมที่ต้องการลดความซับซ้อนและเพิ่มคุณภาพในการทดสอบและดูแลระบบในระยะยาว
สาระเพิ่มเติมจากแนวทาง functional programming
แนวคิดนี้คล้ายกับ “Hexagonal Architecture” หรือ “Clean Architecture” ที่แยก domain logic ออกจาก infrastructure
ภาษา functional เช่น Haskell, F#, หรือ Elm ใช้แนวทางนี้เป็นหลัก
ใน JavaScript/TypeScript ก็สามารถนำไปใช้ได้ โดยใช้ pure functions ร่วมกับ async shell
ช่วยลดการใช้ mock ใน unit test เพราะ core ไม่ต้องพึ่ง database หรือ network
https://testing.googleblog.com/2025/10/simplify-your-code-functional-core.html
🧼🧠 Google แนะนำแนวทาง “Functional Core, Imperative Shell” เพื่อเขียนโค้ดให้สะอาด ทดสอบง่าย และปรับขยายได้
บทความจาก Google Testing Blog เสนอแนวคิดการแยกโค้ดออกเป็นสองส่วน: Functional Core ที่เป็นฟังก์ชันบริสุทธิ์ (pure functions) และ Imperative Shell ที่จัดการ side effects เช่น I/O, database, หรือ network — เพื่อให้โค้ดมีความสามารถในการทดสอบและดูแลรักษาได้ดีขึ้น.
✅ แนวคิดหลักจากบทความ
✅ Functional Core คือส่วนที่ไม่มี side effects
➡️ ประกอบด้วยฟังก์ชันที่รับข้อมูลเข้าและคืนผลลัพธ์โดยไม่เปลี่ยนแปลงสถานะภายนอก
➡️ สามารถทดสอบได้ง่ายและนำกลับมาใช้ซ้ำได้
✅ Imperative Shell คือส่วนที่จัดการกับโลกภายนอก
➡️ เช่น การส่งอีเมล, อ่านข้อมูลจาก database, หรือเขียนไฟล์
➡️ ใช้ผลลัพธ์จาก Functional Core เพื่อดำเนินการจริง
✅ ตัวอย่างจากบทความ: การส่งอีเมลแจ้งเตือนผู้ใช้หมดอายุ
➡️ โค้ดเดิมผสม logic กับ side effects ทำให้ทดสอบยาก
➡️ โค้ดใหม่แยก logic ออกมาเป็นฟังก์ชัน getExpiredUsers() และ generateExpiryEmails()
➡️ Shell ใช้ฟังก์ชันเหล่านี้เพื่อส่งอีเมลจริงผ่าน email.bulkSend(...)
✅ ข้อดีของแนวทางนี้
➡️ ทดสอบง่าย: ไม่ต้อง mock database หรือ network
➡️ ปรับขยายง่าย: เพิ่มฟีเจอร์ใหม่โดยเขียนฟังก์ชันใหม่ใน core
➡️ ดูแลรักษาง่าย
🛠️ ตัวอย่างโค้ดเปรียบเทียบ
🔖 ก่อน (ผสม logic กับ side effects):
function sendUserExpiryEmail() {
for (const user of db.getUsers()) {
if (user.subscriptionEndDate > Date.now()) continue;
if (user.isFreeTrial) continue;
email.send(user.email, "Your account has expired " + user.name + ".");
}
}
🔖 หลัง (แยก core และ shell):
function getExpiredUsers(users, cutoff) {
return users.filter(user => user.subscriptionEndDate <= cutoff && !user.isFreeTrial);
}
function generateExpiryEmails(users) {
return users.map(user => [user.email, "Your account has expired " + user.name + "."]);
}
email.bulkSend(generateExpiryEmails(getExpiredUsers(db.getUsers(), Date.now())));
การใช้แนวทาง Functional Core, Imperative Shell ช่วยให้โค้ดมีโครงสร้างที่ชัดเจนและยืดหยุ่น — เหมาะสำหรับทีมที่ต้องการลดความซับซ้อนและเพิ่มคุณภาพในการทดสอบและดูแลระบบในระยะยาว
✅ สาระเพิ่มเติมจากแนวทาง functional programming
➡️ แนวคิดนี้คล้ายกับ “Hexagonal Architecture” หรือ “Clean Architecture” ที่แยก domain logic ออกจาก infrastructure
➡️ ภาษา functional เช่น Haskell, F#, หรือ Elm ใช้แนวทางนี้เป็นหลัก
➡️ ใน JavaScript/TypeScript ก็สามารถนำไปใช้ได้ โดยใช้ pure functions ร่วมกับ async shell
➡️ ช่วยลดการใช้ mock ใน unit test เพราะ core ไม่ต้องพึ่ง database หรือ network
https://testing.googleblog.com/2025/10/simplify-your-code-functional-core.html
0 Comments
0 Shares
54 Views
0 Reviews