3

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

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

1

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

ดีมั้ยไม่รู้ แต่ถ้าเทียบกับบริษัทข้ามชาติด้วยกันผมว่าพอ ๆ กันนะ

แต่วันนี้จะลองเขียนถึงเรื่องที่ว่า ถ้าอยากทำงานเป็นโปรแกรมเมอร์แต่ไม่ได้จบสายคอมจะต้องทำยังไง

ข่าวร้ายข้อแรกคือ สำหรับคนที่ไม่จบ Com Sci หรือ Com En หรือ IT หรือ BBA in Bus Com หรือ สายที่เกี่ยวข้อง (อาจจะคณิตศาสตร์, สถิติ หรืออะไรก็แล้วแต่) การย้ายงานมาสายนี้นั้นเป็นเรื่องยากมาก แทบทุกที่เขียนว่าความต้องการขั้นต่ำคือวุฒิปริญาตรีในสาขาที่เกี่ยวข้อง เอาเข้าจริง ๆ จบปวช.คอมก็ทำได้นะ (ถ้าเขียนโปรแกรมเป็น) ความรู้ระดับสูง ๆ ในมหาวิทยาลัยนั้นหลาย ๆ ที่ก็ไม่ได้ใช้ครับ

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

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

ดังนั้นความรู้พื้นฐานอย่างแรกที่คุณจำเป็นต้องมีคือ "ภาษาอังกฤษ" นั่นเอง หลายคนถามว่าเอ๊ะเป็นโปรแกรมเมอร์ไม่ต้องมีสกิลคอมพิวเตอร์ก็ได้เหรอ ? บางคนโยงไปเรื่องการประกอบคอม การซ่อมคอม และอื่น ๆ อีกมากมาย ผมคงจะตอบได้ว่าแม้แต่โปรแกรมเมอร์เองหลาย ๆ คนก็ใช้งานคอมพิวเตอร์ได้ไม่คล่องครับ คือแต่ละโปรแกรมก็จะมีวิธีใช้แตกต่างกัน ดังนั้นการใช้งานให้คล่องนั้นก็ใช้เวลา บางคนก็อยากดูละครมากกว่านี่นา (เรื่องประกอบคอมนี่ลืมไปเลยครับ บางคนแค่จะจับเคสยังขยาดเลย) คุณแค่ใช้โปรแกรมที่ใช้เขียนโปรแกรมให้คล่องก็พอ (อาจจะเป็น compiler และ/หรือ IDE นั่นแหละ อยากรู้เพิ่มก็ศึกษาเองนะ)

เมื่อคุณมีความรู้ภาษาอังกฤษแล้วคุณก็จะสามารถศึกษาการเขียนโปรแกรมได้กว้างมากขึ้น มากซะจน .... จนไม่รู้จะเริ่มจากอะไรก่อนดีเลยล่ะ ถ้าเป็นในอดีตผมจะแนะนำให้ลองหัดใช้ C ให้คล่องก่อน เพราะว่ามันทำให้เราเรียนรู้ว่าคอมพิวเตอร์ทำงานอย่างไรได้ลึกมากกว่าภาษาอื่น ๆ แต่ว่าถ้าแค่อยากเขียนโปรแกรมเป็นนี่ภาษาอะไรก็ได้ครับ ในตอนนี้ผมจะแนะนำให้เขียนจาก JavaScript ก่อนละกัน สาเหตุคือคุณไม่ต้องใช้อะไรเลยนอกจาก Web Browser ในการหัดเขียนโปรแกรม (ไม่ต้องติดตั้งอะไรเลย!)

พอคุณเริ่มมีความรู้เกี่ยวกับการเขียนโปรแกรม สิ่งที่ควรจะเรียนรู้ต่อคือเรื่องทฤษฎีครับ ถ้าคุณไม่มีความรู้พวกนี้เลยเวลาคุยกับคนอื่นคุณจะงงไม่รู้เรื่องว่าเขาพูดอะไรกัน และถ้าคุณจะไปสมัครงานด้านนี้ล่ะก็ได้ใช้แน่นอน ทั้งนี้จริง ๆ หลายคนก็เป็นโปรแกรมเมอร์ที่หาเงินได้ทั้ง ๆ ที่ไม่มีทฤษฎีในหัว (หรือเคยมีแต่แทนที่ด้วยละครหลังข่าวไปหมดแล้วก็แล้วแต่) ดังนั้นจริง ๆ มันก็ไม่เชิงว่าเป็นเรื่องที่จำเป็นหรอก แต่ถ้ามีคุณจะต่อยอดได้ง่ายขึ้นมากทีเดียว

ทฤษฎีด้านไหนที่สำคัญ ผมว่าเริ่มจากตัวภาษาโปรแกรมก่อน (เช่น Programming Style/Paradigm ต่าง ๆ ) แล้วขยายไปด้านที่ตัวสนใจ เช่นถ้าชอบเขียนเกมก็ไปทาง Real-Time Graphics/Audio หรือถ้าชอบเขียนเวปก็ไปทางด้าน Usability อะไรทำนองนี้ครับ

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

และการตามการพัฒนาตรงนี้สิ่งที่สำคัญคือภาษาอังกฤษ (ไม่งั้นฟังอะไรไม่รู้) และความรู้พื้นฐานสำหรับสายงานด้านที่คุณสนใจ การขาดความรู้พื้นฐาน (= ทฤษฏี) ทำให้คุณฟังแล้วจับใจความไม่ได้ถึงรู้ว่าเขาพูดอะไรก็ตาม

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

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

Edit: ลืมไปเลย พอคุณเริ่มเก่งแล้ว เริ่มมั่นใจว่าทำได้ ให้ลองส่ง resume ไปตามบริษัท อาจจะต้องหลาย ๆ แห่งหน่อยเพราะหลายที่เขาดูวุฒิ ถ้าโชคดีได้สัมภาษณ์สักแห่งก็ลุยเต็มที่ครับ (ผมเคยเขียนถึงเรื่องการสัมภาษณ์เอาไว้แล้วแหละครับ) ลองดู ระหว่างที่รอเรียกสัมภาษณ์ให้ลองเขียนแอพของตัวเองเก็บไว้เป็นพอร์ทบ้างก็ดีครับ อาจจะเขียนเป็นเว็บไซต์ หรือทำโมบายล์แอพขึ้น Play Store (ซึ่งค่าใช้จ่ายต่ำมาก พันห้าร้อยบาทตลอดชีพ) อะไรแบบนี้ มันจะทำให้เราดูน่าสนใจมากกว่าอีกหลาย ๆ คนครับ อะไรที่ทำได้ก็ต้องทำล่ะครับ

พอดีว่าที่ทำงานกำลังจะเริ่มโปรเจคใหม่ที่เป็นโปรดักท์ใหม่เลย แต่ผมไม่ได้ทำด้วย มารู้เอาตอนเขาเซ็ตคนเสร็จเรียบร้อยละ อิจฉานิด ๆ (ฮา) โอกาสแบบนี้หายากครับ เพราะว่าส่วนใหญ่มีโปรดักท์ใหม่ตัวนึงก็ใช้กันยาว ๆ เป็นทศวรรษ กว่าจะมีโปรเจคใหม่สักตัว

อรัมภบทย์กันมานานละเข้าเรื่องดีกว่า มาสมมติกันว่าเรากำลังจะเริ่มโปรเจคใหม่ เอาแบบใหม่เอี่ยมเลยนะ ตัวโปรเจคนี้ควรจะมีอะไรเตรียมเอาไว้บ้าง

1. Version Control System หรือ VCS

พูดหลายรอบแล้ว แต่อีกสักรอบก็ดี ปัจจุบันนี้เราอยู่ในศตวรรษที่ 21 การขึ้นโปรเจคใหม่โดยไม่มี VCS เลยถือว่าเป็นการย้อนยุคกลับไปสมัยที่ Bill Gates ยังเป็นเด็กประถมที่ขโมยรร.ใช้คอมจนโดนสั่งห้ามนั่นแหละครับ

VCS ที่ใช้อาจจะเป็นรวมศูนย์ หรือแบบกระจายก็ได้ อันนี้ขึ้นอยู่กับองค์กรณ์ เพราะว่าบางที่เองก็ค่อนข้างอนุรักษ์นิยม (จริง ๆ คือคนทำงานขี้เกียจเรียนอะไรใหม่ ๆ มากกว่า) แต่ทั้งนี้ถ้าจำเป็นต้องใช้แบบรวมศูนย์ (Centralized) จริง ๆ ละก็ ... หาวิธีพ่วงแบบกระจายเข้าไปอีกดีกว่าครับ เช่นการใช้ git-svn ที่เป็นการใช้ git คู่กับ subversion เป็นต้น

2. Build Script, Deployment Script และ Dependency Manager

ผมจัดสามตัวนี้อยู่ในกลุ่มเดียวกัน กล่าวคือ มันเป็นส่วนที่ทำให้ Build Server ถูกใช้อย่างเกิดประโยชน์สูงสุด นึกดูนะครับสมมติว่าคุณมี Server ที่สามารถ check-out โค๊ดออกมา Build แล้ว Deploy ทั้งตัวโปรแกรมและ Dependency ทั้งหลายขึ้นไปให้คนใช้งานได้ด้วยคำสั่งเดียวมันจะสะดวกแค่ไหน นี่ไม่ใช่ความฝันครับ เป็นเรื่องที่ทำได้จริง และผมทำมาแล้ว (แต่ยังไม่ได้ใช้จริงจัง เดี๋ยวจะเล่าให้ฟังว่าเกิดอะไรขึ้น)

สำหรับคนใช้ Java ผมเคยพูดถึง Gradle ไปแล้ว Gradle นั้นเป็นระบบ Build ที่มีความสามารถในการเป็นทั้ง Dependency Manager และ Deployment Script ได้ด้วยตัวมันเอง (นอกเหนือจากความสามารถในการบิลด์โปรแกรมแล้ว) เทพไหมครับ นี่ล่ะสาเหตุว่าทำไมผมถึงยุบมันเหลือหมวดเดียวกัน :)

ส่วนสาเหตุว่าทำไมสามตัวนี้ควรถูกเขียนตั้งแต่เริ่มโปรเจค คืองี้ครับ จากประสพการส่วนตัวที่ทำแอพประเภท 2-tier แยกเป็น frontend กับ backend ที่ใช้เทคโนโลยีต่างกัน ผมจะเจอว่าคนที่ทำแต่ละฝั่งจะไม่ยอมศึกษาอีกฝั่งหนึ่งครับ (ข้ออ้างที่ผมเจอบ่อยสุดคือเขาว่า C++ มันยาก แหม ถ้ามันยากจริงทำไมไม่เพิ่มเงินเดือนผมอีกหน่อยล่ะ 😉 คิดไปเองทั้งนั้นแหละ ขนาดจะสอนให้เขายังไม่เอาเลยครับ) ผมอยู่ฝั่ง frontend ก็จะค่อนข้างลำบากนิดหน่อยเพราะว่าเราเข้าถึง data ตรง ๆ ไม่ได้ ก็เลยต้องศึกษาฝั่ง backend ที่เป็นฐานข้อมูลด้วย (และขอสารภาพตรง ๆ นะ ผมเกลียดฐานข้อมูลยังกับอะไรดี ถึงสมัยเรียนจะได้ A ก็เหอะ) (ส่วนอีกเหตุผลนึงคือเป็นคำสั่งจากเบื้องบนครับ ขัดขืนไม่ได้ 555) ในทางกลับกันคนที่เขียน backend นั้นมักจะทำงานส่วนของตัวเองได้สะดวกกว่า จะต้องพึ่งฝั่ง frontend แค่เฉพาะตอนปิดงานเท่านั้น ดังนั้นเขาก็จะขลุกอยู่กับ query (ที่อ่านไม่ค่อยออก) ของเขานั่นแหละ พอจำเป็นต้องใช้ frontend มาร่วมทดสอบทีก็จะมาเบียดเบียนคนทำ frontend ที งานพวกเราก็เยอะอยู่แล้วยังต้องไปซัพพอร์ตคนอื่นอีก รู้สึกน่าน้อยใจ (ทำไมไม่ขึ้นเงินเดือนให้อีกหน่อยล่ะ ?? :P)

เพื่อที่จะลดภาระของเราตรงนี้ผมก็ใช้เวลาวันหยุดเกือบ ๆ 3 เดือน ศึกษาเรื่องระบบ Build เรื่อง Deployment Script และ Dependency Manager (ก็เลยได้ Blog เพิ่มอีกหลายหน้า) หลังจากที่พับบลิชไป 3-4 เวอร์ชั่น ผมก็เผลอไปได้ยินคนที่ทำ backend คนหนึ่ง (ที่ค่อนข้างมีอิทธิพลพอสมควร) พูดกับปากเลยว่า "จะทำเองทำไม ให้เจ้า W ทำให้ก็ได้" ครับ สุดท้ายที่พยายามมาหลายเดือน ก็กลายเป็นแค่การขว้างงูไม่พ้นคอนั่นแหละ

ผมเชื่อว่าถ้าส่วนนี้ใช้งานได้ง่าย และสามารถปลูกฝังให้คนที่ไม่ได้เป็นคนเขียนโค๊ดโดยตรงสามารถใช้งานได้โดยไม่ต้องพึ่งพาคนอื่นละก็ ในระยะยาวมันจะติดเป็นนิสัยของทั้งทีมไปครับ และภาระของคนที่พัฒนาโปรแกรมนี้จะลดลงอย่างมาก

3. Build Server

ข้างบนพูดถึงตัวสคริปท์ ข้างล่างนี้จะเป็นตัวเครื่อง Server เอาไว้บิลด์ คือที่ควรมีเพราะว่าไอ้คนที่ไม่ได้เขียนโค๊ดจะได้ไม่ต้องลงโปรแกรมไว้ในเครื่อง (ซึ่งเป็นอีกข้ออ้างนึงที่เขาไม่ยอมเรียนเรื่องราวของอีกฝั่ง) เขาสามารถที่จะดึงโปรแกรมลงมาใช้ได้เลยทันทีที่อยากใช้ (ก็ไม่ทันทีหรอกครับ แอพหลายตัวบิลด์นาน โปรแกรมผมตอนนี้ล่อไปเกือบชม.แล้ว)

ทั้งนี้ ที่ตัว Repository กลาง (ของ VCS ที่เราเลือกใช้) ควรมีระบบที่สามารถไปสั่งให้ Build Server ทำงานหลังจากมีคน Commit โค๊ดใหม่เข้าไป เป็นการตรวจสอบว่าโปรแกรมนั้นคอมไพล์ผ่านถูกต้องหรือเปล่า ถ้าไม่มีก็ส่งบิลล์ค่าปรับไปที่คน Commit ได้เลยครับ (บ.ผมใช้วิธีนี้จริง ๆ ใครเอาโค๊ดที่คอมไพล์ไม่ผ่านเข้าไปจะถูกปรับ $25) นอกจากนี้หลังจาก Build เสร็จแล้วก็ควรรัน Unit Test และ Automated Test ต่าง ๆ ทั้งหมดอีกรอบด้วย เป็นการสร้างความเชื่อมั่นว่าโปรแกรมจะทำงานถูกต้อง เมื่อผ่านหมดทุกอย่างก็ Deploy ให้ QA เทสต์ต่อได้เลย ไม่ต้องรอรอบ

การมี Build Server ไว้สักตัวจะทำให้โฟลว์งานลื่นไหลขึ้นมากครับ เพราะว่าเป็นการลด Manual Work มหาศาล แต่สุดท้ายก็ขึ้นอยู่กับว่า Build Script/Dependency Script/Deployment Script เขียนมาดีขนาดไหนด้วย ถ้าต้องมีคนเข้ามาเกี่ยวข้องก็ถือว่าความพยายามนั้นไร้ค่าไป

4. Unit Testing

Unit Test ที่ว่านี้เป็นโปรแกรมที่เราเขียนขึ้นเพื่อทดสอบโค๊ดของเราว่าทำงานถูกต้องหรือไม่ (อย่างที่เคยเขียนถึง) การไม่มี Unit Test ในรูปของโปรแกรมเลย (คืออธิบายนิดว่าหลาย ๆ ที่ยังใช้แบบกระดาษอยู่ครับ) เนี่ยทำให้ค่าใช้จ่ายในการทดสอบโปรแกรมในระยะยาวนั้นมหาศาล เพราะโปรแกรมเมอร์จะต้องทดสอบโปรแกรมเอง ซึ่งประสิทธิภาพนั้นทาบแบบ automated ไม่ติดครับ ที่สำคัญคือมันทำซ้ำได้ อย่างถ้าเกิดโปรแกรมเรามีเทสเคสกว่าพันสองร้อยเคส คิดจริง ๆ เหรอครับว่าจะมีคนทดสอบมันหมดทั้งพันสองร้อยเคส ไม่มีทาง ผ่านไปสองเคสผมก็เลิกแล้วล่ะ

การมี Unit Test ตั้งแต่เริ่มโปรเจคนั้นก็เป็นการสร้างวินัยของโปรแกรมเมอร์เองนั่นล่ะครับ ถ้าเกิดว่า Unit Test นั้นไม่ครอบคลุมหรือไม่มีเลยตั้งแต่เริ่มโปรเจคแล้วเนี่ย นานไปก็ไม่มีใครมาดูแลมาทำให้มันสมบูรณ์ได้หรอก (ยิ่งเวลาเริ่ง ๆ จะปิดโปรเจคนะ อย่าให้พูดเลย UT นี่ล่ะจะถูกลืมตั้งแต่แรก)

5. Issue Tracking System

Issue Tracking System น่าจะเป็นเรื่องเดียวในนี้ที่ผมไม่เคยพูดถึงนะครับ โดยหลัก ๆ แล้วก็คือระบบที่จะเก็บว่าซอฟท์แวร์นั้นมีฟีเจอร์ไหนที่ต้องพัฒนา มีบั๊กอะไรบ้าง และใครเป็นคนดูแล เป็นระบบที่คอยแทร็คถึงความก้าวหน้าของโครงการ และปริมาณปัญหาในปัจจุบันนั่นล่ะครับ

ถ้าไม่มี แล้วใช้วิธีจดใส่กระดาษเอาล่ะก็ ... เอ่อ ขอให้โชคดีละกันนะครับ ผมมั่นใจว่ามันจะมีปัญหาแน่นอน ไม่ลืมก็หายนี่ล่ะ

6. Content Management System

CMS ก็คือระบบจัดการเนื้อหา (แปลทำไม?) โดยในโปรเจคเราจะมีเอกสารอยู่จำนวนหนึ่ง (ซึ่งยิ่งน้อยยิ่งดี ถ้าเอกสารมีเยอะมากแปลว่าระบบโดยภาพรวมกำลังมีปัญหา เพราะเอกสารคือสิ่งสุดท้ายที่คนจะสนใจครับ) การเก็บเป็นไฟล์สะเปะสะปะจะทำให้เราไม่สามารถค้นหาเนื้อหาที่จะต้องใช้ได้สะดวก คือพูดง่าย ๆ มันเป็นการทำงานน่าเบื่อให้เป็นเรื่องยุ่งยากเข้าไปอีก

CMS ที่ผมเคยเห็นก็แบ่งเป็นสองพวกหลัก ๆ แบบนึงจะเป็นแบบ Web Site เลย เนื้อหาที่สร้างขึ้นก็จะเป็นหน้าเวปหน้าหนึ่ง กับอีกแบบหนึ่งจะคล้าย ๆ VCS แต่เก็บพวกไฟล์เอกสาร (ที่ดัง ๆ ก็ Sharepoint, Alfresco) จริง ๆ แบบหลังเขาเรียกอีกอย่างว่า DMS (Document Management System) แต่ผมว่ามันก็เหมือนกันแหละ

สำหรับทีมที่โปรแกรมเมอร์ค่อนข้างจะเก่งหน่อย ผมว่าการบันทึกในรูปแบบ WIKI หรือใช้ Syntax แบบ Markdown นั้นจะดีกว่าการใช้พวก WYSIWYG Editor ครับ แต่ถ้าในทีมไม่ค่อยมีคนที่ใช้อะไรลักษณะนี้คล่อง ๆ ก็คงต้องทำใจใช้ Word Processor ไปนะ

1

หายหน้าไปนาน เรื่องที่เขียนค้างไว้เดี๋ยวจะกลับมาเขียนต่อนะครับ หลายเรื่องเหมือนกันแฮะ

ช่วงเดือนนิด ๆ ที่ผ่านมา พอดีผมถูกสั่งให้เข้าไปช่วยงานทีมพัฒนา โดยได้เข้าร่วมในโปรเจคเล็ก ๆ โปรเจคนึง ก็เช่นเคยครับ เป็นโปรเจคประเภทเพิ่มฟีเจอร์ให้กับผลิตภัณฑ์เดิมที่มีอยู่แล้วนั่นแหละ ถ้าให้พูดตรง ๆ ก็แค่เพิ่ม input field สองอันเท่านั้นเอง ฟังดูเป็นงานง่าย ๆ ใช่ไหมครับ ? (จะไม่ลงรายละเอียดของโปรเจคมากกว่านี้นะครับ)

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

มีปัญหาระหว่างการเขียนเอกสารออกแบบบ้างนิดหน่อย เขียน ๆ ไปแล้ว MS Word เดี้ยงครับ (คอมผมเก่าแล้ว แค่ที่ใช้มาก็จะ 7 ปีอยู่เดือนหน้าแล้วครับ นี่ไม่รู้ว่ามีใครใช้ก่อนหน้าอีกไหม) พอกู้ Word ได้คราวนี้ Windows ล่ม 555 ดีนะแค่เข้า Safe Mode แล้วมันหาย

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

บางทีการที่ทำงานบนพื้นฐานของดีไซน์ดั้งเดิมตั้งแต่แรกจนมันทำงานได้นั้นน่าจะเป็นทางเลือกที่ถูกต้องกว่า แน่นอนว่าการออกแบบเดิมนั้นมันก็อาจจะมีปัญหาบ้าง แต่เราก็น่าจะสร้างทางแก้เฉพาะหน้าเพื่อรับมือปัญหานั้นได้เร็วกว่าที่จะรื้อดีไซน์ใหม่ทิ้ง

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

แต่ก็อีกนั่นแหละ ถ้าเรายิดติดกับดีไซน์เดิมมากเกินไป บางทีมันก็พาเราไปหาทางตันได้เหมือนกัน สิ่งที่สำคัญก็คือเราต้องคอยประเมินอยู่ตลอดเวลาว่าสิ่งที่เราทำนั้นเป็นอย่างไรมีปัญหาอะไรบ้างครับ

ปล. ช่วงนี้นอนน้อยมากครับ กลับถึงบ้านก็ลุยเขียนโค๊ดต่อ รู้ตัวอีกทีเกือบสว่างมาหลายวันละ 555