เวลาที่เราเขียนโปรแกรมสำหรับภาคธุรกิจ เราจะเจอลักษณะการเช็คเงื่อนไข ประมาณว่า … บุคคลใด ๆ สามาระทำอะไรบางอย่างได้หรือไม่ได้อยู่บ่อย ๆ ใช่ไหมครับ วันนี้จะแนะนำอะไรพื้น ๆ สนุก ๆ ก็แล้วกันนะครับ
สมมติว่าเรากำลังจะเขียนฟังก์ชั่นเพื่อดูว่า แคนดิดเดดคนนี้เข้าเงื่อนไขกับตำแหน่งที่เชาสมัครหรือเปล่าก็แล้วกัน (พอดีว่าที่ทำงานผมเพิ่งเปิด Walk-in Interview ไปเมื่อสุดสัปดาห์ที่ผ่านมา) นี่คือเงื่อนไขของตำแหน่ง Java Programmer ครับ ตำแหน่ง junior เลยนะ
- Bachelor’s degree or higher in IT related field.
- 0 – 2 years experience software development industry by using JAVA , Object-oriented design, design patterns, JBOSS.
- Experience in J2EE, JAVA Beans, JSF development,XML/XSL/XSLT/XSD, Web Services,SOA, ESB, BPEL would be an advantage.
- Experience building consumer facing web applications.
- Good command of both spoken and written English.
- Strong time management skills and multi-tasking skills with ability to maintain focus on each item.
- Ability to work on tight deadlines.
- Keen to learn new technologies and new business.
Qualification ค่อนข้างสูงใช่ไหมครับ นี่ตำแหน่ง junior เปิดสำหรับเด็กจบใหม่เลยนะ (ถ้ามีใครสนใจก็ส่ง resume มาครับ 555) ผมจะบอกว่าเราไม่สามารถที่จะเขียนโปรแกรมตามข้อกำหนดนี้ตรง ๆ ได้ครับ (อ้าว) เพราะว่ามันมีข้อที่แย้งกันอยู่นั่นเอง ผมย่อ qualification ข้างบนออกจนเหลือแค่นี้ครับ
- Bachelor’s degree or higher in IT related field.
- Pass the following tests : JAVA, Object-oriented design, design patterns, JBOSS.
- Pass spoking and writting English test.
ข้อที่ตัดออกไปนี่คือข้อที่มีลักษณะกำกวม และข้อที่ดูแล้วก็คงไม่มีใครยอมรับว่าตัวเองทำไม่ได้หรอก (ฮา) เอาแค่สามข้อนี้ก็พอครับ
ทีนี้มาลองดูกันว่าจะเขียนแบบไหนดี เริ่มจาก … แบบที่ผมถือว่าห่วยสุด ๆ ก่อนละกัน ง่ายมากครับ … เพื่อความเท่ห์ผมจะเขียนโดยใช้ภาษา C++ นะครับ (เป็นการข่มว่า C++ เท่ห์กว่า Java ในตัว 555 ผมล้อเล่นครับ)
bool eligibleToApplyForJavaProgrammer(const Candidate& candidate)
{
if((candidate.getDegreeInMajor() == "Computer Science") || candidate.getDegreeInMajor() == "Computer Engineering" || candidate.getDegreeInMajor() == "Information Technology") &&
(candidate.getTestScore()["Java"] > 80 && candidate.getTestScore()["Java"] > 80 && candidate.getTestScore()["OOD"] > 80 && candidate.getTestScore()["Design Patterns"] > 80 && candidate.getTestScore()["JBOSS"] > 80) &&
(candidate.getEnglishTestScore()["Speaking"] > 500 && candidate.getEnglishTestScore()["Writting"] > 500)) return true;
return false;
}
เอ่อ … เหนื่อยครับ 555 โค๊ดลักษณะนี้เป็นโค๊ดที่ผมเคยเจอจริง ๆ ในระบบที่รันบนโปรดักชั่นจริง ๆ เป็นหนึ่งในโค๊ดที่มักง่ายแบบสุด ๆ แต่ก็มีคนเขียนครับ ถ้าเจอโปรแกรมลักษณะแบบนี้ล่ะก็เตรียมใจได้เลยว่าได้แก้บั๊กกันแน่ ๆ โดยเฉพาะตอนที่ต้องแก้ฟังก์ชั่นเพื่อเพิ่มข้อกำหนดใหม่ ๆ
มาดูแบบที่ผมชอบกันดีกว่า จะบอกว่านี่ไม่ใช่แบบที่ดีที่สุด แต่ก็ถ้าจะเขียนให้จบในฟังก์ชั่นเดียวแบบนี้ถือว่ายอมรับได้ครับ (สำหรับผมนะ)
bool eligibleToApplyForJavaProgrammer(const Candidate& candidate)
{
auto major = candidate.getDegreeInMajor();
if( major != "Computer Science") &&
major != "Computer Engineering" &&
major != "Information Technology")
{
return false;
}
auto scoreMap = candidate.getTestScore();
if(scoreMap["Java"] <= 80 ||
scoreMap["OOD"] <= 80 ||
scoreMap["Design Patterns"] <= 80 ||
scoreMap["JBOSS"] <= 80)
{
return false;
}
auto englishScoreMap = candidate.getEnglishTestScore();
if(englishScoreMap["Speaking"] <= 500 ||
englishScoreMap["Writting"] <= 500)
{
return false;
}
return true;
}
วิธีนี้ผมเรียกว่าการทำ negative test ก็คือทดสอบว่าไม่ผ่านหรือเปล่า ถ้าไม่ผ่านก็ถือว่าจบ ตกรอบ ไม่ได้ไปต่อ ถูกโหวตออก และอื่น ๆ เป็นเทคนิคที่ธรรมชาติมาก และที่สำคัญคือวิธีนี้ไม่ทำให้ indent เยื้องไปทางขวาเรื่อง ๆ (ตรงข้ามกับการทำ positive test หรือทดสอบว่าผ่านหรือเปล่า ถ้าผ่านก็ทดสอบต่อไปเรื่อย ๆ ซึ่งจะเยื้องออกขวาไปเรื่อย ๆ จนตกหน้าจอ)
ที่สำคัญ วิธีข้างล่างมี performance ดีกว่าด้วยครับ ถ้าไม่เชื่อก็ลองไล่โปรแกรมบนดูครับว่ามันมีจุดไหนที่มีปัญหา
เป็นเทคนิคง่าย ๆ แต่ว่าบางคนที่ไม่มีประสพการณ์มากพออาจจะคาดไม่ถึงครับ อ่านแล้วก็ลองคิดเล่น ๆ นะครับว่าเห็นด้วยกับผมไหม ลงคอมเม้นกันได้ครับ
ปล. ผมมีแอบวางบั๊กไว้ด้วยครับ 😉 อย่างที่บอก ฟังก์ชั่นบนมีโอกาสที่จะผิดได้ง่ายมาก และมันก็ผิดจริง ๆ 555