Hardcode ในการพัฒนา: มันคืออะไร ความเสี่ยง และวิธีหลีกเลี่ยง

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-31 เวลาอ่าน: 7 นาที

“ตอกตะปูน” และ “ทำฮาร์ดโค้ด” เป็นคำศัพท์เวงที่หมายถึงการกำหนดค่าแน่นอนในโค้ดโปรแกรมโดยตรง แทนที่จะนำไปไว้ในการตั้งค่าหรือคอนฟิกุรัชัน Hardcode เป็นหนึ่งในแอนตีพะเทิร์นที่รู้จักดีที่สุดในการพัฒนา เพราะมันลดความยืดหยุ่นและความสามารถใช้ซ้ำของโค้ด ตามข้อมูลจาก Refactoring Guru แฮร์ดโค้ดทำให้การทดสอบ การบำรุง และการปรับแอปพลิเคชันให้เข้ากับสภาพแวดล้อมแตกต่างๆได้ยากขึ้น การใช้ค่าคงอย่างมีสติแทน hardcode เป็นสัญญาณของสถาปัตยกรรมที่โตเต็มโตเต็ม

หัวข้อสำคัญ

  • ทำฮาร์ดโค้ด — เขียนค่าโดยตรงในโค้ดต้นฉบับ
  • Hardcode ถูกถือว่าเป็นแอนตีพะเทิร์นเนื่องจากการสูญเสียความยืดหยุ่นและความยากในการบำรุง
  • ข้อยกเว้น: ค่าคงทางคณิตศาสตร์, ขนาดแอร์เรย์, ค่าเริ่มต้น
  • ทางเลือก: ไฟล์การตั้งค่า, ตัวแปรสภาพแวดล้อม, ทรัพยากร
  • การรีแฟกเตอร์ฮาร์ดโค้ดช่วยปรับปรุงความสามารถในการทดสอบและการขยายโค้ด

“ตอกตะปูน” และ “ทำฮาร์ดโค้ด” หมายความว่าอย่างไร

ทำฮาร์ดโค้ด (ตอกตะปูน) — สอดค่าเฉพาะเจาะจงในโค้ดโปรแกรมโดยตรงเสียนนานที่การเปลี่ยนแปลงต้องแก้ไขโค้ดต้นฉบับและคอมไพล์แอปพลิเคชันใหม่ การเปรียบเทียมแบบ“ตอกตะปูน”สะท้อนถึงสาระสำคัญได้อย่างถูกต้อง: ค่าถูกกำหนดไว้อย่างถาวร และสามารถแยกออกจากโค้ดได้โดยต้องใช้ความพยายาม

ตัวอย่างของ hardcode — URL เซิร์ฟเวอร์ที่เขียนเป็นคำสั่งโดยตรงในตัวฟังก์ชัน หากเซิร์ฟเวอร์ย้ายไปที่อยู่อื่น นักพัฒนาต้องหาคำสั่งในโค้ด เปลี่ยนแปลง สร้างแอปพลิเคชันใหม่ และเผยแพร่รุ่นใหม่ ในแอปพลิเคชันที่มีสถาปัตยกรรมที่ถูกต้อง URL ดังกล่าวจะถูกนำไปไว้ในไฟล์การตั้งค่า ตัวแปรสภาพแวดล้อม หรือบริการการตั้งค่า

คำว่า“ตอกตะปูน”มีลักษณะทางอารมณ์มากกว่า: มันเน้นย้ำว่าค่าถูกใส่ไว้อย่างถาวร โดยไม่สามารถเปลี่ยนแทนได้อย่างรวดเร็ว ในสภาพแวดล้อมที่พูดภาษารัสเซีย ทั้งสองสำน่วนถูกใช้เป็นคำพ้องกันอย่างสมบูรณ์โดยมีนัยแนะทางลบ บางครั้ง hardcode ถูกเรียกอย่างเสียดังว่า“ค่าคงที่ถูกแยกออกไปเป็นค่าคงอีกอันจากค่าคงอีกอัน”

ทำไม hardcode ถึงถูกถือว่าเป็นแอนตีพะเทิร์น

Hardcode เป็นแอนตีพะเทิร์นเพราะมันละเมิดหลักการบำรุงรักษา การทดสอบ และการขยายโค้ด ในโค้ดที่ค่าถูก“ตอกตะปูน” การเปลี่ยนแปลงสภาพแวดล้อม การออกแบบ หรือตรรกะโลจิการใดๆ จำเป็นต้องค้นหาและแทนที่ด้วยตนเองในโค้ดต้นฉบับ สิ่งนี้เพิ่มความเสี่ยงของข้อผิดพลาดและทำให้การพัฒนาช้าลง

พิจารณาผลกระทบอย่างเฉพาะเจาะของ hardcode โดยใช้ตัวอย่างแอปพลิเคชันมือถือทั่วไป หากระยะห่างของปุ่มทั้งหมดถูกกำหนดโดยตัวเลขในโค้ด แทนที่จะผ่านทรัพยากร — การเปลี่ยนแปลงการออกแบบจะต้องค้นหาทุกตำแหน่งที่ปรากฏและแทนที่ หาก URL จุดสิ้นสุดถูกกำหนดตายตัว — การสลับระหว่างสภาพแวดล้อม (dev, stage, prod) เป็นไปไม่ได้หากไม่ได้สร้างใหม่

ผลกระทบคำอธิบายระดับวิจารณ์
ความยากในการบำรุงการเปลี่ยนแปลงต้องค้นหาทั่วทั้งโค้ดสูง
ข้อผิดพลาดเมื่อคัดลอกไม่พบและแทนที่ได้ทุกตำแหน่งสูง
ไม่สามารถทดสอบได้ไม่สามารถใส่ข้อมูลทดสอบได้ปานกลาง
ปัญหาการแปลภาษาข้อความในโค้ดไม่ได้รับการแปลปานกลาง
ความซับซ้อนของการตรวจโค้ดผู้ตรวจต้องจ๊าบริบทุกบริบทต่ำ

ตัวอย่าง hardcode แย่ย้าย

ฟังก์ชันที่ใช้ตัวเลขมหาศจรรย์และคำสั่งตายตัว — ตัวอย่างคลาสสิกของ hardcode หนึ่งเดือนต่อมา ผู้เขียนจะไม่จำได้ว่า 18, 0.07 และ 2.5 หมายถึงอะไร หนึ่งปีต่อมา — ไม่มีใครในทีมกล้าเปลี่ยนตัวเลขเหล่านี้เพราะกลัวว่าจะทำลายลอจิก การนำค่าไปไว้ในค่าคงที่มีชื่อทำให้โค้ดสามารถอธิบายตัวเองได้

kotlin
// แย่: ตัวเลขมหัศจรรย์และสตริง
fun calculatePrice(base: Double): Double {
    val tax = base * 0.07
    val tip = base * 0.15
    val discount = if (base > 100) 10 else 0
    return base + tax + tip - discount
}

ผลกระทบต่อการทดสอบ

URL ฐานข้อมูลที่ทำฮาร์ดโค้ดจะไม่อนุญาตให้เริ่มต้นการทดสอบบนฐานข้อมูลในหน่วยความจำที่อยู่ในหน่วยความจำ นักพัฒนาจะต้องเริ่มเซิร์ฟเวอร์ที่สมบูรณ์หรือแก้ไขโค้ดก่อนทดสอบ การนำคอนฟิกุรัชันออกจากโค้ดช่วยแก้ปัญหา: การทดสอบใช้พารามิเตอร์ทดสอบ production ใช้พารามิเตอร์จริง และโค้ดไม่เปลี่ยนแปลง

เมื่อไอรัการทำฮาร์ดโค้ดเป็นที่ยอมรับ: ข้อยกเว้นจากกฎกฎา

Hardcode เป็นแอนตีพะเทิร์น แต่มีข้อยกเว้นที่ชอบธรรมโดยเฉพาะเมื่อค่าตายตัวไม่เพียงแค่ยอมรับได้ แต่ยังเป็นที่ต้องการอีกด้วย ขอบเขตอยู่ตามแนวความสามารถในการเปลี่ยนแปลงได้: หากค่าไม่เคยหรือแทบไม่เคยเปลี่ยนแปลงในวงจรของแอปพลิเคชัน สามารถทำฮาร์ดโค้ดได้ หากมีโอกาสเปลี่ยนแปลง — นำไปไว้ในคอนฟิกุรัชัน

ค่าคงทางคณิตศาสตร์และฟิสิกส์ — ค่า Pi, ความเร็งแห่งแรงดึงดูด, จำนวนมิลลิวินาทีในหนึ่งวินาที — ปลอดภัยสำหรับ hardcode สิ่งเหล่านี้ถูกกำหนดโดยธรรมชาติหรือมาตรฐานและจะไม่เปลี่ยนแปลง ขนาดแอร์เรย์คงที่กำหนดโดยข้อกำหนดเฉพาะเจาะจง ก็สามารถตายตัวได้ แต่ต้องมีคำอธิบายเกี่ยวกับที่มาของตัวเลข

ตัวอย่างของ hardcode ที่ยอมรับได้

จำนวนมิลลิวินาทีในหนึ่งวินาทีเป็นค่าคงที่มั่นคงซึ่งกำหนดโดยมาตรฐานเวลา ไม่มีประโยชน์ในการนำไปไว้ใน config เพราะมันจะไม่มีวันเปลี่ยนแปลง อย่างไรก็ตาม แม้แต่ค่าคงเช่นนี้ก็ควรประกาศโดยใช้ชื่อที่เข้าใจได้ เพื่อไม่ให้โค้ดมี“ตัวเลขมหาศจรรย์”: แทนที่จะเป็น 1000 ให้เขียน MILLISECONDS_IN_SECOND

kotlin
// Hardcode ที่ยอมรับได้: ค่าคงที่เสถียร
private const val MILLIS_IN_SECOND = 1000
private const val LOGIN_TIMEOUT_SECONDS = 30

fun formatDuration(ms: Long): String {
    val seconds = ms / MILLIS_IN_SECOND
    return "${seconds} sec."
}

ทางเลือกแทน hardcode: คอนฟิก, ENV, DI

มีหลายวิธีที่พิสูจน์แล้วในการหลีเลี่ยง hardcode แต่ละวิธีเหมาะสมกับประเภทของค่านั้น การเลือกทางเลือกขึ้นอยู่กับว่าค่าเปลี่ยนแปลงบ่อยแค่ใด และใครเปลี่ยนแปลง: นักพัฒนา, devops หรือผู้ใช้ปลายทาง

ไฟล์การตั้งค่า

สำหรับ URL เซิร์ฟเวอร์, คีย์ API และ feature flag ให้ใช้ไฟล์การตั้งค่าในรูปแบบ JSON, YAML หรือ TOML บน Android คือ build.gradle กับ buildConfigField หรือ res/values/config.xml บน iOS — Info.plist หรือ xcconfig ไฟล์การตั้งค่าถูกสร้างร่วมกับแอปพลิเคชัน แต่สามารถแตกต่างกันได้สำหรับแผนการสร้างที่แตกต่างกัน

ตัวแปรสภาพแวดล้อม

สำหรับข้อมูลลับ (token, รหัสผ่าน) และพารามิเตอร์สภาพแวดล้อม ให้ใช้ตัวแปรสภาพแวดล้อม ตัวแปรเหล่านี้จะไม่อยู่ในคลังโค้ด และสามารถแตกต่างกันได้บนเซิร์ฟเวอร์ dev, stage และ prod ในการพัฒนามือถือ ตัวแปรสภาพแวดล้อมมักถูกจำลองผ่านแผนการสร้าง Xcode หรือ build flavors ใน Gradle

ทรัพยากรแอปพลิเคชัน

ข้อความ, สี, ขนาด, รูปภาพควรถูกนำไปไว้ในไฟล์ทรัพยากร: strings.xml บน Android, Localizable.strings บน iOS, ไฟล์ ARB ใน Flutter ซึ่งช่วยให้การแปลภาษา, การปรับให้เข้ากับหน้าจอแตกต่างๆ และโหมดมืดง่ายขึ้น การเปลี่ยนข้อความในทรัพยากรไม่จำเป็นต้องเขียนโค้ดใหม่

xml
<!-- Android: res/values/strings.xml -->
<resources>
    <string name="app_name">MyApp</string>
    <string name="api_base_url">https://api.example.com</string>
</resources>

การฉีดพึ่งพา (DI)

สำหรับบริการและผู้ให้บริการ ให้ใช้ Dependency Injection ผ่าน Dagger, Hilt หรือ Koin บน Android, Swinject บน iOS โครงสร้าง DI ช่วยให้สามารถแทนที่การนำไปใช้ได้ทันที — สำหรับการทดสอบ, สำหรับสภาพแวดล้อมแตกต่างกัน, สำหรับผู้ใช้แตกต่างกัน นี่คือระดับสูงสุดของการทำนามธรรม, ที่การ“ตอกตะปูน”ค่าถูกแทนที่ด้วยการฉีดจากภายนอก

วิธีรีแฟกเตอร์โค้ดที่ทำฮาร์ดโค้ด

การรีแฟกเตอร์ฮาร์ดโค้ด เป็นกระบวนการนำค่าที่ตายตัวไปไว้ในคอนฟิกุรัชันหรือทรัพยากร นี่เป็นหนึ่งในการดำเนินการรีแฟกเตอร์ที่ปลอดภัยที่สุด หากดำเนินการอย่างมีระบบ ลำดับที่อธิบายด้านล่างมีความเหมาะสมสำหรับทุกภาษาและแพลตฟอร์ม

ขั้นตอนที่ 1: ค้นหาตัวเลขมหาศจรรย์และคำสั่งทั้งหมด

สามารถค้นหาได้ผ่าน IDE (Search in Project) หรือสคริปต์ ค้นหาคำสั่ง, URL, ตัวอักษรเฉพาะเจาะจง, ขนาด, กำหนดเวลา ให้ความสนใจเป็นพิเศษ — กับค่าที่ซ้ำกัน: หากตัวเลขเดียวกันปรากฏในห้าแห่ง, แสดงว่าเป็นผู้สมัครสำหรับค่าคง ใช้ grep หรือการค้นหาในตัวของ IDEA / Xcode

ขั้นตอนที่ 2: แทนที่ด้วยค่าคงที่มีชื่อ

สำหรับแต่ละค่าที่พบให้สร้างค่าคงที่มีชื่อสะท้อนความหมาย จัดกลุ่มค่าคงตามโมดูลหรือคลาส ชื่อควรอธิบายความหมายของค่า ไม่ใช่วิธีการใช้งาน: API_TIMEOUT, ไม่ใช่ TIMEOUT_30 หลังจากแทนที่ ไม่ควรมีตัวเลขในโค้ดที่ไม่มีคำอธิบาย

swift
// ก่อน: ตัวเลขมหัศจรรย์ 0.4
let cardHeight = screenHeight * 0.4

// หลัง: ค่าคงที่ที่มีชื่อ
private let cardHeightRatio: CGFloat = 0.4
let cardHeight = screenHeight * cardHeightRatio

ขั้นตอนที่ 3: นำไปไว้ในคอนฟิกุรัชันหรือทรัพยากร

หากค่าสามารถแตกต่างกันได้ระหว่างการสร้างหรือสภาพแวดล้อม — นำไปไว้ในไฟล์การตั้งค่าหรือทรัพยากรแอปพลิเคชัน สำหรับคำสั่ง ใช้ไฟล์การแปลภาษา สำหรับ URL — build config หรือ xcconfig สำหรับขนาด — ไฟล์ทรัพยากร (dimens.xml บน Android) ตรวจสอบว่าแอปพลิเคชันสร้างและทำงานได้อย่างถูกต้องหลังจากการนำออก

ขั้นตอนที่ 4: เขียนการทดสอบ

หลังจากการรีแฟกเตอร์ เขียนการทดสอบที่ตรวจสอบว่าคอนฟิกุรัชันถูกโหลดอย่างถูกต้อง และค่าต่างๆตรงกับที่คาดหวัง หากในอนาคตมีใครเปลี่ยนแปลง config การทดสอบจะชี้ไปที่ความไม่สอดคล้อง การทดสอบคอนฟิกุรัชัน — วิธีที่รวดเร็วและเชื่อถือได้ในการป้องกันการถดถอย

ขั้นตอนที่ 5: ลบข้อมูลที่ซ้ำกัน

หลังจากนำไปไว้ใน config ตรวจสอบว่าทุกตำแหน่งที่ใช้ค่าเก่าอ้างอิงแหล่งเดียวกัน ลบโค้ดที่ถูกเสิมคำอธิบายและค่าคงเก่าที่ไม่ได้ใช้แล้ว สรุปการรีแฟกเตอร์ด้วย commit พร้อมข้อความที่อธิบายว่าค่าใดบ้างและถูกนำไปไว้ที่ไหน

คำถามที่พบบ่อย

“Hardcode” ในการเขียนโปรแกรมหมายความว่าอย่างไร?

Hardcode — การเขียนค่าโดยตรงในโค้ดต้นฉบับ แทนที่จะนำไปไว้ในคอนฟิกุรัชันหรือทรัพยากร ซึ่งทำให้โค้ดมีความยืดหยุ่นน้อยลงและเพิ่มความยากในการบำรุง

ทำไม hardcode ถึงถูกถือว่าเป็นแนวปฏิบัติที่ไม่ดี?

Hardcode ทำให้การเปลี่ยนแปลงพฤติกรรมของแอปพลิเคชันยากขึ้น ขัดขวางการทดสอบ สร้างการทำซ้ำ และเพิ่มความเสี่ยงของข้อผิดพลาดในการคัดลอก การเปลี่ยนแปลงค่าที่ทำฮาร์ดโค้ดจำเป็นต้องสร้างแอปพลิเคชันใหม่และเผยแพร่ใหม่

เมื่อไอรัการทำ hardcode เป็นที่ยอมรับ?

ยอมรับได้ สำหรับค่าคงทางคณิตศาสตร์, ค่าที่มั่นคงที่ไม่เปลี่ยนแปลงในวงจรของแอปพลิเคชัน, และสำหรับโปรโตกรแอมชั่วคราว ในการผลิตจริง, แม้แต่ค่าคงก็ควรถูกนำไปไว้ในตัวแปรที่มีชื่อ

จะแทนที่ hardcode ในโค้ดที่มีอยู่แล้วได้อย่างไร?

ค้นหาตัวเลขมหาศจรรย์ทั้งหมดโดยการค้นหา, แทนที่ด้วยค่าคงที่มีชื่อ หรือนำไปไว้ในไฟล์การตั้งค่า เขียนการทดสอบที่ตรวจสอบการโหลดคอนฟิกุรัชัน ลบข้อมูลซ้ำ และทำ commit พร้อมคำอธิบายการเปลี่ยนแปลง

ความแตกต่างระหว่างค่าคงที่และ hardcode คืออะไร?

ค่าคงที่ — ค่าที่มีชื่อในโค้ด, สามารถเปลี่ยนแปลงได้ที่เดียว Hardcode — ค่าที่ไม่มีชื่อกระจายอยู่ในโค้ด แนวปฏิบัติที่ดี: ใช้ค่าคงที่มีชื่อพร้อมชื่อที่มีความหมายเสมอ

สรุป

  • ทำฮาร์ดโค้ด (ตอกตะปูน) — เขียนค่าในโค้ดโดยไม่มีโอกาสเปลี่ยนแปลงได้อย่างรวดเร็ว
  • Hardcode — แอนตีพะเทิร์นที่ทำลายการบำรุง, การทดสอบ และการขยายโค้ด
  • ตัวเลขมหาศจรรย์ และสตริงที่ไม่มีชื่อ — รูปแบบ hardcode ที่พบบ่อยที่สุด
  • ข้อยกเว้น: ค่าคงทางคณิตศาสตร์และค่าเสถียรเริ่มต้น
  • ทางเลือก: ไฟล์การตั้งค่า, ทรัพยากร, ENV, DI คอนเทนเนอร์
  • การรีแฟกเตอร์ hardcode เริ่มต้นด้วยการค้นหาที่ซ้ำและการแทนที่ด้วยค่าคงที่มีชื่อ
  • หลังการรีแฟกเตอร์ เขียนการทดสอบการโหลดคอนฟิก

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม