ฟังก์ชั่นสำหรับเช็คเงื่อนไข

เวลาที่เราเขียนโปรแกรมสำหรับภาคธุรกิจ เราจะเจอลักษณะการเช็คเงื่อนไข ประมาณว่า ... บุคคลใด ๆ สามาระทำอะไรบางอย่างได้หรือไม่ได้อยู่บ่อย ๆ ใช่ไหมครับ วันนี้จะแนะนำอะไรพื้น ๆ สนุก ๆ ก็แล้วกันนะครับ

สมมติว่าเรากำลังจะเขียนฟังก์ชั่นเพื่อดูว่า แคนดิดเดดคนนี้เข้าเงื่อนไขกับตำแหน่งที่เชาสมัครหรือเปล่าก็แล้วกัน (พอดีว่าที่ทำงานผมเพิ่งเปิด 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

Wutipong Wongsakuldej

Programmer, interested in frontend applications, music and multimedia.

Latest posts by Wutipong Wongsakuldej (see all)

3 thoughts on “ฟังก์ชั่นสำหรับเช็คเงื่อนไข

  1. คนผ่านทาง

    ปกติผมชอบเขียนแบบที่สองมากครับ รวมไปถึง method ที่ไม่มีการคืนค่าเช่น

    void processData(String data) {
    if(data == null){
    return;

    }
    //ทำงานต่อ
    }
    แต่ไปทำงานที่หนึ่งแล้ว Tech lead บอกว่าการเขียนโค้ดในลักษณะที่ผมทำ ไม่ควรทำเพราะคนอื่นๆ อ่านไม่เข้าใจ และไม่เป็นมาตรฐาน ทำเอาผมเสียศูนย์ไปเลย งง มาได้เป็นปี ไม่รู้ทำไมแกถึงพูดแบบนั้น

    Reply
    1. ของผม Product Manager อ่านแล้วโอเคครับ (ฮา) เขาเลยไม่ว่าอะไร

      เป็นไปได้ว่า Tech Lead คุณเป็นคนทำงานอย่างเดียวไม่ค่อยศึกษาอะไรเพิ่มนะ วิธีนี้เป็นวิธีที่มีในตำราหลายเล่มเหมือนกัน (Clean Code ก็มีถ้าจำไม่ผิด ผมเอามาจาก The C++ Programming Language)

      Reply
  2. sleepyfurious

    จริงๆ ผมว่าเรื่องเยื้องเรื่อยๆ ในตัวอย่างนี้ ถ้าจัดดีๆ รวม get* ก็ไม่เกี่ยวกับ การเยื้องเท่าไหร่นะครับแหม่:

    auto major = candidate.getDegreeInMajor();
    auto scoremapProg = candidate.getTestScore();
    auto scoremapEng = candidate.getEnglishTestScore();

    return ( (
    major == "Computer Science") ||
    major == "Computer Engineering" ||
    major == "Information Technology"

    ) && (

    scoremapProg["Java"] > 80 &&
    scoremapProg["OOD"] > 80 &&
    scoremapProg["Design Patterns"] > 80 &&
    scoremapProg["JBOSS"] > 80

    ) && (

    scoremapEng["Speaking"] > 500 &&

    scoremapEng["Writting"] > 500

    ) )? true: false;

    แต่ยังมองไม่ออกว่า performance ต่างกันอย่างไรแหะ

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *