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

เอาเถอะ ...

เท่าที่ลองวิเคราะห์ดู ตัวโปรดักท์ตัวนี้ตัวมันเองมีสองส่วน ส่วนหนึ่งคือชุดของ HTML Single Page Application เขียนด้วย Angular.JS กับเฟรมเวิร์คอีกหลายตัว ตรงนี้เซ็ตไม่ยากมีแค่ web server ตัวเดียวเอาไฟล์ไปวางไว้ก็ทำงานได้ละ

จุดที่ยากคือส่วนของ Middle Tier ที่เป็น Web Application แบ่งเป็นส่วนที่เก็บไอ้ส่วนแรกนั่นแหละ กับส่วนที่เป็นเรื่องของ service ต่าง ๆ ตรงนี้มันพึ่งพากับบริการสองส่วน ก็คือ JBoss EAP กับ MySQL (อันหลังเนี่ยอยากด่าสุด ๆ) ซึ่งบริการสองตัวนี้ก็ต้อง config ไม่งั้นมันก็ทำงานไม่ได้

มาถึงตรงนี้เรามีสี่ส่วนที่ต้องดูแล โชคดีว่าไอ้ Single Page นั่นเป็นแค่ static html ธรรมดาเลยไม่ต้องสนใจ ไอ้ที่เหลือเนี่ยสิงานช้าง ...

ตัวโปรดักท์เก่าเป็น J2EE Web App ธรรมดา ดังนั้นที่ต้องทำคือทำให้มันคอมไพล์ผ่าน ตัว application server ไม่จำเป็นต้องมีการคอนฟิกอะไรมากนัก ผมเคยเสนอ build automation ที่ชื่อว่า Gradle พร้อมเขียนสคริปท์ไปให้เรียบร้อย (ใช้วันหยุดไปตั้งหลายวัน เซ็งเป็ด) แต่ตัวใหม่เนี่ยแค่ Build Automation ไม่พอแล้ว เพราะว่าตัว application server ก็ต้องมีการ setup วุ่นวายมากมายตาแป๊ะไก่ นี่ยังไม่ได้พูดถึง MySQL เลยนะ

วันนี้เลยจะจดว่า แค่ Gradle มันไม่พอแล้ว เพราะว่าตัว JBoss eap ไม่มีวิธีที่จะ deploy module เข้าไปผ่านทางคำสั่ง ต้องเอาไฟล์ไปวางเอง ซึ่งตรงนี้เขียนเป็นสคริปท์ก็ลำบากเพราะว่าแต่ละเครื่องก็วางกันคนละที่ ส่วน MySQL นั้นยิ่งแล้วใหญ่ เพราะว่าถ้าใช้วิธีมี DB Server ในเครื่องแล้วโหลดเข้าโหลดออก (อย่าลืมว่าผมต้องทำงาน 3 release พร้อม ๆ กันนะครับ) แล้วมันอลวนสุด ๆ

ทางออกที่นึกออกตอนนี้คือ ใช้ Docker ซะเลย Docker เป็น Application Container มันจะมีซอฟต์แวร์ทุกอย่างที่จำเป็น เราสามารถสร้าง image ที่คอนฟิกทุกอย่างเอาไว้เรียบร้อยแล้ว แค่โหลดลงมาแล้วเรียกใช้ตรง ๆ ไม่ต้องคอนฟิกอะไรอีก ผมว่าวิธีนี้เวิร์คสุดในการคอนฟิกตัว service สองตัวที่จำเป็นต้องใช้

ส่วน Application Code นั้นเราก็สร้าง Gradle script ขึ้นมาใช้แบบเดิม น่าจะดีกว่า ...

ข้อเสียเหรอ ? มันต้องลงโปรแกรมเพิ่ม และ Docker ใช้งานได้เฉพาะบน Linux ถ้าเป็นแพลตฟอร์มอื่นต้องลง Virtual Machine ซึ่งก็มีเครื่องมือจัดการอยู่แล้วไม่น่ามีปัญหาอะไร

ปัญหาใหญ่ที่สุดคือทำอย่างไรให้คนอื่นฟังความเห็นเรานี่ล่ะ โปรดักท์เก่าเคยเสนอไปแล้วก็โดนตีกลับมาอย่างไม่มีความเห็น คราวนี้ manager product ตัวนี้มาไทยคงได้คุยกันบ้าง

ก่อนเริ่มขอนอกเรื่องนิด ไอ้เจ้าช่อง PG-Talk ที่ผมไม่ได้ทำมาตั้งครึ่งปีเนี่ย ผมคิดว่าน่าจะได้กลับมาทำในเร็ว ๆ นี้ครับ เพิ่งเคลียร์อะไรหลาย ๆ อย่างไปก็เลยว่าจะกลับมาทำต่อ

เรื่องที่จะเล่าวันนี้เป็นเรื่องนึงที่ผมคิดระหว่างการขับรถกลับบ้าน (อันตรายครับไม่ควรทำ 55) ก่อนจะเริ่มไปถึงจุดที่ผมว่าผมขอเล่าให้ฟังนิด คือได้ยินว่าในหลาย ๆ องค์กรมักจะวาง ecosystem ของระบบไอที ทั้งที่เป็นแบบให้บริการภายในบริษัทเอง หรือเป็นที่ให้บริการลูกค้า ตาม "ผลิตภัณฑ์" ที่แต่ละคนทำงานอยู่ ซึ่งไอ้เจ้า "ผลิตภัณฑ์" ที่ว่านี้นั้นสร้างจากเทคโนโลยีที่แตกต่างกัน เช่น ตอนแรกสร้างแอพเป็นคอนโซล เขียนด้วยภาษาดาต้าเบส (PL/SQL ?) แล้วต่อมาก็สร้างระบบ UI เป็น Windows ด้วยภาษา C++ หลังจากนั้ันก็พัฒนา web frontend ด้วย Python หรืออะไรก็ว่าไป ซึ่งฟังดูผ่าน ๆ มันก็เหมาะสมดีนะ เอาคนที่ทำงานคล้ายๆ กันมาอยู่ด้วยกัน มีอะไรก็แทนกันได้

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

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

แล้วก็ ปัญหาที่สำคัญที่สุดคือ ทำไมมันถึงมีส่วนที่ทับซ้อนกัน ?? การสร้างอะไรซ้ำซ้อนกันหลาย ๆ ที่นั้นเป็นข้อบ่งชี้ที่ดีอย่างหนึ่งว่า ระบบของเรากำลังจะมีปัญหาครับ ปัญหาที่ผมเล่ามาข้างบนนี่ล่ะ

ระหว่างที่ขับรถผมก็คิดว่า แล้วทำไมเราถึงไม่แบ่งตาม "functionality" ของตัว ecosystem แทนล่ะ ? เช่นสมมติเราทำระบบธนาคาร ก็มีส่วนงานหนึ่งดูแลแต่เรื่องข้อมูลส่วนที่ไม่ใช่การเงิน (เช่นพวกที่อยู่) อีกส่วนงานหนึ่งดูแลเรื่องการประมวลผล transaction (transaction processing) อีกส่วนงานหนึ่งดูแลเรื่องระบบสร้าง transaction ไป และอื่น ๆ ... คือมันก็เหมือนกับการแบ่งงานให้คนทำล่ะครับ ทำตามหน้าที่ของตัวงาน ไม่ใช่แบ่งตาม เอ่อ ... "สถาบันการศึกษา" หรืออะไรคล้าย ๆ กันนั่นล่ะครับ (ถ้ามองว่าคนงานคือตัวแผนกงานที่ทำ function ต่าง ๆ ผมว่าตัวภาษาที่ใช้สร้างตัวชิ้นส่วนที่ทำงานตรงนั้นก็คล้าย ๆ กับสถาบันการศึกษาที่สร้างคนงานมานั่นล่ะมั้ง ? 555)

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

คราวนี้ก็จะมีคนสงสัยว่า อ้าว ถ้าต่างคนต่างดูแล function ของตัวเองแล้วมันจะเชื่อมโยงได้อย่างไร ถ้าเป็นในอดีตก็ยากครับ อาจจะมีการปิดโปรแกรมโน้นเปิดโปรแกรมนั้น เพราะว่าแอพบนเดสก์ท็อปจะมีความเชื่อมโยงกันน้อย แต่เราอยู่ในยุคที่เว็บครองเมืองแล้วใช่ไหมครับ ? แต่ละทีมก็สร้างผลิตภัณฑ์แบบเว็บ ใช้วิธีที่แตกต่างกันหรือเหมือนกันก็ได้ (เหมือนกันดีกว่าครับ) ของใครของมันไปเลย แต่สามารถเชื่อมโยงถึงกันได้ แชร์ session id กันได้ สามารถสลับไปมาระหว่างผลิตภัณฑ์โดยที่ผู้ใช้ไม่รู้ตัว (แบบเดียวกับ Google -> Google Drive -> GMail -> Google Docs อะไรทำนองนี้ล่ะครับ) คราวนี้ต่อให้เป็นซอฟต์แวร์ที่แยกขาดออกจากกันก็ยังสามารถทำงานร่วมกันได้ ผู้ใช้ไม่รู้ตัว อ้อ วิธีนี้มีข้อดีอีกอย่างคือสามารถขายแยกส่วนได้ครับ เพราะมันไม่อิงซึ่งกันและกันนั่นเอง

อีกอย่างที่สำคัญคือ ถึงจะบอกให้แยกตาม functionality แล้วก็จริง แต่ละฟังก์ชันก็ควรจะทำงานร่วมกันได้ แต่ละทีมควรจะมี API เพื่อเรียกใช้ฟังก์ชันของทีมตัวเองได้ อาจจะเป็น Web Service หรืออะไรก็แล้วแต่

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

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