วันจันทร์ที่ 28 มีนาคม พ.ศ. 2559

Vaadin: How to listen to animation end part 3 (end)

>> เข้าประเด็นกันเลย
- ผมไม่ต้องการคลาส EndAnimatorWidget เพราะคลาส EndAnimator ไม่จำเป็นต้องมีหน้าตาใดๆ
- ผมไม่ต้องการอินเตอร์เฟส EndAnimatorClientRpc เพราะไม่มีงานของหน้าบ้านที่ต้องคุยกับหลังบ้านด้วย rpc ของหน้าบ้าน (ขอโทษครับเรื่องศัพท์แปลกๆของผม)
- ผมไม่ต้องการคลาส EndAnimatorState เพราะจะไม่มีการรับส่งค่าใดๆผ่านตัวแปร
- ผมต้องการ ให้คลาส EndAnimator ลงทะเบียนอินเตอร์เฟส EndAnimatorServerRpc เพื่อคอยรับสัญญาณจากคลาส EndAnimatorConnector แค่นั้น
- ผมต้องการ ให้อินเตอร์เฟส EndAnimatorServerRpc ใช้ rpc คอยรับการทำงานจาก EndAnimatorConnector เมื่อจาวาสคริปต์ทำงาน 'animationend' ของ animation ใดๆ
- ผมต้องการ ให้คลาส EndAnimatorConnector มีบริการลงทะเบียน 'animationend' สำหรับ component ใดๆที่ต้องการให้เล่น animation
- และเมื่อ 'animationend' ปรากฏ นั่นหมายความว่า EndAnimatorServerRpc จะต้องทำงานและส่งการทำงานนี้ให้กับอินเตอร์เฟสที่ทำหน้าที่เสมือนรับฟังเหตุการณ์เล่น animation เสร็จสิ้น
- ผมขอตั้งชื่ออินเตอร์เฟสที่ทำหน้าที่เสมือนรับฟังเหตุการณ์เล่น animation เสร็จสิ้นนี้ว่า AnimationEndListener ซึ่งมีบริการ onAnimationEnd สำหรับทุก component ที่เรียกใช้คลาส EndAnimator ครับ

>> ดังนั้นคลาส EndAnimator หรือก็คือหัวใจของเรื่องนี้จึงต้องมี AnimationEndListener บังคับให้ใช้อยู่ภายใน, สำหรับทุก component ที่มันรับฟัง (listen) การเล่น animation จนเสร็จสิ้นจะถูกบังคับทำ onAnimationEnd จาก EndAnimatorServerRpc อีกทอดหนึ่ง รายละเอียดทั้งหมดดังรูป

- เพื่อที่จะให้คลาสนี้ส่ง component ใดๆไปให้คลาส EndAnimatorConnector จึงต้องให้สืบทอด com.vaadin.server.AbstractExtension, เช่นเดียวกับคลาส EndAnimatorConnector ที่ต้องเป็นลูกของ com.vaadin.client.extensions.AbstractExtensionConnector มิเช่นนั้นมันจะคุยกันไม่รู้เรื่อง

>> คลาส EndAnimatorConnector เมื่อเป็นลูกของ com.vaadin.client.extensions.AbstractExtensionConnector จึงถูก override เมธอด extend เพื่อที่จะนำ component ที่รับมาจากคลาส EndAnimator มาเพิ่มการฟัง 'animationend' (ชื่อมาตราฐาน) ด้วยการเรียก registerCssCallback ที่ทำงาน native javascript code จับเหตุการณ์การเล่น animation เสร็จสิ้นของแต่ละ browser, เมื่อ callback function ถูกเรียกก็จะส่งผลให้ onAnimationEnd ของอินเตอร์เฟส AnimationEndEventHandler ทำงาน มันจะส่งสัญญาณไปบอกต่อ EndAnimatorServerRpc ซึ่งจะกลับไปที่คลาส EndAnimator เพื่อทำงาน onAnimationEnd ของอินเตอร์เฟส AnimationEndListener นั่นเอง



>> ทีนี้มาดูกันว่าใช้งานอย่างไร และเหตุใดผมจึงต้องหาวิธีการอย่างนี้มาจัดการกับเหตุการณ์ end animation
- ปรับปรุงคลาส MyUI ให้สร้างสี่เหลี่ยมขนาด 300 x 300 px ออกมา ให้ชื่อมันว่า animateLayout
- ใส่ style sheet พื้นหลังสีเหลือง ให้เล่น animation ของไลบรารีตัวนี้ http://daneden.github.io/animate.css/ มันก็จะหมุนติ้วๆ
- และเมื่อ animation เล่นจบลง ผมก็ให้เปลี่ยนพื้นหลังเป็นสีเขียว (อย่างที่เพื่อนๆชาว css ทราบกันดีอยู่แล้วว่าจะเกิดการ override สีพื้นหลัง) พร้อมกับลบ animation หมุนติ้วๆนี้ออก




- เพื่อนๆจะเห็นว่า css class names ที่ถูกเพิ่มเข้าไปเมื่อไม่ลบออกก็จะฝังอยู่ในแท็ก html (ได้แก่ .background-yellow และ .background-green) ซึ่งงานของผมไม่ต้องการให้ css class names ของ animation ฝังอยู่จึงสั่งให้ลบออกไปหลังจาก animation เล่นจบลง ทีนี้เวลาผมกดปุ่ม F5 หรือเคลื่อนย้าย dom ก็จะไม่เกิดการเล่น animation เหล่านี้อีก เป็นว่าบรรลุเป้าหมายครับผม (ยิ้ม)

>> และนี่คือโครงสร้างทั้งหมดของโปรเจ็กต์และการ include css animation ดังข้างต้นเข้าไป


*** ผมสังเกตว่า
- หากแก้ไข (รวมถึง เพิ่มไฟล์ ลบไฟล์) widgetset ก็ต้อง compile มันใหม่ ผมจะคลิกขวาที่โปรเจ็กต์แล้วเลือกคำสั่ง Build
- หากแก้ไข vaadin หลังบ้าน (ในที่นี้ได้แก่คลาส EndAnimator และ MyUI) ให้คลิกขวาที่โปรเจ็กต์แล้วเลือกคำสั่ง Run ได้เลย (มันจะ compile กับ deploy ให้อัตโนมัติ)

>> ใครที่สนใจ gwt อยากลองมาเขียน vaadin ผมขอบอกว่ามันแจ่มมาก! เป็น open source เพื่อทำงานกับ JEE เหมือนกันแต่ compile ไวกว่า ลองไปเยี่ยมชมพวกเขาสิครับ
https://vaadin.com/home
คืนนี้ฝันดีจ้า

วันอาทิตย์ที่ 27 มีนาคม พ.ศ. 2559

Vaadin: How to listen to animation end part 2

>> มาสร้างโปรเจ็กต์แรกกันเถอะ ด้วย netbeans เวอร์ชัน 8.1 กับ jdk เวอร์ชัน 1.8.0_65

1) เลือกสร้างโปรเจ็กต์จาก maven ด้วยวิธีการ project from archetype

2) ที่หน้าต่าง maven archetype ให้เพื่อนๆค้นหาแม่แบบที่เป็น vaadin-archetype-application (อ่านเพิ่มเติมสำหรับแม่แบบอื่นๆ)

3) ตั้งชื่อโปรเจ็กต์, กำหนดที่อยู่ของโปรเจ็กต์, ตั้งชื่อ group id รวมไปถึงรายละเอียดปลีกย่อยด้านล่าง ได้แก่ ชื่อของ widgetset และชื่อของคลาสหลัก

4) เสร็จแล้วโปรดคอยสักครู่ เจ้า maven นี้จะตามไปโหลดไฟล์จาร์ที่เกี่ยวข้องกับแม่แบบที่เราได้เลือกไว้มาให้ และหลังจากนั้นก็เปิดเข้าไปดูหน้าตาของ source code ที่มันเขียนไว้ให้กันเลย

5) เดี๋ยวผมจึงจะอธิบายว่ามันเขียนอะไรมาให้บ้าง ตอนนี้อยากให้ลองรันโปรเจ็กตนี้กันก่อนครับ ด้วยการคลิกขวาที่ชื่อโปรเจ็กต์แล้วเลือก run มันจะถามว่าจะรันบน server ตัวไหน ผมเลือกเป็น glassfish server เวอร์ชัน 4.1.1 จากนั้นกดปุ่ม ok

6) เข้าใจว่ามันจะ compile สิ่งที่เรียกว่า widgetset ด้วย (ถ้ามี) รวมไปถึงสร้าง .war และ deploy ขึ้นสู่ server

7) และปรากฏสู่สายตา


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

- บรรทัดที่ 24 บอกว่าเราใช้ theme ชื่อ mytheme ซึ่งอยู่ ณ end_animator\src\main\webapp\VAADIN\themes
- บรรทัดที่ 25 บอกว่าเรามีไฟล์ .gwt.xml หรือก็คือ widgetset อยู่ที่ end_animator\src\main\resources\com\pros\endanimator


- บรรทัดที่ 29 นี่เป็นเมธอดแรกที่ vaadin จะเข้ามาทำงาน
- บรรทัดที่ 30 คือ layout แบบ vertical เหมือนกับจานที่ตั้งซ้อนกันขึ้นไป เพียงแต่ความจริงแล้วการเพิ่ม component จะเป็นการเรียงลงมาด้านล่าง หากแกะดู html code ก็จะพบว่ามันคือแท็ก div ที่วางเรียงต่อกันจากบนลงล่างครับ
- บรรทัดที่ 32 สร้างช่องรับข้อมูลหรือก็คือ text field ขึ้นมา จากนั้นระบุ caption ว่า Type your name here:
- บรรทัดที่ 35 สร้างปุ่มหรือก็คือ button โดยระบุ caption ว่า Click Me จากนั้นกำหนด click event ให้กับปุ่ม ประมาณว่ากดปุ่มแล้วอยากจะให้ทำอะไรด้วยวิธีการเขียนของจาวา 1.8 ที่เรียกว่า lambda expressions (อ่านเพิ่มเติม) ซึ่งต้องการให้เพิ่ม label เข้าไปใหม่ทุกครั้งที่กดปุ่ม โดยให้ label นี้มีค่าเป็น Thanks ตามด้วยข้อความที่เราได้กรอกเข้าไปในช่อง text field ตามด้วย , it works!
- บรรทัดที่ 41 เพิ่ม text field กับ button เข้าไปใน layout
- บรรทัดที่ 42 กำหนด padding ใหักับ layout (ระบบ margin ของ vaadin ก็คือ padding ครับ)
- บรรทัดที่ 43 กำหนดพื้นที่ว่างระหว่าง text field กับ button ให้แลดูสวยงาม
- สุดท้ายบรรทัดที่ 45 ก็กำหนด layout ให้กับ panel หลักหรือก็คือพื้นที่ที่ใช้แสดงผลนั่นเอง (แท็ก body) หากขาดบรรทัดนี้ไป เราก็จะมองไม่เห็นอะไรเลย (เห็นหน้าเปล่าๆ)


- บรรทัดที่ 48 กำหนดให้มี servlet (อย่างที่เพื่อนๆทราบ พื้นฐานของจาวาเว็บก็คือ servlet) ตัวหนึ่งมีหน้าที่รับผิดชอบต่อประดา request ที่ถูกยิงเข้ามาหาโปรเจ็กต์นี้ (สำหรับ /* คือทุก request)
- บรรทัดที่ 49 กำหนดให้ MyUI เป็นคลาสหลักที่สืบทอดจากคลาส com.vaadin.ui.UI (vaadin ตั้งแต่เวอร์ชัน 7 เป็นต้นมาคลาสหลักต้องเป็นลูกของคลาส UI) ทั้งกำหนดโปรเจ็กต์นี้ถูกจัดการหน่วยความจำแบบ dev mode (หรือก็คือการกำหนดว่า production mode มีค่าเป็น false)
- บรรทัดที่ 50 พูดถึงบรรทัดที่ 48 เจ้า servlet ที่รับผิดชอบต่อทุก request ของโปรเจ็กต์นี้ก็คือคลาสชื่อ MyUIServlet ที่เป็นลูกของ VaadinServlet นั่นเองครับ

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

>> ผมต้องการสร้าง widgetset เพื่อทำงาน javascript กับ rpc, ผมพบอยู่ 2 วิธีครับ
1) สร้างทีละคลาสเอง (= =) อื่ม... ก็ทำได้อยู่ หรือ
2) ติดตั้ง vaadin plugin ตามขั้นตอนต่อไปนี้ (ผมเลือกวิธีนี้นะ)
จาก https://www.youtube.com/watch?v=P9YupaOpsMk
- เลือกเมนู Tools ตามด้วย Plugins

- เลือกแท็บ Available Plugins และค้นหาด้วยคีย์ว่า vaadin

- พบ plugin ชื่อดังรูปด้านล่างนี้ (เวอร์ชันอาจต่างกัน) ก็ติดตั้งเลยครับ


- เมื่อติดตั้งเสร็จเรียบร้อยแล้ว (รวมถึงหลังจากที่เจ้า netbeans ขอ restart) เพื่อนๆจะสามารถสร้างโปรเจ็กต์ vaadin ได้ โดย netbeans รู้จักวิธีการดังกล่าวแสดงอยู่ในช่อง Categories และมีรูปแบบย่อยให้เลือกสร้างในช่อง Projects (ทดลองสร้างโปรเจ็กต์ใหม่อีกสักรอบ ต้องเห็นดังรูปด้านล่างนี้)


>> ทีนี้เรากก็ขอให้ netbeans สร้าง widgetset ให้ได้แล้วล่ะ คลิกขวาที่โปรเจ็กต์เลย แล้วเลือก New > Other... > มองหา Vaadin แล้วเลือก File Types เป็น Vaadin Widget กดปุ่ม Next

- ผมตั้งชื่อ Class Name: เป็น EndAnimator และคลาสนี้อยู่ฝั่งหลังบ้านหรือก็คือ vaadin
- ให้สังกัด Package: เป็น com.pros.endanimator
- ตัวเลือกด้านล่าง เลืก Server side component / Client side connector with shared state and RPC, including custom widget. เดี๋ยวอันไหนไม่ได้ใช้ค่อยลบออก
- กด Next เลย

- โดยปกติแล้ว หลังบ้าน (vaadin) กับ หน้าบ้าน (gwt) จะติดต่อกันผ่าน interface ที่ระบบนี้สามารถเข้าใจกันได้ และโดยปกติแล้วหลังบ้านจะใช้ com.vaadin.ui.AbstractComponent interface แต่ครั้งนี้ผมขอเปลี่ยนเป็น com.vaadin.server.AbstractExtension ทว่าไม่มีให้เลือก ? โอเค งั้นก็ใช้ com.vaadin.ui.AbstractComponent ไปก่อน เดี๋ยวค่อยไปแก้ไขเอาทีหลัง กดปุ่ม Finish

- netbeans ก็จะสร้างคลาสและอินเตอร์เฟสต่างๆออกมา อย่างที่ผมได้รับตามนี้ครับ


>> เป็นว่าตอนนี้ผมให้ netbeans เตรียม widgetset ให้เสร็จแล้ว แต่มันไม่ได้ทำงานตามที่ผมต้องการ แต่ผมก็อยากจะอธิบายเสียหน่อยว่า widget ใหม่ที่เพิ่งได้มานี้ เขาเขียนโค้ดให้มันทำงานอะไร เรามาดูแต่ละคลาสแต่ละอินเตอร์เฟสที่สำคัญกันก่อนนะ ซึ่งแบ่งออกเป็นสองฝั่ง
- ฝั่งหลังบ้าน ตอนนี้มีคลาส EndAnimator กับ MyUI
- ฝั่งหน้าบ้าน คือทั้งหมดใน package ชื่อ com.pros.endanimator.client นั่นแหละ ประกอบด้วย EndAnimatorClientRpc, EndAnimatorConnector, EndAnimatorServerRpc, EndAnimatorState และ EndAnimatorWidget

>> คลาส EndAnimator (หลังบ้าน) มี constructor ทำงาน register ออบเจ็กต์ rpc หลังบ้านไว้ตัวหนึ่ง พร้อมกับบริการ getState ที่สามารถให้ค่าของตัวแปรชื่อ text ออกมาได้, มองไปที่ตัวออบเจ็กต์ rpc มันคือ EndAnimatorServerRpc ที่เป็น interface โดยจะรอสัญญาณ (จากหน้าบ้าน) เพื่อทำงานเมธอด clicked และมี MouseEventDetails เป็นพารามิเตอร์ (อ่านทั้งหมดนี้ด้วยตัวเอง) ดูรูปประกอบ

- หมายความว่าอย่างไรสำหรับสิ่งที่ออบเจ็กต์ rpc นี้ทำ หมายความว่า ทุกครั้งที่เมธอด clicked นี้ถูกเรียก ค่าของตัวแปร clickCount จะเพิ่มขึ้นหนึ่งทุกครั้งไป และเมื่อไรก็ตามที่ค่าของมันเอาไปหารเอาเศษด้วย 5 แล้วได้ค่าเป็น 0 มันจะเรียกไปที่ rpc อีกตัวที่อยู่ฝั่งหน้าบ้าน (ซึ่งตอนนี้เรายังไม่รู้จัก) โดยบอกให้ rpc ฝั่งหน้าบ้านนี้ทำงานเมธอด alert แสดงข้อความ Ok, that's enough! ออกมา
- โดยทุกรอบที่เมธอด clicked นี้ทำงานก็จะเปลี่ยนค่าตัวแปร text ที่ถูกสร้างไว้ในคลาส EndAnimatorState เป็น You have clicked ตามด้วยค่า clickCount และตามด้วย times (ประมาณว่านับครั้งให้)
- เพื่อนๆมือใหม่จะเห็นว่าคลาส EndAnimator นี้ไม่มีหน้าตาใดๆเลย มันไปอยู่ไหนนะ?

>> คลาส EndAnimatorConnector (หน้าบ้าน) มี constructor ทำงาน register ออบเจ็กต์ rpc หน้าบ้านไว้ตัวหนึ่ง, บริการ getState ที่สามารถให้ค่าของตัวแปรชื่อ text ออกมาได้, บริการ getWidget คือช่องทางที่ connector จะสื่อสารกับ gwt, กลไก onStateChanged ที่ทำงานอัตโนมัติเมื่อมีการเปลี่ยนค่าของตัวแปร text จากหลังบ้านมายังหน้าบ้าน (ปกติแล้ว vaadin สามารถคุยกับ gwt ได้ก็ผ่าน onStateChanged นี้ครับ แต่ถ้า gwt จะคุยกลับไปที่ vaadin จะต้องใช้ rpc มาช่วย), มองไปที่ตัวออบเจ็กต์ rpc มันคือ EndAnimatorClientRpc ที่เป็น interface โดยจะรอสัญญาณ (จากหลังบ้าน) เพื่อทำงานเมธอด alert และก็จะใช้ javascript เขียน message แบบกล่องข้อความออกไป ซึ่งก็คือข้อความว่า Ok, that's enough! นั่นเอง

- คำถามคือ แล้วเมื่อไรที่ rpc ฝั่งหลังบ้านจะถูกเรียกล่ะ? เพราะเท่าที่อธิบายมา ดูเหมือนว่า logic นี้จะคอยให้มีการส่งสัญญาณไปหา rpc ฝั่งหลังบ้านก่อน จากนั้นฝั่งหน้าบ้านจึงจะ alert ข้อความออกมาได้ ฮั่นแน่!เพื่อนๆที่ตาไวตอบผมได้ทันควัน บรรทัดที่ 33 ในรูปข้างต้นนั่นไงที่จะผลิตสัญญาณหรือก็คือการเรียกเมธอด clicked ของฝั่งหลังบ้านให้ทำงานตาม logic นี้โดยส่งพารามิเตอร์ที่มันต้องการให้ด้วย นั่นคือออบเจ็กต์ MouseEventDetails ครับ
- เรื่องของเรื่องจะเริ่มจากผู้ใช้ต้องเห็นหน้าตาของ widget ที่ browser ก่อนจากนั้นทำอะไรกับมันสักอย่าง ฮั่นแน่!เพื่อนตาไวคนเดิมตอบผมทันทีว่า คลิก ผู้ใช้คลิกอะไรสักอย่างไง! ใช่ครับบรรทัดที่ 28 เราได้ขอ widget จาก getWidget เพื่อคอยฟัง ClickHandler (ฟังการคลิกจากผู้ใช้) เพราะเมื่อคลิกเข้ามา onClick จะทำงาน เกิดการสร้างออบเจ็กต์ MouseEventDetails ด้วยกลวิธีดังในรูป แล้วส่งให้กับ rpc หลังบ้านทำงานในที่สุด เย้! เป็นว่าเพื่อนๆกับผมเข้าใจหัวใจการทำงานของระบบ rpc นี้แล้วนะครับ

>> สุดท้ายที่จะอธิบายก็คือคลาส EndAnimatorWidget หรือก็คือ widget เจ้ากรรมที่ผู้ใช้จะมองเห็นหน้าตาของมันนั่นเอง คลาสนี้เป็นลูกของ com.google.gwt.user.client.ui.Label ดังนั้นหน้าตาที่จะเห็นก็ต้องเป็น label ที่ถูกกำหนดค่ามาให้

ฮั่นแน่! เพื่อนตาไวอีกคนรู้เลยว่าค่าของมันก็คือ
"You have clicked " + clickCount + " times"
ที่ถูกกำหนดมาตั้งแต่แรกที่คลาสหลังบ้าน EndAnimator นั่นแล้ว (ลองกลับไปดูบรรทัดที่ 21 ของคลาส EndAnimator) แต่ผิดครับ ไม่ใช่ข้อความ "You have..." มันคือข้อความว่า "This is EndAnimator" นั่นเพราะว่ามันคือค่าแรกที่กำหนดให้กับตัวแปร text ในคลาส EndAnimatorState (ลองเปิดดูสิ) ถือว่าเป็นเสน่ห์ของ EndAnimatorState ที่สามารถส่งค่าของตัวแปรใดๆ (ต้องมีชนิดตามที่ระบบของทั้งสองฝั่งรู้จักนะ) ออกไปได้ผ่านบริการ getState ของทั้งฝั่งหลังบ้านและหน้าบ้านครับ

>> เอาล่ะ เรามาทดลองรันมันกันเถอะ โดยกลับไปแก้ไขคลาส MyUI ให้เรียกมันออกมาก่อน ตามนี้

- เพื่อนๆควรทราบว่า หากเราได้เคยลองรันมาแล้วแล้วรันใหม่ ผลลัพธ์ที่ได้จะไม่เปลี่ยนแปลง เนื่องจากว่า server ยังคงใช้ .war อันเก่า เราต้องหาวิธีการให้ server มันรู้ว่าต้องใช้ .war ใหม่นะ (เพราะ source code เราได้เปลี่ยนแปลงไปแล้ว)
- ให้คลิกขวาที่โปรเจ็กต์ เลือก Build หรือ Clean and Build เพื่อ compile ทุกสิ่งใหม่ จากนั้นจึงคลิกขวาที่โปรเจ็กต์อีกครั้งแล้วสั่ง run ก็จะเป็นการ deploy .war ใหม่ขึ้นสู่ server ครับ (ใครมีวิธีดีกว่านี้ช่วยบอกผมหน่อยก็ได้นะ)

- ทดสอบคลิกไปที่ข้อความ

- และคลิกครั้งที่ 5 ซึ่งหารเอาเศษกับ 5 จะมีค่าเท่ากับ 0


>> อ๊! อธิบายเพลินจนลืมตัว มันยาวอีกแล้ว (= =) ไว้ต่อ part หน้านะครับ ดึกแล้วฝันดี

วันเสาร์ที่ 26 มีนาคม พ.ศ. 2559

Vaadin: How to listen to animation end part 1

>> เนื่องจากผมกำลังศึกษาการเขียน vaadin ด้วย netbeans ซึ่งแท้จริงแล้วผมเขียนมันด้วย eclipse เสมอมา (สังเกตได้จากตัวอย่างก่อนหน้านี้ที่ได้นำเสนอไป) ก็เพราะว่าคราวนี้ผมมีงานที่จำเป็นต้องใส่ animation ให้กับ component บางชิ้น ผมจึงต้องถามตัวเองว่า เทคโนโลยีในขณะนี้ในเรื่องของ animation (โดยเฉพาะกับเว็บเนี่ย) เขาใช้อะไรกัน? คำตอบก็คือ...

>> ใช้ css เวอร์ชัน 3 น่าจะดีที่สุดและง่ายที่สุดสำหรับผมในตอนนี้ครับ

แน่นอนว่า browser ใหม่ๆรองรับมาตราฐานนี้กันหมดแล้ว (เยี่ยมชม)

>> มาฟังปัญหาของผมกันก่อนนะ แท้จริงแล้ว component (รากฐานของ ui ของ vaadin แต่ละชิ้นมาจาก interface ที่ชื่อ Component) เพียงนำมาจับใส่ css class name พวกมันก็สามารถเล่น animation ได้ด้วยดี แต่ทว่า...เมื่อพวกมันเล่น animation จบสิ้นไปแล้ว พวกมันก็ยังคงติดแหง่กฝังอยู่ในแท็ก html (= =) ใครฟังมาถึงตอนนี้ก็ต้องบอกผมว่า แหม มันก็เป็นธรรมชาติของการใส่ style sheet อยู่แล้วนี่ (css ย่อมาจาก Cascading Style Sheets) ก็เหมือนตอนใส่สีพื้นหลังไง background-color: yellow; มันก็ต้องได้สีเหลืองอยู่อย่างนั้นแหละ แต่ๆๆแต่ผมไม่ต้องการแบบนั้น เพราะงานของผมเจ้าชิ้นที่ใส่ animation ไปนั้นน่ะเมื่อมันถูกลากหรือย้ายตำแหน่ง (ตำแหน่งของ dom เปลี่ยนไป) มันจะกลับไปเล่น animation ซ้ำอีกรอบ เพื่อนคนเดิมก็บอกมาอีกว่า ก็ใช้ animation fill mode กำหนดให้มันเล่นไปข้างหน้า (forwards) อย่างเดียวเลยก็ได้นี่ ผมก็ขอบคุณเขานะ แต่ๆๆแต่เมื่อผมกดปุ่ม F5 (refresh page) เท่านั้นแหละ เจ้ากรรม animation ก็จะกลับมาเล่นใหม่เหมือนเดิม คำตอบที่ผมต้องการคือ เมื่อพวกมันเล่นจบผมจะลบพวกมันทิ้งไปเลย! (เอาออกจากแท็ก html)

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

เพราะผมเองก็ไม่คล่อง javascript หนักเลยคือรู้เรื่อง animation ของ css น้อยมากเมื่อเที่ยบกับการเขียนโปรแกรมนี้ด้วย vaadin ในเมื่อผมเป็น java และตอนนี้ต้องใช้ css มาทำ animation, ผมจึงอยากทราบว่า ผมจะรู้ได้อย่างไรว่า animation เหล่านั้นได้เล่นจนเสร็จสิ้นไปแล้วครับ?

และผมก็มีคำตอบ นั่นคือเรื่อง animation end event (อ่านเพิ่มเติม) ซึ่งต้องใช้ javascript มาดักฟัง ...ห๊ะ?...นี่ต้องมาเขียนจาวาสคริปต์อีกแล้วหรือ ก็ใช่ไง

>> เอาล่ะในเมื่อหนีมันไม่พ้นก็พุ่งชนเสียเลย, ผมรู้ว่า vaadin สามารถเข้าใจ javascript เพียวๆได้ (อ่านเพิ่มเติม) ด้วยการกำหนด function ก่อนจากนั้นค่อยเรียกใช้ แต่แนวทางนี้สำหรับสินค้าแต่ละชิ้นของเว็บดูเหมือนว่าจะต้องส่งค่า id ให้กับ function ด้วย เพื่อที่ function จะได้แยกแยะสินค้าแต่ละชิ้นได้ แล้วยังไงต่อ...ก็ต้องหาทางผูก id เข้ากับ animation end event อย่างนั้นสินะ โอ้ย~คิดไม่ออก อ่อนแอจาวาสคริปต์

มีวิธีอื่นอีกไหมที่สามารถเอาชนะปัญหานี้ได้ (แน่นอนว่ายังต้องพึ่งพา javascript) อ้อ การเขียน vaadin แบบ native ไง (คำเรียกของผมเอง) ซึ่งจะเรียกให้ถูกต้องคือการเขียน gwt ขึ้นมาเองโดยวิธีการที่เรียกว่า widgetset (อ่านเพิ่มเติม) พร้อมกับใช้วิธี rpc ในการสื่อสารระหว่าง vaadin (ฝั่งหลังบ้าน) กับ gwt (ฝั่งหน้าบ้าน) ดังกล่าว (อ่านเพิ่มเติม) เพื่อนๆจะเห็นว่าผมต้องอ่านเยอะ ยิ่งความรู้ไม่มี ผมก็ต้องอ่านให้มากเข้าไว้ (ไม่นับว่าอ่านแล้วตีความผิดอีก อะโด่~) เอาล่ะครับมาลงมือทำกันเถอะ

>> เครื่องมือที่ผมจะใช้สร้างงานชิ้นนี้
- NetBeans IDE 8.1
- และวิธีทำให้ netbeans นี้สร้าง vaadin project ให้ผมได้
(คลิกไปอ่านพร้อมกันเลย: https://vaadin.com/docs/-/part/framework/getting-started/getting-started-netbeans.html)

>> อุ้ย!ยาวไปแล้วขอตัดจบก่อน (เล่นตัว) ให้เพื่อนๆลองสร้างโปรเจ็กต์แรกพลางกันไปก่อน เดี๋ยวพรุ่งนี้ผมมาคุยให้ฟังต่อ

>> ขอบคุณยิ่งสำหรับแหล่งความรู้เหล่านี้ที่แชร์กันในโลกออนไลน์ ซึ่งทำให้ผมสามารถเอาชนะปัญหานี้ได้ โดยเพื่อนๆสามารถอ่านเพิ่มเติมเองได้ครับ
- How to Capture CSS3 Animation Events in JavaScript
- Client-server connector and onStateChanged
- How to add CSS AnimationEnd event handler to GWT widget?
- Navigator userAgent Property
- Delayed Client -> Server RPC call when using JSNI -> Java callbacks
- Component and UI Extensions
- Animate.css

>> และนี่คืองานที่ผมทำสำเร็จแล้วบน eclipse ครับ


วันเสาร์ที่ 19 มีนาคม พ.ศ. 2559

Spring4 & Hibernate4 & MySQL project example

>> น้องคณะคนหนึ่งถามผมเกี่ยวกับเรื่องนี้ว่า เราจะใช้ spring มาจัดการ config เข้ากับ hibernate โดยสร้างเป็นโปรเจ็กต์เล็กๆได้อย่างไร ในเมื่อตอนนี้เพื่อนๆและตัวผมเองก็ได้ทบทวน spring bean ขั้นพื้นฐานกันไปเรียบร้อยแล้ว (ทบทวนเนื้อหาที่ผ่านมา)

>> ผมจะขอใช้ตัวอย่างจากสองเว็บไซต์ด้านล่างนี้มาประยุกต์เป็นตัวอย่างของเรานะครับ และขอขอบคุณพวกเขาทั้งสองที่แชร์ความรู้มา ณ ที่นี้ครับ
- https://dzone.com/articles/securing-mongodb-part-2-database-access-control
- http://www.journaldev.com/3524/spring-hibernate-integration-example-tutorial-spring-4-hibernate-3-and-hibernate-4

>> เราจะใช้ spring เวอร์ชัน 4.x, ใช้ hibernate เวอร์ชัน 4.x ติดต่อกับฐานข้อมูล mysql และเขียนอยู่บนจาวาโปรเจ็กต์ธรรมดา ทั้งหมดนี้ก็จะเป็นพื้นฐานสู่เรื่องจาวาเว็บ (servlet) และ spring mvc ต่อไป

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

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

>> ส่วน hibernate ก็เป็นความคิดการใช้ ออบเจ็กต์ ซึ่งในที่นี้ก็คือ จาวาบีนธรรมดา เป็นตัวนำพาข้อมูลไปจัดเก็บไว้ยังฐานข้อมูล* โดยตัวมันเองรับประกันว่า** ขั้นตอนการทำธุรกรรมจะต้องเรียบร้อยสมบูรณ์ไม่มีผิดพลาดแน่นอน
* ความคิดการนำพาข้อมูลไปจัดเก็บนี้เรียกว่า Java Persistence API ซึ่งเป็นหนึ่งในข้อกำหนดของเทคโนโลยี JEE
** สิ่งนี้สำหรับ Java Persistence API เรียกว่า Transaction (อ่านเพิ่มเติม...)

>> ฐานข้อมูลผมใช้ mysql ที่ถูกติดตั้งมาพร้อมกับ XAMPP เวอร์ชัน 3.2.2 ดังนั้นผมจึงสร้าง database ด้วย phpMyAdmin โดยตั้งชื่อว่า

spring_hibernate_part_1

ใช้คำสั่ง sql ต่อไปนี้สร้างมันขึ้นมาครับ

CREATE TABLE `spring_hibernate_part_1`.`USER` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(20) NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;

>> โครงสร้างของโปรเจ็กต์ประกอบด้วย 2 layers ดังนี้
- com.pros.example.model สำหรับเก็บจาวาบีนธรรมดา
- com.pros.example.dao สำหรับเก็บจาวาบีนที่มีบทบาทในการพูดคุยกับ hibernate
ส่วน Main.java นั้นเป็นคลาสเริ่มต้นการทำงานครับ ตามรูปด้านล่าง


>> ปกติแล้วเมื่อติดต่อกับ hibernate เราจำเป็นต้องเขียนไฟล์ configuration ในรูปแบบ .xml ขึ้นมา หรือไม่ก็ใช้ java annotation ก็ได้ เพื่อจะบอกแก่ hibernate ว่าฐานข้อมูลของเราคืออะไร (MySQL, Oracle, PostgreSQL ฯลฯ), มันอยู่ที่ไหน (บอกเป็น url), มันใช้ port อะไร (ถ้าเป็น MySQL ค่า default คือ 3306), มี username กับ password ต้องใส่หรือไม่ และต้องใช้จาร์ driver ตัวไหนเป็นตัวขอ connect เข้าไป เป็นต้น ด้วยเหตุนี้ hibernate จึงจะสามารถคุยกับฐานข้อมูลได้ แต่สำหรับงานนี้เราจะไม่บอกกับ hibernate ตรงๆหรอกครับ เราจะบอกให้ spring แทน แล้วให้พวกมันไปคุยกันเองอีกที

>> ขอพูดแบบภาษาของผมนะ ได้ว่า เรา (ในที่นี้คือ Main.java) จะคุยกับ spring จากนั้น spring จะคุยกับ hibernate จากนั้น hibernate จะคุยกับ mysql

>> รายละเอียดของไฟล์ spring_configuration.xml มีดังต่อไปนี้

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

>> นี่คือ Main.java ของผม

- เริ่มจากขอ context จาก spring ในที่นี้ก็คือการสั่งให้ spring อ่านไฟล์ spring_configuration.xml นั่นเอง
- จากนั้นขอ spring ฉีดออบเจ็กต์ UserDao มาให้ ซึ่งแท้จริงคือ UserDaoImpl
- จากนั้นสร้างผู้ใช้มาหนึ่งคน ซึ่งก็คือตัวผมเอง proS พร้อมทั้งกำหนดชื่อให้ผมว่า proSbeginner ผมนี่คือจาวาบีนธรรมดาฮี่ๆ
- จากนั้นเอาผมไปจัดเก็บยังฐานข้อมูลผ่านบริการ save ของ UserDao (ผมถูก persistent ในที่สุด)
- จากนั้นทดสอบเรียกผมออกมาดู (เพื่อนๆอาจลองเขียน save ผู้ใช้เข้าไปหลายๆคนนะ) ผมก็จะกลับมาอยู่ในสถานะจาวาออบเจ็กต์อีกครั้ง

>> จาวาบีน User

- คลาส User นี้จะติดต่อกับตารางในฐานข้อมูลที่ชื่อ USER
- คลาส User นี้มี id ชื่อเดียวกับคอลัมน์ในฐานข้อมูล (คอลัมน์ id) โดยจะเพิ่มค่าเองอัตโนมัติ

>> interface UserDao

- ให้บริการ save นำจาวาออบเจ็กต์ User ไปเก็บไว้ยังฐานข้อมูล
- ให้บริการ findAll คือค้นหาออบเจ็กต์ User ทั้งหมดใส่ไว้ใน list (ชุด java collection)

>> จาวาบีน UserDaoImpl

- เพื่อนๆจะสังเกตได้ว่า บีน ตัวนี้แหละที่เป็นหัวใจ กล่าวคือ spring จะฉีดมันให้กับเราผ่านทาง setter method, มันคุยกับ hibernate แทนเรา (ในแง่การใช้ฐานข้อมูล)

>> และนี่คือรูปผลลัพธ์เมื่อรันไฟล์ Main.java ครับ (ผมทดสอบไปหลายครั้ง)



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

หรือใครอยากจะดูแบบเรียงลำดับชื่อก็ตามนี้


>> คืนนี้นอนหลับฝันดีครับผม

วันอังคารที่ 15 มีนาคม พ.ศ. 2559

ทำไมต้องมี JMS ?

>> คิดเสียว่ามาเล่าสู่กันฟังนะครับเพื่อนๆ ถึงประเด็นที่ว่า ทำไมต้องใช้ Java Messaging Service (JMS) และหากนี่เป็นความรู้เก่าและผิดพลาดประการใด ผมขออภัยด้วยนะครับ

>> Java Messaging Service เกิดขึ้นมาทำไม? คำตอบนี้มักหนี้ไม่พ้นเหตุผลและประโยชน์ที่มันจะสร้างให้กับระบบ (เน้นว่า ระบบ) งานของเรา

>> ผมอยากจะเล่าย้อนไปว่างานหรือโปรแกรมที่เราพัฒนาขึ้นมานั้นต้องได้รับการประมวลผลจาก CPU มันจึงจะทำงานได้ จริงอยู่บางคนก็ว่างานบางอย่างก็ต้องใช้ IO สลับกับ CPU (ไม่ได้ใช้ CPU อย่างเดียว) โอเคผมไม่เถียงเพราะเราต่างก็พูดเรื่องเดียวกันว่า เราใช้ CPU ทำงานงานของเราด้วย สมมติให้เรามี 1 CPU ทำงานทั้งสิ้น 2 งาน เมื่อ CPU ทำงานที่ 1 นั่นหมายความว่างานที่ 2 จะต้องรอให้งานที่ 1 เสร็จก่อนจึงจะทำงานของตนได้ ถ้าเพื่อนๆมีงานให้ CPU ตัวนี้ทำสัก 100 งาน นั่นก็หมายความว่าแต่ละงานจะแซงคิวกันไม่ได้

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

>> กาลเวลาผ่านไปก็เกิดการพัฒนาระบบเครือข่ายคอมพิวเตอร์หรือระบบเน็ตเวิร์ก ไม่เพียงแค่ CPU คุยกับงานของตัวเองในบ้านของตัวเอง ตอนนี้มันมีเพื่อนแล้ว มันมีเพื่อนเป็น CPU ด้วยกันที่กำลังทำงานอยู่ที่ใดๆก็ได้ในระบบเครือข่าย แหม~ล้ำ เพื่อติดต่อสื่อสาร แลกเปลี่ยนข้อมูลและใช้อุปกรณ์ต่างๆในเครือข่ายร่วมกันได้ CPU ตัวเดียวของเรานั้นมันก็คุยเพลินเลยเทียวล่ะ เอาล่ะ สมมติให้เราเป็นบริษัทที่ให้บริการส่วนลดภาษี (สมมติอะไรก็ได้ แบบว่าให้เป็นการบริการลูกค้าในระบบเน็ตเวิร์ก) ใครก็ตามที่มาขอใช้บริการจากเรา เขาคนนั้นก็จะได้ส่วนลดทันที 50 เปอร์เซ็นต์ โอ้แม่จ้าว เศรษฐีทั้งหลายจะแห่มาขอลดภาษีกับเว็บของเราแน่ๆ (เพราะการสร้างรายได้ที่ง่ายที่สุดก็คือการลดต้นทุนหรือจ่ายให้น้อยเข้าไว้) และน้อง CPU ตัวเดียวของเรานี้แหละก็จะต้องทำงานส่วนลดเจ้ากรรมนี้ให้กับผู้ใช้บริการทุกคน เดิมทีงานของมันก็มีให้ทำอยู่แล้วยังต้องมาคำนวณภาษีให้อีก เอาสัก 10 คน แหมจิ๊บๆกุ๊กๆไก่ แร๊บเดียวก็เสร็จกิจ โอเค เอาสัก 1000 คน แหมน้อง CPU นี่เขียนยิ๊กๆเลย แต่ก็รอดมาได้ โอเคจ้า เอาสัก 1,000,000 คน รับรองว่าทำไม่ทันแน่นอน ต้องเข้าคิวแบบว่าทยอยบริการทีละ 1000 คนไรงี้ก็พอจะทำให้เสร็จไปได้ คำถามคือ มันช้าแล้วครับ ต้องมาเกิดคอขวดเนี่ยเข้าประเด็นบริการได้แต่ช้าแล้วครับ

>> ผมขอหยิบคำพูดของพี่ชายผมที่ว่า รถวิ่งบนถนนเส้นเดิมแต่จำนวนรถเพิ่มขึ้นทุกวัน วันหนึ่งรถก็ต้องติดและทยอยกันออกจากสี่แยกไฟแดง สี่แยกไฟแดงที่เกิดขึ้นก็คือระบบคิวหรือเปรียบเปรยว่าเป็นคอขวดนั่นแหละครับ ผมถามง่ายๆเลยว่า ในเมื่อน้อง CPU ทำงานเพียงตัวเดียวไม่ทันกิจจะแก้ไขอย่างไร ก็คล้ายกับถนนที่มีรถติดจะแก้ไขอย่างไร คำตอบนี้ในทางนักพัฒนาพวกเขาก็จะว่า ขยายถนนสิ! คำตอบคือ ถูกต้องค๊าบ! ขยายเลนให้รถวิ่ง รถก็ติดน้อยลง จากที่เป็น 2 เลนก็จะกลายเป็น 3 เป็น 4 เลนไปเรื่อยๆตามปริมาณของรถที่เพิ่มมากขึ้นอย่างต่อเนื่อง เราก็จะทำอย่างเดียวกันกับถนนคือไปซื้อ CPU มาเพิ่ม พูดง่ายๆว่าตั้งเซิร์ฟเวอร์เพิ่ม เป็น 2 เครื่องเป็น 3 เป็น 4 เครื่องตามปริมาณของผู้มาขอใช้บริการ (หรือคำร้องขอจากผู้ใช้บริการผ่านระบบอินเตอร์เน็ต) ที่มากขึ้นอย่างต่อเนื่อง งานต่อไปที่จะงอกก็คือการ deploy โปรแกรมขึ้นสู่เซิร์ฟเวอร์นี่แหละครับ สมมติว่าตอนนี้เรามีเครื่องเซิร์ฟเวอร์ 10 เครื่อง โปรแกรมขอลดภาษีเวอร์ชัน 1.0 ก็จะถูกติดตั้งไว้กับเซิร์ฟเวอร์ทุกเครื่อง พอเราพัฒนาโปรแกรมเป็นเวอร์ชัน 1.1 ก็ต้องเอาไป deploy ใหม่ให้ครบทุกเครื่อง เกิดเป็นกรรมสาม คือ กายกรรม วจีกรรมและมโนกรรม พอเวอร์ชันเปลี่ยนก็จะเข้าสู่วงโคจรเดิมๆที่ต้อง deploy โปรแกรมให้ครบทุกเครื่อง หรือเรียกว่าการเข้าสู่ วัฏสงสาร นั่นเอง

>> สิ่งที่เกิดขึ้นดังข้างต้นเป็นเรื่องของการจัดการข้อมูลข่าวสาร การให้บริการ การใช้บริการผ่านระบบอินเตอร์เน็ตหรือระบบเครือข่ายที่มีกิจกรรมร่วมกันของแต่ละองกรณ์ แต่ละบริษัทมากมายนัก ใครที่เป็นโปรแกรมเมอร์หรือนักพัฒนาจาวาก็จะได้รู้จักกับ J2EE หรือ JEE ก็คราวนี้แหละจ้า แค่ JSP ก็ต้องใช้ JEE แล้วใช่ไหมล่ะ

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

>> นักคิดนักสร้างระบบจึงเสนอว่า เอางี้ดีไหม แทนที่จะคอยซื้อฮาร์ดแวร์มาเพิ่มถ่ายเดียว เอางี้ มาบริหารจัดการงานที่ทำอยู่ทุกวันนี้ก่อนดีกว่า เขาว่า อย่าให้ CPU เดียวมาทำงานทุกอย่าง ให้แยกประเภทงานออกมาก่อน เช่นพวกบริการลดภาษีเนี่ย (ที่ยกตัวอย่าง) ให้เครื่องเซิร์ฟเวอร์หมายเลข 1 ทำเท่านั้น เครื่องที่เหลือให้ไปทำงานบริการด้านอื่นๆ ก็จะเห็นว่า CPU ของเครื่องหมายเลข 1 มีงานให้ทำแค่อย่างเดียวคือคอยบริการการลดภาษี จากเดิมที่สามารถบริการทุกอย่างทีละ 1000 คน เมื่อตัดการบริการด้านอื่นๆออกไป อาจทำได้ 100,000 คนสำหรับงานบริการภาษีอย่างเดียว หรือพูดในทางกลับกันคือตั้งอีกเซิร์ฟเวอร์ขึ้นมาเพื่อจัดการกับงานด้านลดภาษีแค่นั้น งานเดิมที่น้อง CPU ต้องมาแบกรับก็จะลดลงแล้วทีนี้ (เห็นไหมล่ะ เพียงลดต้นทุนหรือตัดรายจ่าย รายได้ก็เพิ่มขึ้น) ลักษณะการแก้ไขปัญหาที่เกิดขึ้นนี้มีศัพท์ที่เรียกว่า Message Oriented Middleware (MOM) หรือเรียกตามความเข้าใจของผม มันก็คือ 'ตัวกลางจัดการ message' ซึ่งมันถูกกำหนดให้เป็นหนึ่งในหลายเทคโนโลยีย่อยที่สามารถทำงานร่วมกันได้ของ JEE

>> มันในที่นี้ก็คือ Java Messaging Service หรือย่อว่า JMS นั่นเองครับ

*** มือใหม่อ่านมาถึงตรงนี้หากเข้าใจบ้างไม่เข้าใจบ้างนั่นถือเป็นธรรมดา JMS น่ะคือความคิดหรือก็คือวิธีคิดในการจัดการการกระจาย message จำนวนมากจากผู้ส่งไปยังผู้รับ มันจึงมี API หรือก็คือคู่มือการใช้งานหรือก็คือแผนที่วิธีติดต่อกับมัน สิ่งเหล่านี้เรียกว่า ข้อกำหนด (แรกเลยก็เป็นเอกสาร เขียนกันในกระดาษนี่แหละ) ที่ท้ายสุดก็นำมาร่างเป็น interface (หมายถึงจาวา interface) ตลอดจนนำข้อกำหนดนี้ไปทำโปรแกรมทางการค้า ตัวอย่างเช่น TIBCO EMS ของ TIBCO, MQSeries ของ IBM เป็นต้น อ้อ แบบที่ให้ใช้ฟรีก็มี เช่น ActiveMQ ของ Apache ไงล่ะ

>> สวัสดี

วันเสาร์ที่ 12 มีนาคม พ.ศ. 2559

ทำความรู้จักกับ JEE part 1

>> JEE คืออะไร?
JEE ย่อมาจาก Java Enterprise Edition แต่ก่อนเรียกว่า J2EE ซึ่งย่อมาจาก Java 2 Enterprise Edition, JEE คือ standard set หรือชุด (เทคโนโลยี) มาตรฐานของฝั่ง server ที่ใช้ภาษา java ในการพัฒนาครับ

>> ประกอบไปด้วยอะไรบ้าง?
JEE ประกอบไปเทคโนโลยีย่อยมากมาย อาธิ
- JavaServer Faces (JSF)
- Enterprise JavaBean (EJBs)
- Java Messaging Service (JMS)
- Java Persistence API (JPA)
- Java API for WebSocket (มีใน JEE เวอร์ชัน 7)
- Contexts and Dependency Injection (CDI)
- Java API for XML Web Services (JAX-WS)
- Java API for RESTful Web Services (JAX-RS) ซึ่งผมเขียนไปบ้างแล้ว ที่นี่
- Java API for JSON Processing (JSON-P)
- และอื่นๆ

>> เพื่อนๆทราบว่างานของจาวาคือหลังบ้านย่อมต้องการเซิร์ฟเวอร์ในการปฏิบัติการ ในเมื่อเราเป็นผู้เริ่มต้นเหมือนกัน ผมจึงขอแนะนำให้รู้จักกับ GlassFish server ครับ
อยากบอกเล่าให้เพื่อนๆทราบว่าโปรแกรมการค้าเชิงพาณิชย์ (แสวงผลกำไร) ที่มีอยู่มากมายรวมถึงเหล่าโปรแกรม open source (ไม่มีเจตจำนงแสวงผลกำไร) ที่มีอยู่ต่างก็อาศัยเซิร์ฟเวอร์ในการปฏิบัติการ (เรากำลังพูดถึงโปรแกรมจาวาอยู่นะ) หนึ่งในเซิร์ฟเวอร์ที่เป็น open source ที่สามารถทำงานงานของ JEE ได้ก็คือ GlassFish (มันเป็นจาวาแอพพลิเคชันเซิร์ฟเวอร์ตัวแรกเลยที่สามารถทำงานกับ JEE เวอร์ชัน 7) นอกจากนี้ยังมีเซิร์ฟเวอร์ open source อื่นอีก เช่น WildFly (แต่ก่อนเรียกว่า JBoss) ส่วนบริษัทขนาดใหญ่ที่ต้องใช้โปรแกรมจาวาอย่างหนัก (อาจมีทีมพัฒนาเองหรือซื้อโปรแกรมสำเร็จรูปมาก็ได้) ซึ่งยินดีจ่ายเงินซื้อจาวาเซิร์ฟเวอร์ราคาแพง เราเรียกจาวาเซิร์ฟเวอร์ดังกล่าวว่า Commercial application server ที่มีชื่อดังๆเท่าที่ผมรู้จักได้แก่ Oracle WebLogic, IBM WebSphere เป็นต้น (เพื่อนผมคนหนึ่งบอกว่าบริษัทที่จะใช้ commercial application server ได้นั้น อย่างน้อยๆต้องมีทุนหมุนเวียนหรือมูลค่าบริษัทกว่า 1000 ล้านบาทขึ้นไป ฟังแล้วตกใจ)

>> หนังสือรวมที่ผมอ่านอยู่นี้บรรจุเนื้อหาของปี 2014 ค่อนเข้าปี 2015 เดี๋ยวนี้ปี 2016 แล้ว นั่นหมายความว่าเทคโนโลยีมีการพัฒนาที่ไม่หยุดยั้งและรวดเร็ว ป่านฉะนี้มันเวอร์ชันอะไรกันแล้วไม่รู้ มีความสามารถเพิ่มขึ้นอย่างไรแล้วหาทราบไม่ ก็ต้องตามไปอ่านรายละเอียดกันอีกที ดังนั้นขอแบบคร่าวๆแล้วกันว่าแต่ละเทคโนโลยีที่ได้บอกกล่าวไปข้างต้นเขาใช้ทำอะไรกันบ้าง หรือมันมีประโยชน์อย่างไรกับเราบ้างนั่นเองครับ

>> JavaServer Faces (JSF)
- JSF คือ MVC web framework ครับ (เฟรมเวิร์ก คือ ระบบวิธีคิดที่ออกแบบมาเพื่อแก้ปัญหาอะไรสักอย่าง, MVC ก็เป็นระบบความคิดที่ต้องการแยกการทำงานของโปรแกรมส่วน business logic (อาจแยกไปใส่ไว้ใน Model) ออกจากส่วนแสดงผล (View) และมีคนกลางหรือผู้ยิ่งใหญ่คอยบงการความสัมพันธ์ระหว่าง model กับ view คนกลางนี้ก็คือ Controller) JSF ช่วยลดความยุ่งยากในการสร้าง user interfaces (UI) และให้ความสำคัญกับการนำ UI กลับมาใช้ใหม่ (reusable) ในเพจใดๆครับ อ่านต่อที่นี่
- เข้ากันได้กับ HTML5 ด้วยนะ (HTML5 friendly markup)

>> Java Persistence API (JPA)
- JPA คือ เทคโนโลยีที่ว่าด้วยวิธีการใช้คลาสและพฤติกรรมของคลาส (ง่ายๆว่าใช้คลาส) เพื่อที่จะนำข้อมูล (ผ่านทางคลาส) ปริมาณมาก (มากๆๆๆ) ไปจัดเก็บยังฐานข้อมูลโดยสะดวกแฮ มันถูกจัดตั้งหรือคิดขึ้นโดยบริษัท Oracle อ่านต่อที่นี่
- JPA ถูกรวมเข้ากับ JEE ตั้งแต่เวอร์ชัน 5 ความคิดของการใช้คลาสในทางจาวาคลาสก็ถูกทำให้เป็นมาตรฐานและ third-party object relational frameworks (มือที่สามหรือก็คือเจ้าอื่นที่ไม่ใช่ Oracle) ก็เกิดขึ้นโดยพวกเขาได้ implement ความคิดของและวิธีการนี้จาก JPA API, third-party object relational frameworks ดังกล่าวได้แก่ Hibernate, JDO เป็นต้น
- หากยังมองภาพการใช้ JPA ไม่ออก ขอแนะนำตัวอย่าง (Hibernate) จาก http://na5cent.blogspot.com/ ครับ

>> ไว้เท่านี้ก่อนนะครับ ผมกับคุณเธอกำลังจะไปวิ่งออกกำลังกายกัน ไว้มาเล่า (แอบทบทวนด้วย) ให้ฟังใหม่นะ

วันศุกร์ที่ 11 มีนาคม พ.ศ. 2559

Spring part 10-2 Bean Scopes

>> เรื่องขอบเขตของบีนที่ผมกำลังจะเล่าให้ฟังนี้ก็มาถึงตัวสุดท้ายกันแล้วสำหรับ spring bean ขั้นพื้นฐาน (เพราะยังไม่ลุย spring web) นั่นก็คือ prototype scope ซึ่งต่างจาก singleton scope ตรงที่ว่าเราจะได้ออบเจ็กต์ใหม่ต่อหนึ่งครั้งที่ร้องขอเสมอครับ หรือง่ายๆว่ามันตรงข้ามกับ singleton scope นั่นเอง

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


>> และนี่คือ prototype scope ที่กำหนดโดย java annotation ผมก็ใส่ไปอย่างนี้ และผลที่ได้ก็เป็นดังรูป


สรุปคือ เราได้ออบเจ็กต์บีนใหม่ทุกครั้งที่ขอเลยครับ (เลข address ต่างกันไง)

>> เนื่องจากว่ารูป xml ข้างต้นไปเอามาจากแหล่งอื่น ก็ต้องให้เครดิตเขานะครับ แล้วเว็บของเขาก็เขียนเอาไว้ดีมากเลย (มีตัวอย่างประกอบด้วย) จึงขอหยิบยกเนื้อหาที่เกี่ยวข้องกันกับเรื่องของเราจากเว็บของเขาดังนี้
- จาก http://www.mkyong.com/spring/spring-bean-scopes-examples/

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