Pages

แสดงบทความที่มีป้ายกำกับ java แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ java แสดงบทความทั้งหมด

วันอังคาร, ตุลาคม 08, 2556

[Java] 5 วิธีเขียน Code ให้อ่านง่าย

ช่วงนี้สำนวน แนวๆ "ทุบกำแพงเจอไททัน" ค่อนข้างจะได้ใช้บ่อยเนื่องมาจากที่ออฟฟิศกำลังพยามเอา TDD มาใช้ แต่ด้วยโครงสร้างของโปรแกรมที่พัฒนามาอย่างน้อยๆ ก็เกือบ 10 ปี เลยทำให้เกิดอาการของหายของพังไปบ้าง ครั้นจะเขียนใหม่ทั้งหมดก็แลดู over power มากเกินไป ... เลยแวปมาเขียน blog สั้นๆ เกี่ยวกับวิธีเขียน code ให้อ่านง่ายๆ ไว้หน่อยดีกว่า

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

1. อย่า code ถ้า Test ไม่ได้ ... กฎเหล็กอันหนักหน่วง ที่บางทีก็แอบแหก .... แต่ต้องเข้าใจว่ามันเป็นวิธีที่ดีที่เราควรคำนึงถึงการ Test ก่อนลงมือแก้ไขอะไรลงไป เพราะจะทำให้เราเข้าใจได้ว่า ถ้าเราจำเป็นต้องใช้ code นั้นในกรณีอื่นๆ เราจะมีชีวิตที่ดีขึ้นหรือไม่ สิ่งที่เขียนไปแล้วจะมีคนด่าลับหลังเหรอเปล่า ....

2. อย่าทำลาย Law of Demeter - จริงอยู่ว่า ในวงปาร์ตี้ที่เราจัดขึ้นโดยชวนผองเพื่อนมาร่วมงาน เราสามารถคุยกับทุกคนที่เข้ามาในปาร์ตี้ได้ แม้ว่าคนๆ นั้น จะเป็น เพื่อนของเพื่อนของเพื่อน ก็ตาม ... แต่ในเนื้อแท้แล้ว เราจะรู้จักคนๆ นั้น ได้ก็ต่อเมื่อ คนที่รู้จักเราพาเค้ามาในงานเท่านั้น ... เราจึงไม่ควรมีความสัมพันธ์กับคนๆ นั้นโดยตรงจนกว่าจะมั่นใจได้ว่า เราจำเป็นต้องรู้จักเค้าจริงๆ

3. จิตใจโลเลอย่าใช้ static - อันตรายมากสำหรับการใช้ static หากจิตใจไม่มั่นคง ... โลกคงจะปั่นป่วนไม่ใช่น้อยหากพระอาทิตย์ไม่ขึ้นทางทิศตะวันออกเสมอ ....

4. interface over subclass - อยากได้ "ยาม" อย่าจ้างลูกของ "ยาม" ควรจ้าง "ยาม" ไม่ใช่ลูกของคนที่เคยเป็น "ยาม" มันย้อนแย้งในหน้าที่ เพราะเราต้องการ "ยาม"  

5. Given When Then - วิธีเขียนโปรแกรมให้ง่ายที่สุดคือการคิดแบบเป็นระบบ input / process / output ... พื้นฐานง่ายๆแต่ตีความได้ลึกซึ้ง ... การใช้ Given when then ก็เป็นการขยายความเพื่อให้เราคิด logic ในการเขียนโปรแกรมให้ถี่ถ้วนก่อนลงมือทำจริงทำให้เราตอบสนองกับ scenario ที่คาดไม่ถึงได้

แลดูค่อนข้าง abstract แต่คิดว่าแค่ห้าข้อนี้น่าจะทำให้ชีวิต Java Dev อย่างเราๆ ท่านๆ สะดวกสบายมากยิ่งขึ้นครับ




วันอาทิตย์, กุมภาพันธ์ 24, 2556

[Blog] Java ดราม่าสำเร็จรูป ?


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

เคยออกตัวไว้ใน Blog เก่าๆ นานแล้วว่าใช้ Java เพื่อทำมาหากิน
และ Oracle ไม่ใช่พ่อ ดังนั้น ไม่มีเหตุผลอะไรที่ต้องเขียน "อวย" 
แต่ด้วย ปัญหาสุดฮอต เรื่อง Java โดนเจาะในตอนนี้ 
ในฐานะ Software Developer ที่ทำอยู่กับ Java
สิ่งที่ควรนำเสนอก็ ควรจะเขียนแบบไม่ Bias
มากกว่า "เลิกใช้มัน ไปใช้อย่างอื่นเถอะ" ซึ่งฟังแล้วดูเหมือน

Java เป็น Death Star ส่วน Oracle เป็น Dart Vader 
( ส่วนสาวกจะเปรียบดั่ง เสื้อแดง ปะทะ เสื้อเหลือง ก็มิปราณ ....  )
 
Java พรุนส์ จริงหรือ ? 
ว่ากันด้วยสัจธรรมของ Software Development  ที่ว่า
"ไม่มี Software ใดที่ไม่มี Bug"  ...
Java ก็เช่นกัน แต่ถ้าตามอ่าน Oracle Securiy Alert เป็นประจำ
หรือ ศึกษาที่มาของปัญหา ก่อนที่จะเอา Emo มาบรรเลงบน Keyboard
จะพบว่า การโดน"เจาะ" หนักๆ ที่ค้นพบจะกระทบ ...

issues CVE-2013-0422 (US-CERT Alert TA13-010A - Oracle Java 7 Security Manager Bypass Vulnerability) and another vulnerability affecting Java running in web browsers. These vulnerabilities are not applicable to Java running on servers, standalone Java desktop applications or embedded Java applications. They also do not affect Oracle server-based software.
นั่นหมายความว่า จะกระทบเครื่อง Server ที่เป็น Java ได้ก็ต่อเมื่อ
มี Developer รู้เท่าไม่ถึงการไปเล่น Web Browser แล้วเปิดเวปที่มี Vulnerability
บนเครื่อง Server ...  เท่านั้น ซึ่งก็ดูจะ Non-Sense มากกับองค์กรนั้นๆ
ที่ให้ Developer ไปเล่น web ที่มีโอกาสโดน attack บน Server ที่สำคัญๆ

ในเรื่องของความปลอดภัยระดับ end-user
โดยปกติ ถ้าหาก "กังวล" กับเรื่อง Security มากมาย
ก็ควรจะปิดทุก plug-ins บน Web Browser อยู่แล้ว
แต่ทำไงได้หากจำเป็นต้องใช้ Plugins ?

JRE รุ่นใหม่ๆ ก็มีระบบ Security เพียงพอ ที่จะ Acknowledge
ให้ user รู้ว่า " จะรัน Java ที่ไม่ Trust แล้วนะ บน Web Browser จะอนุญาต หรือเปล่า ? "


ซึ่งถ้าจะ impact กับระดับ end-user ได้นั้น
คงไม่พ้น user ที่ไม่คิดจะอ่านอะไร / ไม่คิดจะ update security
แล้ว ติด malware จาก web กระจาย ไม่ต่างกัน

Java ค้างส์ จริงหรือ ? 
วาทกรรมนี้ เป็นวาทกรรมที่ Bias แบบสุดติ่ง
เหมือนเราขับรถชน แต่ดันไปโทษ แก๊สโซฮอล์

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

Java ใช้ทรัพยากรเครื่องเยอะ จริงหรือ ?
เยอะจริง ... เพราะมันเป็น "Java Virtual Machine"
แต่เคยมองกลับกันไหมว่า หากเราเปิด window ใน osx หรือเป็น linux บน window
สิ่งเหล่านั้นก็เป็น Virtual Machine เหมือนกัน
ทำไมเราถึง "ยอม" ให้ VM เหล่านั้น ใช้ทรัพยากรเครื่องได้เยอะๆ แต่กับ Java ไม่ได้ ?


สรุป

ในมุมของ Software Development มักจะมีคำพูดเสมอว่า
"ขึ้นอยู่กับการใช้งาน"
แม้ว่า java จะไม่ปลอดภัยในระดับ end-user
แต่มันก็มี workaround และ Knowledge Management
ที่สามารถสื่อสารให้ end-user เข้าใจ และ ระมัดระวังได้ดีกว่า
การบอกให้เลิกใช้ โดยยกแม่น้ำทั้ง 5 ว่า คนนั้น คนนี้ Evil ....

อาห์ ดูจะปกป้องมากเกินไปหรือเปล่า ...
แค่นี้ดีกว่า อุอิ




วันอาทิตย์, พฤศจิกายน 13, 2554

Play Framework ของเล่น code ไม่เล่น

หลายๆครั้งที่มีความพยายามจะทำ Legacy Code มาให้เป็น Web Application แต่ก็ล่มไปหลายครั้ง
อันเนื่องมาจากการที่จะทำ Prove Of Concept ให้ได้ Productivity ที่สูงๆนั้น
จำเป็นที่จะต้องมีเครื่องมือที่ดี และ framework ที่ดี เพื่อที่จะได้ output นั้นมาได้  ...

ก็ใช้เวลาหามาเกือบปี เลยได้ Play Framework มาใช้ครับ ...

ชื่อของ Play Framework อาจจะดูแปลกๆ ... เหมือน framework ที่เขียนขึ้นมาเล่นๆ
แต่พอมาดู feature แล้ว ไม่ใช่ของเล่น แบบชื่อของมันครับ

Concept หลักๆ ของ Play Framework อาจจะดูใหม่สำหรับ java แต่จริงๆ แล้ว
ตัว folder structure ของ framework นั้นแทบจะลอก Ruby มาเต็มๆ ...
Highlight หลักๆ คือสิ่งที่ต่างจาก J2EE Framework ทั่วๆไป ดังต่อไปนี้ครับ


  • ไม่มี Page / Session / Application Context ให้ปวดหัว ...  ทุกอย่างเป็น Stateless โดยเก็บข้อมูลทุกอย่างในรูปแบบของ cached ทำให้สามารถทำ distribute system ได้สบายๆ
  • Build-in Template System ถ้าเคยใช้ Taglib ใน J2EE ก็น่าจะไม่มี Learning Curve สูงนัก
  • Full-Stack Framework ในความหมายคือ  พร้อมรันเป็น server โดยไม่ต้องพึ่งพา Application Container
  • Build-in Unit Test ถึงขี้เกียจแค่ไหน ก็สามารถเขียน Unit Test ได้ไม่ยากนัก
  • Request-to-POJO Transformation ไม่ต้องมาเหนื่อย map Request.getAttribute( ... ); มาเป็น POJO เอง Framework สามารถทำให้ได้ทันที
  • POJO-to-JSON และ POJO-to-XML ได้ทันที (มี lib อยู่แล้ว)
  • และที่สำคัญเป็น Asynchronous Call ที่เหมาะสำหรับทำ RESTful Service ที่กำลังเป็นที่นิยมขณะนี้ 

นับว่าหายากสำหรับ java framework ที่จะมี feature ตามภาษาอื่นได้ทัน ในขณะนี้ ....
แต่ที่เป็นจุดอ่อนสำคัญของ Play Framework คงหนีไม่พ้น  Security Authenticate
ที่ค่อนข้างหา reference ได้น้อยมาก(มีอยู่แต่ใน google group) ต้องรอดู Play Framework 2.0 ครับ
ว่าจะออกมารูปแบบไหน

วันอาทิตย์, ตุลาคม 09, 2554

JavaOne 2011 : Road Map ที่จะเกิดขึ้น


นานๆ ที กว่าจะได้เห็น Oracle เปิด Free Session ให้ดู ....
เลยต้องเขียนสรุปกันลืมไว้หน่อยครับ .....

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

หลักๆ แล้ว Keynote Style Oracle จะค่อนข้างขายของพอสมควร ...
ดูสรุป JDK7 ได้ที่นี่ครับ



ใครๆ ก็คิดว่า Oracle ซื้อ Java มาดองเค็ม ...
แต่หลักจากฟัง Guest Speaker มาบรรยายใน Session KM
ทำให้รู้ว่าจริงๆ แล้ว สิ่งที่ Oracle พยายามขายไม่ใช่เพียงแค่ Software
แต่เป็น Knowledge ด้วยตังหาก ...

ทีนี้ แล้ว JDK RoadMap จะเป็นยังไง ?

JDK RoadMap


แอบดีใจว่า JDK7 จะไม่โดนลากไป 27 update .... แต่มันแค่เรื่องอนาคตก็ต้องรอลุ้นต่อไป lol
จุดที่หน้าสนใจสำหรับ JDK7 คือ Project Coin , Invoke Dynamic ( ใช้กับพวก JRuby, Nashorn ) , และ Fork/Join Framework

ซึ่งโดยรวมก็ถือว่า สิ่งที่เพิ่มขึ้นมาทำให้ เขียน code ได้ง่ายขึ้นเยอะ ... ที่น่ารอคงไม่พ้น Lambda ที่เพิ่มให้ Java สามารถเรียก dynamic method แบบ functional language ได้ ก็ต้องร้องเพลงรอกันต่อไป  ....

JavaFX Roadmap



สำหรับคนที่คาดหวังกับ Swing Replacement  ของ Java
อาจจะผิดหวังไปแล้วสำหรับ  Webview   ... javaFX จึงไม่ได้ตอบโจทย์
สำหรับคนที่ต้องการ Cross Platform ระหว่าง Web กับ Desktop  เท่าไหร่นัก
(เพราะมันออกแบบมาเพื่อเป็น Desktop แต่ deploy บนเวปได้แค่นั้น)

แล้ว Oracle จะตอบโจทย์ HTML5 ให้กับ Java ได้ยังไง ....
นั่นคือ ...


AVATAR !!!





แต่เหมือนจะมาช้าไปหนึ่งเก้าทุกทีสำหรับ java .... เพราะตอนนี้ก็ยังเป็นวุ้น
เช่นเดียวกับสมัย javaFX ที่ Adobe เริ่มมี Flex , Microsoft เริ่มมี silverlight ไปเป็นที่เรียบร้อยแล้ว ...


ก็ยัง งงๆ กับ สิ่งที่ Oracle คิดอยู่ ว่ายังมองว่า Desktop App กับ Web App ยังไม่ควรเป็น​ Application เดียวกัน ?? ก็คงต้องติดตามต่อไปว่า แนวคิดไหน จะดีที่สุด ครับ :)

โดยสรุป .... Oracle งานงอกขึ้นมาอีก 1 stack  ที่จะเอาไว้ชนเรื่อง HTML5 กับเจ้าอื่น ....

แต่ทั้งหมดเป็นเรื่องของอนาคตครับ ต้องรอดูต่อไปว่าจะเป็นยังไง
เพราะ Technology เปลี่ยนแปลงบ่อย ...


วันอังคาร, มิถุนายน 28, 2554

Native Swing ... อุดจุดบอด ให้ Java Desktop


พอดีไปรับอาสา Coaching ให้กับเด็ก interns ฝั่ง London ของที่ออฟฟิศ
เลยได้ของเล่นมาเล่นเยอะแยะมากมาย ... ไม่ว่าจะเป็น JavaFX หรือแม้แต่ SWT ...

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

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

เข้าเรื่องเลยดีกว่า ...
ตั้งแต่ทำ java desktop มาจะเกือบ 3 ปีได้ ... ก็เจอจุด pain หลายๆ อย่าง ...
ไม่ว่าจะเป็น code เมพ ... design แหล่ม ... หรืออะไรก็แล้วแต่ ...
สิ่งที่เป็นจุดบอดสำคัญๆ ของ java desktop คือ ยังเป็น UI ยุคเก่า ....
ที่แม้ชาวบ้านจะทำ Graphic เป็นระดับ HD ไปแล้ว ... java ก็ยังวิ่งอยู่ระดับ pixel ต่อไป ...

แต่หลังจากได้ coaching เด็ก interns ก็พบว่ายังมีบาง Lib ที่ไม่เคยคิดจะเข้าไปยุ่งกับมัน ...
มีความสามารถพอที่จะช่วยให้ java คลานต่อไปได้อีกหน่อย นั่นคือ SWT ...


SWT คือ UI toolkit อีกชุดของ java ที่พัฒนาโดย .. IBM ...
หลักๆ ของ SWT ที่แตกต่างจาก AWT คือ SWT จะพยายามทำทุก component ของ Java
ให้เป็น Native Component ... โดยผ่าน JNI ... ข้อดีข้อเสียของมันเป็นดังเหมือนดาบสองคม
นั่นคือ .... ดีที่เร็วส์ ... แต่เสียที่ไม่ cross platform (หรือพูดง่ายๆว่าต้องมี for window , for linux )

จึงเป็น Lib ข้าวนอกนา ในสายตาของคนที่วิ่งอยู่บน Standard JDK มาก ....
ซึ่งการรัน SWT พร้อมกับ Swing นั้นค่อนข้างที่จะบาป ยิ่งกว่าการเขียน AWT ผสมกับ Swing ..
เพราะ Thread ที่ใช้ ในการ render component นั้น จะแยกกันทำงาน ทำให้ยากต่อการ debug มาก ...

แต่ทั้งหมดนั้น ... เป็นเรื่องที่เกิดขึ้นเมื่อ 10 ปีที่ผ่านมา ....
ในวันนี้ มีคนหัวใส เขียน Bridge ระหว่าง SWT และ Swing ขึ้นมา ชื่อว่า Native Swing

คร่าวๆ เกี่ยวกับ Native Swing คือเป็น wrapper ที่ Bridge ระหว่าง Swing กับ SWT
และ SWT กับ Window Native โดยใช้ OLE Bridge อีกต่อนึง .... (เหมือนเขียน VB เรียก ActiveX)
ทำให้สามารถ integrate SWT Component ที่มีอยู่แล้ว ขึ้นมาใช้ได้ใน Swing App ปกติ ...
ที่น่าสนใจของ Library ตัวนี้ ก็คือ SWT Component อันได้แก่

JWebBrowser

ไว้สำหรับ embed Browser ลงใน Swing App ... ที่ครั้นจะรอ JavaFX ก็คงอีกนาน
(แม้ Beta version ออกมาก็ยังกาก เกินกว่าจะเทียบ native ได้ )
ข้อดีของ component ตัวนี้คือ เป็นการดึง Native Feature ของ IE มาใช้ ....
ดังนั้น หากเครื่องที่ลง IE9 ไว้จะพบกับความเร็วส์ ในการโหลด ตามประสิทธิภาพของ IE
พร้อมทั้งอาจจะเจอความห่วย ในรุ่นเก่าๆ ลงมาไปพร้อมกัน ..... ซึ่งหากไม่พอใจ
ก็สามารถใช้ XULRunner ของ Firefox มา embed แทนได้ ....
แต่ package application ก็จะมีขนาดใหญ่ขึ้น ตามขนาดของจิ้งจอกไฟ ...

 

ตัวต่อมาคือ

JFlashPlayer 

เป็น component ที่ดึง Flash ActiveX มาใช้ได้อย่าง ... เนียนมาก ... เนียนจนขนาดที่
สามารถทำ bridge กลับระหว่าง Java กับ Flash ได้ .... ซึ่งหากใครที่มองว่า Java Desktop
เป็น UI ล้าสมัย ... ก็สามารถทำ Flash มาต่อกับ API ที่มีอยู่เดิมให้มีลูกเล่นเพิ่มเติมได้มากขึ้น
ทั้งนี้ ก็ขึ้นอยู่กับ code ของ project นั้นๆ ว่ามีความ messy เพียงใด (ฮา)


มีหลาย component มากขี้เกียจรีวิวเยอะ เอาตัวสุดท้ายแล้วกัน ...

JMediaPlayer 

แทบน้ำตาไหลสำหรับ video player ที่สามารถเล่นบน java ได้ ...
ซึ่ง Lib นี้ก็มี bridge ให้ใช้กับ VLC ได้อีกเช่นกัน ...



สรุป
แม้ว่า SWT จะทำได้หลายอย่างโดยที่มี Native Swing เป็นตัวจัดการให้กับ Swing
แต่ทั้งนี้ก็ขึ้นอยู่กับว่า Feature ที่เป็น native นั้นๆ สามารถรองรับความต้องการของลูกค้า
รวมไปถึง time-to-market ได้ดีแค่ไหน .... และที่สำคัญคือ ...
License ในการ distribute เป็นอย่างไร ....
การทำ commercial app ที่มีลักษณะเป็น product ... ยากกว่าที่คุณคิดเยอะ ...

วันจันทร์, เมษายน 11, 2554

Vavar ปะทะ Java Swing #5 : Component Painting

จาก ตอนที่ 4 ที่ได้พูดถึง EDT และ Swing MVC ไปแล้ว

ในตอนที่ 5 นี้เลยจะพูดถึง Painting ครับ

ประกาศ : บทความเหล่านี้เขียนด้วยความคิดเห็นของตัวเองล้วนๆ ... 
ผิดถูกยังไง สามารถเสนอแนะโดย post comment ด้านล่างได้ครับ :)




Swing Component หรือแม้แต่  AWT Component ใน Java นั้นสิ่งที่จำเป็นมากๆ
ในการออกแบบ UI ก็คือการทำ Custom Paint ที่ให้ LookAndFeel  ของตัว Component นั้น
เป็นอย่างที่เราได้ออกแบบไว้ ... โชคร้ายของ AWT Component ที่ ​Java ไม่ได้ออกแบบตรงจุดนี้มาให้
โดยให้เหตุผลว่า AWT เป็น Heavy Weight Class ที่ออกแบบมาให้เป็น Native Component ของ OS นั้นๆ
การจะปรับเปลี่ยน LookAndFeel สำหรับ AWT จึงไม่ใช่ทางออกนัก ....

แต่ก็เป็นโชคดีสำหรับ ​Swing Component ที่ Sun ทำ LookAndFeel Architecture มาให้ใช้
โดยตัว Swing เองอย่างที่เป็น Sequence Diagram ในตอนที่ 4 จะเห็นว่า
JComponent ทั้งหลายเปรียบเสมือน Controller เท่านั้น ส่วนที่เป็น View คือส่วนที่เป็น UI Class
ที่ฝังอยู่ใน LookAndFeel ....

ข้อดีของการแยก Class ดังกล่าวทำให้เราสามารถปรับเปลี่ยนหน้าตาของ UI
โดยไม่กระทบกับ Behavior ที่มีของ Component นั้นๆ ได้ ....
ยกตัวอย่างเช่น

ปุุ่ม .....
หน้าที่ของปุ่มคือรอรับ event การ click โดยจะ click ซ้าย หรือ ขวา ก็ขึ้นอยู่กับ
manage code ที่ทำการตอบรับ action นั้น

แน่นอนว่าหากการเปลี่ยน UI แล้วกระทบกับ Behavior ดังกล่าวดูจะแปลกๆ
ตั้งแต่ลักษณะการ Design ของ Behavior ก่อนหน้านี้แล้ว ....

การ Paint บน Swing Component จึงได้เปลี่ยนการทำงานใหม่ที่แตกต่างไปจาก AWT Component
ที่มีการเรียก paint() method แล้วทำการวาด Component ทั้งหมด

ใน Best Practice ของ Swing Component แนะนำว่าหากต้องการทำ Custom Paint ที่ไม่ขึ้นกับ
LookAndFeel ก็สามารถทำได้โดยการ override paintComponent() (ไม่มี s) method เพื่อให้สามารถ
แสดงผลได้อย่างที่เราต้องการ .....

สิ่งที่สำคัญสำหรับการ paint ใน Swing Component คงจะหนีไม่พ้น 3 สิ่งดังต่อไปนี้

1. Opaque - การแสดงผลแบบ Transparent Background.
2. Border - ขอบของ Component ที่ต้องการให้แสดงผล
3. Inset -  ขอบช่องว่างที่ต้องการให้แสดงผล มักจะถูก set จาก Border

ซึ่งหากเปรียบเทียบกับการเขียน CSS ทั้งสามส่วนนี้คงหนีไม่พ้น คำสั่งดังต่อไปนี้

1. background:
2. border:
3. padding:

จะเห็นได้ว่าจริงๆ แล้ว Component ของ Swing นั้นก็ไม่ได้แตกต่างจาก
การเขียน HTML เท่าไหร่นัก เพียงแต่การใช้งานจะต้องมีการจัด layout
เพื่อให้ได้รูปแบบตามที่เราต้องการ ได้ยากกว่าเท่านั้นเอง ...
แต่โชคร้ายของ Swing Component ที่ Sun ออกแบบมาไม่ดีนัก
ที่ระบุให้ Border เป็น Component ที่ถูกวาดหลังสุด ทำให้การที่เราจะทำ
Component ที่มีขอบ ตามประเภท Border ที่เรา assign ให้กับ Component นั้น ยากมาก
ซึ่งจะต้องหาวิธีมาประยุกต์ใช้เพื่อทำงานในลักษณะดังกล่าว ...

ทำให้มี trick มากมายในการประยุกต์ใช้เพื่อให้ได้รูปแบบตามที่เราต้องการ ....

โดยส่วนตัวคิดว่าไม่ค่อยดีนักสำหรับ การ open ให้ implement เยอะขนาดนี้ เพราะหาก
Developer ไม่สนใจที่จะอ่าน Architect ของ Swing จะทำให้การ ​Manage sourcecode นั้นลำบากมาก
ด้วยอายุของ Swing Toolkit ก็ปาไปเกือบ 10 ปี แล้วจึงคิดว่า javaFX น่าจะมีอะไรเปลี่ยนแปลง
ในจุดนี้ไม่มาก ... ก็น้อย ....

แต่ชีวิตก็ยังต้องดำเนินต่อไป  .... ไปเขียน silverlight ดีกว่า ๕๕๕

วันพุธ, มีนาคม 02, 2554

Vavar ปะทะ Java Swing #4 : EDT + MVC

มาถึงตอนที่ 4 ขอแอบบ่นขั้นเวลาหน่อยครับ ...

เป็นธรรมดาที่เวลาเขียน Application ใดๆ ก็ตามที่ต้องมี User Input  ...
สิ่งที่ต้องตามมาก็คือ User Interface ... แน่นอนว่า คงไม่มีใครอยากเขียน code เยอะๆ ...
เพื่อแสดง power แน่นอน ... แต่สิ่งที่ต้องมาคู่กับการ Design User Interface นั้น ...
จำเป็นที่จะต้องสนใจ input + output ของ process นั้นๆ ด้วย ....
เพราะหากเราคำนึงถึงเพียงแค่การแสดงผล ให้กับ user บนหน้าจอ คงจะไม่ถูกต้องนัก ...

มีตลกร้ายอยู่เรื่องนึง สมัยทำ Web Application เมื่อนานมาแล้ว
ด้วยความที่ Web Application นั้น เป็นการทำ Document Management System...
สิ่งที่สำคัญในระบบนั้นคือ

การเก็บเอกสารที่สามารถค้นหาให้ได้ง่ายที่สุดเท่าที่จะทำได้ ...

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

และสิ่งที่ไม่คาดฝันก็เกิดขึ้น ... อาจจะเพราะด้วย Design ที่ไม่คำนึงถึง Concurrent ที่เกิดจาก
การ input มาจากหลายช่องทาง ( Multi-User ) จึงทำให้ Index Repository ... ล่มสลาย ...
ต้อง ทำการสร้าง index ให้กับเอกสารที่นำเข้าไปแล้วใหม่ทั้งระบบ ... เจ็บกันไป ...

นี่คือตัวอย่างของการคิดแบบง่ายๆ ที่เกิดขึ้นจากการออกแบบ ที่ไม่ได้คำนึงถึง concurrent
ที่เกิดขึ้นในระบบ ... วิธีแก้ มีหลายวิธี ไม่ว่าจะเป็นการทำ Thread Queue หรือแม้แต่การแยก
Indexing Service ไปไว้ในการทำงานทีหลัง ... เท่านี้ก็จะสามารถทำให้ระบบมีประสิทธิภาพมากขึ้นได้ ...

ในการทำ UI ใน Java ก็เช่นกัน ... ใน Java Desktop จะมี Thread อยู่ตัวหนึ่่งที่ชื่อว่า

Event Dispatcher Thread 

หรือที่เรียกสั้นๆ ว่า EDT .... ในส่วนของ EDT นี้ จะเกิดขึ้นทุกครั้งที่มีการส่ง
Event ที่เกิดขึ้นจาก User Input ที่เกิดขึ้นกับ UI ไปหา Listener ที่เราทำการ Add ไว้อยู่ทั้งหมด ...
ซึ่งการเขียน Listener จึงต้องมีความระมัดระวังในการเขียนค่อนข้างมาก เนื่องจากว่าเราจะต้องรู้
"พฤติกรรม" ที่ Listener นั้นๆ จะได้รับ เมื่อเกิดเหตุการณ์ XX , YY , หรือ ZZ เพราะไม่เช่นนั้น
การใส่ Listener เยอะๆ ไป จะทำให้เราไม่สามารถ กำหนดต้นทางของข้อมูลได้เลยว่า มาจากจุดไหน
หรือแม้แต่กำหนด "พฤติกรรม" ที่เราต้องการจะทำได้

ยกตัวอย่างเช่น

ItemListener กับ ActionListener

สิ่งที่แตกต่างกัน ระหว่าง Listener 2 ตัวนี้คือ ...

ItemListener จะทำการ detect ทุึกครั้งเมื่อ Item State นั้นมีการเปลี่ยน  ....
การเปลี่ยนในที่นี้หาก Component ที่ต้องการเพิ่ม Listener นั้น มีเพียง 1 Item ..
เราก็สามารถ trigger Event นั้นได้อย่างง่ายดาย เช่นเดียวกับ ActionListener ที่มีการ "กระทำ"
กับ Component นั้นๆ แต่เมื่อ Component นั้นมี Item มากกว่า 1 items ... สิ่งที่เกิดขึ้นตามมาก็คือ

Item State Event จะถูกส่งมา 2 ครั้ง นั่นคือ

1. Item เก่า ถูก Deselect
2. Item ใหม่ ถูก Select

ซึ่งถ้าเราเขียน code ตรงจุดดนี้ไม่ดี ... หรือการส่งค่า input บางอย่างไปยัง ฐานข้อมูล
ก็จะทำให้เกิด Duplicate Record ได้ง่าย .... ซึ่งจะแตกต่างจาก ActionListener ที่
เราต้อง Handle เพียง 1 Event วิธีแก้ไขง่ายที่สุดคือ
"เลือก implement Listener เฉพาะพฤติกรรมที่เราต้องการ"

การทำงาน ใน EDT ก็ยังมีความต้องระวังอีกจุดหนึ่งนั่นคือ
การนำ "Long-Session Process" ไปประมวลผลใน EDT .... ยกตัวอย่างเช่น
การที่ user กดปุ่ม Save แล้วทำการ Commit ข้อมูลลง Database บนสภาวะ เนตเวิร์คกากๆ
สิ่งที่เกิดขึ้นก็คือเมื่อเราทำการประมวลผลอะไรนานๆ บน EDT จะทำให้ ...

จาวาค้างส์

ดังนั้นสิ่งที่ทำให้ค้างส์ ไม่ใช่ จาวา แต่เป็นเพราะคนเขียน นะจ๊ะ ... จุบุ จุบุ ...
แต่ก็ไม่ต้องแปลกใจว่าทำไม ไม่มีใครคอยบอก / แนะนำ ว่าไม่ควรทำบน EDT ....
ความรู้นี้ก็ได้มากจาก Best Practices ต่างๆ ช่วงหลังๆ ที่ SUN มาเอาจริงเอาจัง
กับ Java-Desktop แล้ว ... ซึ่ง App เก่าๆ ไม่ต้องพูดถึง .... วิ่งอยู่บน EDT ซะเยอะ ... ก็ค้างส์กันไป ...

วิธีแก้แบบง่ายที่สุดในการลด Long-Session Process บน EDT คือการ "แตก" Thread
ให้มาทำงานนอก EDT แล้วหากต้องการ Update Event ใดๆ ที่เกี่ยวกับ UI ให้ใช้
SwingUtilities.invokeLater ( Runable runable )
สิ่งที่ขัดใจจอร์จอีกอย่างเวลาทำการแก้ code ที่เป็น Legacy นั่นคือ
การใช้ UI มาทำการ Handle Process ที่เกี่ยวข้องกับการประมวลผล ...
ยกตัวอย่างเช่น

เอา State ของ Checkbox มากำหนดเงื่อนไขของ Boolean แบบ True / False ซึ่งดูๆ
ไปแล้วอาจจะ Common มากในการที่จะบอกว่า "ก็ disabled ไปสิ เค้าก็แก้ไม่ได้แล้ว"
แต่การ Disabled เป็นเพียงการแก้ปัญหาที่ปลายเหตุเอามากๆ ถ้าเกิดเจอ User เกรียนๆ
ที่ Trigger UI ไปมา แล้วใน Trigger นั้นเป็น การ Query Data 10k Record พร้อมกับต่อ Database ....
ซึ่งถ้าเรามีการ Handle ข้อมูลโดยแบ่งเป็น MVC ที่ดีแล้ว ... ปัญหาดังกล่าวจะขี้เล็บมากๆ
เมื่อเทียบกับการปล่อยมันเอาไว้ แล้วเกิดปัญหาที่รับมือได้ยากทีหลังนั้น
มันค่อนข้างจะคุ้มค่ามากกว่าไม่ใช่เหรอ ?

วันอาทิตย์, กุมภาพันธ์ 27, 2554

Vavar ปะทะ Java Swing #3 : Why Swing ?

UI สุดเมพ สมัย ป.โท ..
ประกาศ : บทความเหล่านี้เขียนด้วยความคิดเห็นของตัวเองล้วนๆ ... 
ผิดถูกยังไง สามารถเสนอแนะโดย post comment ด้านล่างได้ครับ :)

ตลอดเวลาที่นั่ง code มา 2-3 เดือน คอยถามตัวเองเสมอว่า
"ทำไมต้อง Swing ?"
"เขียน AWT อย่างเดิมไม่ดีกว่าเหรอ ?"

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

ถ้าจะทำ Client GUI ... โดย Java ... ในขณะนี้ ...
คงมีเพียง Swing ที่เป็นคำตอบสุดท้าย ...

จริงๆ แล้วการทำ GUI ด้วย java
ก็ไม่ใช่เรื่องเลวร้ายซักเท่าไหร่ ...
แต่ต้องยอมรับอย่างนึงว่าช่วงตั้งแต่ JRE 1.4 - 1.5 ...
SUN ไปเน้นหนักทาง J2EE มากเกินไป ...
จน Java Desktop มันย่ำแย่ซะจน Developer หลายๆ คน
ตั้งเป็น slogan ให้ว่า

"จาวาค้างส์" 

กันเลยทีเดียว ...

ถ้าอยากรู้ว่ามัน "แย่" ขนาดไหนแนะนำให้รัน app
ที่เป็น JRE 1.5 กับ JRE 1.6 ครับ ... จะเห็นความแตกต่างอย่างรู้สึกได้ :)

อ้อ อีกอย่าง ... ไม่ได้สนับสนุนว่า "จาวาเร็วส์" นะครับ
และก็ไม่ได้เป็น zealot ด้วย .... กลับมาดู Swing ของเรากันต่อดีกว่า ...

ด้วยอายุของ Java Swing แล้ว ... คงปฎิเสธ ไม่ได้ว่าเป็น Techonology ที่ค่อนข้าง "เก่า"
เพราะมัน 10 ปี มาแล้ว ... แต่ยังแก่น้อยกว่าอย่าง MFC
ที่เป็น lib ของ Microsoft อยู่เยอะหน่อย :)

Firewall App บ้านๆ ที่เคยเขียนสมัย ป.ตรี (MFC + C++)

แต่หากด้วยใครเคยเขียน MFC มาบ้าง ก็จะรู้สึกทันทีว่าการเขียน GUI บน Java นั้น ...
ไม่ได้ยากเท่า MFC แต่อาจจะต้องใช้จินตนาการ นิดหน่อย
เพราะหากเขียน code แบบ AWT มันไม่มี Visual Tool ให้ดูขณะที่กำลังเขียน code อยู่ ...
ซึ่งใน Swing ก็มีให้อยู่พอสมควร ดังเช่น netbean หรือ window builder pro ...

โดยตัว Swing เองมีการใช้ MVC Framework เป็น Core Architect
อยู่ตรงกลางโดยแบ่งออกเป็น 3 ส่วนหลักๆ คือ

  1. Model
    ใช้ในการเก็บข้อมูลต่างๆ ไม่ว่าจะเป็น การ enabled / disabled
    หรือพูดง่ายๆ ว่า Attribute ทุกอย่างของ Component นั้นจะถูกเก็บอยู่ที่ Model ....
    อย่าง ปุ่ม ( JButton ) ก็จะมี ButtonModel ที่เก็บข้อมูลของปุ่มที่เราสร้างขึ้นนั้นไว้ ...
    เราสามารถเรียกข้อมูลจาก Model มาเพื่ออ่านค่า หรือเปลี่ยนแปลงค่าได้ ...
    ซึ่งการเรียกค่าต่างๆ นั้น จะต้องทำมาจาก Controller หากเราต้องการเปลี่ยนค่าภายใน Model โดยไม่ผ่าน Controller เราจำเป็นที่จะต้อง "Fire" หรือบอกให้ Controller รู้ด้วยว่า ...
    ค่าใน Model มีการเปลี่ยนแปลง ... Controller เองก็จะทำการดึงข้อมูลเพื่อให้
    View ทำการแสดงผลข้อมูลใหม่ให้ถูกต้อง ...  
  2. Controller
    หรือเรียกง่ายๆ ว่า Component ... ตัว Controller จะทำหน้าที่จัดการ
    "Behavior" หรือ User Input ต่างๆ ที่ สามารถกระทำกับ Component นั้นให้ได้ถูกต้องตามลักษณะ
    ยกตัวอย่างเช่น setEnabled หรือ setVisible จะเป็น "Behavior" ของ Component ทุกอันที่จะต้องมี ...
  3. View
    หรือที่เรียกอีกอย่างว่า UI ... การที่ Component จะทำงานได้ ไม่ได้ขึ้นอยู่กับว่าหน้าตาของ
    Component นั้น มีหน้าตาเป็นอย่างไร ... ตัวอย่างง่ายๆคือ ปุ่มแบบ Turn On/Off  ...
    เราอาจจะใช้ RadioButton แทนการใช้ Button ธรรมดาที่จะต้องมานั่งเขียน Code
    ในการเปลี่ยนสถานะปุ่มอื่นๆ ที่อยู่ภายใต้เงื่อนไขเดียวกันแทนก็ได้ ...

ซึ่งในการเปลี่ยน View หรือ UI นั้น ใน Swing เรียกว่า UI Delegate โดยมีลักษณะตาม
Sequence Diagram ข้างล่างนี้


จะเห็นได้ว่า แต่ละ Component จะมีการไปเรียกใช้ UIManager ซึ่งเป็น class กลางของ Swing ...
จึงทำให้เกิด Concept ที่เรียกว่า LookAndFeel ขึ้นมา ... ทำให้เราสามารถปรับเปลี่ยน UI
ได้อย่างที่เราต้องการ

สรุปแล้วโดย Architect ของ Swing เองก็ออกแบบ มาได้ค่อนข้างมีประสิทธิภาพมาก
มีความเป็น "Mature" UI ToolKit ที่เหมาะในการทำ Application พอสมควร ....

ซึ่งเนื่องจาก Application เดิม เป็น AWT Component ทั้งหมด จึงต้องมีภารกิจในการเปลี่ยน
ให้เป็น Swing เพื่อใช้ Architect ที่ว่านี้ ....
แล้วจะทำได้ยังไงบ้าง ? เจอกันตอนหน้าครับ :)

วันพุธ, พฤศจิกายน 03, 2553

Renew Vs Renovation

**คำเตือน : บทความนี้ เหมาะสำหรับ Geek


หลายๆ ครั้ง การพัฒนาโปรแกรม ก็มีความยากในการพัฒนา ...
เหตุผลหลักๆ ของการพัฒนาที่ยากนั้น ไม่ใช่เพราะความยากของงาน
แต่เป็นเพราะ solution ที่จะใช้สำหรับงานนั้นๆ มันยากที่จะตัดสินใจ ....
ด้วยโครงสร้าง ของโปรแกรม ที่เป็นลักษณะ Product 
โดยไม่ใช้ 3rd party software มาช่วยทุ่นแรง นั้น ...
สิ่งที่ challenge มากที่สุด คือ การสร้าง compatibility ให้กับตัว Product นั้นๆ 
เพราะเมื่อการที่พัฒนา application ในรูปแบบ Product จะมีข้อจำกัดมากมายที่
Developer ไม่สามารถ control ให้ลูกค้่า(เก่า)ให้ปฎิบัติตามได้ ... 
การเลือก technology  จึงจำเป็นที่จะต้อง คำนึงถึงจุดนี้เช่นกัน ...


การที่ โปรแกรม มีอายุการใช้งานมามากกว่า 3-4 ปี 
โดยพัฒนาตาม Requirement ของ ลูกค้า
จะเป็นสิ่งที่ค่อนข้างขาด Innovation มากพอสมควร ... 
User Interface เป็นอีกจุดนึง ที่มีความคล้างคลึงเช่นเดียวกับ technology .. 
วันนี้ ใ้ช้ง่าย ... พรุ่งนี้อาจจะมี Interface แบบใหม่ที่ใช้งานได้ง่ายกว่าแล้วก็ได้ ...  
ความ challenge จึงอยู่ที่ว่า ผู้พัฒนา จะทำอย่างไรให้ โปรแกรมของตัวเองนั้น 
มี UI ที่ UP-TO-DATE อยู่เสมอ ?? 


การเขียนใหม่ทั้งหมด ( re-new ) เป็นทางออกแบบนึงแต่ไม่สามารถ การันตีได้ว่า 
ของที่ทำใหม่ จะดี / เทียบเท่าของที่มีอยู่เดิม ....

ทางออกที่เลือกสำหรับงานในบางครั้ง จึงจำเป็นที่จะต้องเปลี่ยนจากการคิด
ที่จะ re-new เป็น renovation แทน ดังนั้นด้วย legacy code ต่างๆ 
ยกตัวอย่างเช่น Java AWT ก็ค่อนข้างเป็น Challenge ที่จะคิดว่า 
เราจะเอาอะไรมาเป็น replacement แต่ต้องได้ productivity เท่าเดิม ???


ไม่ว่าจะทำอะไรก็ควรที่จะศึกษาความเป็นไปได้ ก่อนที่จะทำเสมอ ...
เลยไปแอบอ่านเจอ บทความ เกี่ยวกับ Swing ขึ้นมา


 http://www.jroller.com/phidias/entry/is_swing_dead

เค้าก็เขียนได้ดีอะนะ ๕๕
โดยสรุปก็คือ ... ถ้า technology มันยังพอไปต่อได้ 
ถ้าเสีย effort ในการ renovate อย่างน้อย ก็ยังใช้น้อยกว่า renew อยู่ดี ...