Quantcast
Channel: cc :: somkiat
Viewing all 2000 articles
Browse latest View live

ขำ ๆ ไปกับ WebSphere Liberty

$
0
0

ws-00

ws-00 เนื่องจากช่วงนี้ต้องทำงานกับ IBM Websphere บ้างนิดหน่อย ดังนั้นจึงอยากจะลองติดตั้งและใช้งานนิดหน่อย แต่เมื่อไปดูขนาดของไฟล์ติดตั้ง และ ความต้องการต่าง ๆ แล้วไม่น่าจะรอด จึงไปดูว่า มีวิธีการไหนที่น่าเป็นไปได้บ้าง เมื่อไปดูแล้วพบว่ามี Websphere Liberty ให้ใช้งาน ซึ่งสามารถใช้งานกับ Docker ได้อีก ดังนั้นมาลองใช้งานกันดูหน่อยสิ

Websphere Liberty คืออะไร ?

คือ JavaEE application server ซึ่งมีขนาดไม่ใหญ่ และ ทำงานได้รวดเร็ว ซึ่งสร้างขึ้นมาเพื่อใช้ในการพัฒนา (Development environment) แต่ว่าตัวมันพร้อมสำหรับการ deploy ระบบงานบน production รวมทั้งพร้อมสำหรับระบบ cloud อีกด้วย ซึ่งเป็นการรวมเอาเทคโนโลยีของ IBM เข้ากับ open source ต่าง ๆ ทำให้มี startup time ที่เร็วมาก ในเอกสารบอกว่าน้อยกว่า 2 วินาที ไม่ต้องทำการ restart เมื่อมีการแก้ไข สามารถ configuration ได้ง่าย ๆ ออกแบบมาเพื่อให้ง่ายต่อการใช้งาน แถมยังมี profile ทั้ง JavaEE 6 และ 7 ให้ใช้งานอีกด้วย ws-02 ที่สำคัญคือ สามารถทำงานร่วมกับ Docker, Chef, Puppet, Apache Maven และ Jenkins ได้ง่าย ๆ อีกด้วย
ปล. แล้วมีใครใช้บ้างนะ ?

ลองมาใช้งานผ่าน Docker กันหน่อยสิ ว่าง่ายจริงไหม ?

ขั้นแรกไปดู image ใน Docker hub :: Websphere Liberty กันก่อน มีการ pull มากกว่า 1 แสนครั้ง !! มันน่าสนใจไม่เบาเลยนะ ดังนั้นมาใช้งานกันหน่อย

สิ่งที่ต้องการคือ ทำการ deploy ไฟล์ WAR สำหรับ Java web application

โดยระบบงานจะอยู่ในไฟล์ Sample1.war ดังนั้นทำการสร้าง Dockerfile ดังนี้ [gist id="12a8b2136ce331e91e464da2cd94c6f4" file="Dockerfile"] ทำการสร้าง image ชื่อว่า websphere-app ด้วยคำสั่ง [code] $docker build -t websphere-app . [/code] ขนาดของ image ประมาณ 400 MB จากนั้นทำการสร้าง container จาก image websphere-app โดยสามารถเข้าใช้ผ่าน port 80 และ 443 ดังนี้ [code] $docker run -d -p 80:9080 -p 443:9443 websphere-app [/code] จากนั้นเข้า browser ทดสอบการติดตั้ง app เป็นดังรูป ws-01 เพียงเท่านี้ก็สามารถติดตั้ง Java web application บน WebSphere Liberty ได้แล้ว ชีวิตง่ายขึ้นเยอะเลยนะ Reference Websites https://wasdev.net/ https://developer.ibm.com/wasdev/websphere-liberty/

[Bug] Xcode 7.3 + Swift 2.3 มัน build นานมาก ๆ

$
0
0

xcode-00

เนื่องจากทำการเตรียมข้อมูลสำหรับการทำสอบ iOS app นิดหน่อย ซึ่งเตรียมข้อมูลในรูปแบบ dictionary แต่ดันเจอปัญหาการ build ช้ามาก ๆ ใน XCode 7.3 (Swift 2.3) !! โดยไร้สาเหตุ ตัวอย่าง code จาก Swift literal parsing bug [gist id="6fbf97c7dfa467f4d02dbacd95c07326" file="bug.swift"] แสดงผลการทำงานดังรูป (รอกันต่อไป build นานมาก ๆ) xcode-00
เมื่อไปดูใน web ก็พบว่ามันคือ Bug ของภาษา Swift นั่นเอง อยู่ใน SR-305 ซึ่งถูกแก้ไขไปแล้ว ซึ่งจะอยู่ใน Swift 3 !!

ดังนั้นจึงทำการเปลี่ยน Toolchains ไปใช้ Swift 3 แทน

พบว่าปัญหานี้ถูกแก้ไข และ หายไปเรียบร้อยแล้ว xcode-01
มีใครเจอปัญหานี้บ้างครับ ?
ส่วนใน XCode 8 ก็ทดลองเช่นกัน พบว่าไม่มีปัญหาเช่นกัน เนื่องจากใช้ Swift 3 นั่นเอง Reference Websites https://github.com/mattnedrich/swift-literal-parsing-bug https://spin.atomicobject.com/2016/04/26/swift-long-compile-time/

แนะนำการเรียน Programming ผ่าน Mimo app

$
0
0

phones@2x

phones@2x เนื่องจากต้องกลับบ้านต่างจังหวัดและไม่ได้เอา notebook กลับไปด้วย แต่ต้องการเรียนรู้เกี่ยวกับ programming ผ่าน Mobile app จึงลองค้นหา app หลาย ๆ ตัว โดย app ที่ลองเรียนแล้วชอบคือ Mimo ซึ่งเหมาะมาก ๆ สำหรับผู้เริ่มต้นศึกษา programming ส่วนระดับกลางและสูงนั้นยังไม่เห็นมีนะ เท่าที่ลองเรียนภาษา Java, Swift และ HTML ก็ถือว่าใช้ได้เลย ไม่ได้ยุ่งยากอะไร แถมอธิบายได้ชัดเจนดี แต่สำหรับคนที่มีพื้นฐานอยู่แล้วอาจจะไม่ชอบก็เป็นไปได้ และมีเฉพาะ iOS app เท่านั้นนะ nexus-phone@2x แต่ถ้าต้องการลงรายละเอียดเชิงลึกของแต่ละภาษา ก็มี app แยกออกไปอีกนะ ประกอบไปด้วย
  • Swifty สำหรับภาษา Swift
  • Javvy สำหรับภาษา Java
มาสนุกกับการ programming กันครับ Reference Websites https://techcrunch.com/2016/08/19/mimos-new-app-teaches-you-how-to-code-on-your-iphone/

สรุปการจัดการ Dependency แบบง่าย ๆ ด้วย CocoaPods

$
0
0

pod-00

pod-00 สำหรับ iOS developer ทั้งหลายคงต้องใช้ dependency หรือ library อื่น ๆ อย่างแน่นอน ซึ่งถ้า copy code มาใส่ project เองคงไม่ดีเท่าไรนัก !! ดังนั้นน่าจะต้องจัดการผ่านเครื่องมือต่าง ๆ เช่น โดยใน blog นี้จะพูดถึง CocoaPods ตั้งแต่การติดตั้งไปจนถึงการใช้งานแบบง่าย ๆ

เริ่มต้นด้วยการติดตั้ง

[code] $gem install cocoapods [/code] เมื่อติดตั้งเสร็จสามารถเริ่มต้นด้วยการ clone master repository ของ CocoaPods มาลงไว้ที่เครื่องของเราซึ่งใช้เวลาพอสมควรนะครับ ด้วยคำสั่ง [code] $pod setup [/code] จากนั้นเริ่มนำมาใช้ใน iOS project ด้วยคำสั่ง [code] $pod init [/code] จะสร้างไฟล์ Podfile ออกมาซึ่งเป็น configuration หลักของ CocoaPods สำหรับ project ของเรานั่นเอง [gist id="dfdb2373a4ea872ea4bd52794e08e345" file="Podfile"]

จากนั้นทำการเพิ่ม 3-party dependency/library กันหน่อย

สามารถค้นหา dependency ได้ที่ CocoaPods feed เช่นต้องการเพิ่ม RxSwift เข้ามาใน project [gist id="dfdb2373a4ea872ea4bd52794e08e345" file="Podfile2"] ทำการติดตั้ง dependency/library ต่าง ๆ ลงใน project ของเราด้วยคำสั่ง [code] $pod install [/code] แต่ถ้าทำการเปลี่ยนแปลง dependency/library ให้ทำการ update ด้วยคำสั่ง [code] $pod update [/code]

แต่บางเครื่องอาจจะมีปัญหาในการติดตั้ง

หรือไม่สามารถใช้คำสั่ง pod ได้ เช่น ไม่สามารถ download library ได้ สามารถแก้ไขได้ด้วยการ custom GEM_HOME ได้ดังนี้ [code] $mkdir -p $HOME/Software/ruby $export GEM_HOME=$HOME/Software/ruby $gem install cocoapods $export PATH=$PATH:$HOME/Software/ruby/bin $pod --version [/code] ขอให้สนุกกับการเขียน code ครับ

สรุปสิ่งที่ได้รับจากงาน ReactJS Bangkok 1.0.0 ในห้องสำหรับผู้เริ่มต้น

$
0
0

react-00

react-00 มีโอกาสไปร่วมงาน ReactJS Bangkok 1.0.0 โดยแบ่งออกเป็น 2 ห้องคือ
  1. ห้องพื้นฐานสำหรับผู้เริ่มต้น (น่าจะสำหรับคนที่เขียน ReactJS มาแล้ว)
  2. ห้องขั้น Advance
ส่วนผมอยู่แต่ห้องพื้นฐานโดยในห้องนี้มี session ต่าง ๆ ดังนี้
  • Introduction to React
  • Redux
  • React Native
  • Discussion เป็นการถามตอบกับ speaker ทุกคน
จึงทำการสรุปไว้นิดหน่อย โดยในแต่ละ session จะมีการทำ demo ให้ดู แต่ว่ามีเวลาเพียง 1 ชั่วโมงจึงไม่สามารถ Live demo ได้ จึงมี code ตัวอย่างให้กลับไปดูและทำตามต่อไป

Introduction to React

เป็นการอธิบายการพัฒนา web application ตั้งแต่แบบเดิม มาจนถึง SPA (Single Page Application) แต่การพัฒนาระบบ web application ด้วย JavaScript แบบเดิม เช่น jQuery มักก่อให้เกิด code ซ้ำซ้อน และ กระจัดกระจาย ทำให้ reuse ไม่ดีเท่าที่ควร ดังนั้นจึงมี JavaScript framework ต่าง ๆ ออกมาให้ใช้งาน หนึ่งในนั้นคือ React ซึ่งพัฒนาโดยทีมของ Facebook อีกทั้งยังถูกใช้งานจากบริษัทชื่อดังมากมาย สามารถเข้าไปดูเพิ่มเติมได้ที่ Sites Using React React ออกแบบมาเพื่อทำให้ reuse code ง่ายขึ้น เนื่องจากออกแบบมาในรูปแบบ component-based มี performance การทำงานที่รวดเร็ว (Virtual DOM) รวมทั้งมี Ecosytem มากมาย จึงเป็นอีกทางเลือกหนึ่งในการพัฒนา web application ที่น่าสนใจอย่างมาก แต่ว่า React นั้นมี Learning curve ที่ค่อนข้างสูงเช่นกัน เนื่องจากต้องทำการศึกษาหลายอย่าง ไม่ว่าจะเป็น
  • NodeJS
  • ES6, JSX (JavaScript syntax extension)
  • Bable สำหรับการแปลง ES6 ไปเป็น JavaScript
  • ESLint
  • Webpack
  • Dependency อื่น ๆ อีกมากมาย
สำหรับผู้เริ่มต้นกับ React แนะนำให้เริ่มด้วย Create React App ทำให้เราสร้าง React app ง่าย ๆ โดยไม่ต้อง configuration อะไรเองเลย แต่เมื่อเข้าใจแล้วก็หัดทำเองด้วยนะ สามารถติดตั้งและเริ่มใช้งานด้วยคำสั่ง [code] $npm install -g create-react-app $create-react-app my-app $cd my-app/ $npm start [/code] ดูผลการทำงานที่ http://localhost:3000 แสดงดังรูป react-01 เมื่อต้องทำการ deploy ขึ้น production ให้ใช้คำสั่ง [code] $npm run build [/code] จะทำการ generate code ต่าง ๆ ออกมา เพื่อใช้ในการ deploy ต่อไป โดยใน workshop นั้นอธิบายสิ่งต่าง ๆ ดังต่อไปนี้
  • การสร้างและใช้งาน React component
  • การใช้งานร่วมกับ bootstrap
  • การจัดการ event และ state ต่าง ๆ ภายใน React app
  • Reuse component
เป็นสิ่งที่ผู้เริ่มต้นควรศึกษา และ ลงมือทำ เพื่อให้เข้าใจและสามารถนำไปใช้งานต่อไปได้ง่ายขึ้น ส่วน code ตัวอย่างและ Slide สามารถ download ได้จาก Github:: Intro React BKK ยังไม่พอนะมีแถมสิ่งที่น่าสนใจสำหรับการศึกษาเพิ่มเติมเช่น
  • React Router
  • Redux
  • Universal ReactJS หรือ Isomorphic ซึ่งมี session ในห้อง Advance

ว่าด้วยเรื่อง Redux

เมื่อระบบงานที่พัฒนาด้วย React มีขนาดใหญ่และซับซ้อนขึ้น ทำให้การจัดการ state ของระบบงานยากขึ้น ซึ่งปกติจะส่ง state หรือ ข้อมูลผ่าน Props ดังนั้นจึงมีคนคิดและสร้าง Redux ขึ้นมา เพื่อช่วยแก้ไขปัญหาของการจัดการ state ทำให้สามารถแยก state และ UI ออกจากกันได้อย่างชัดเจน ซึ่งมีรูปแบบที่เรียบง่าย ไม่ซับซ้อน ดังนี้
  • การทำงานเป็นแบบ Publish-Subscribe model
  • ทำการเก็บ state ไว้ในสิ่งที่เรียกว่า Store
  • ถ้าใครต้องการแก้ไข state ให้ทำการส่ง action ผ่าน method dispatch()
  • ถ้าใครสนใจ state อะไรก็ห้ทำการ subscribe ไว้ใช้งานต่อไป
แต่บางครั้งก็อาจจะทำให้เกิด code ซ้ำ ๆ ขึ้นมา จากการสร้าง action ที่ส่งเข้าไป ซึ่งเป็นข้อเสียอย่างหนึ่งของ Redux โดยโครงสร้างของ Redux ประกอบไปด้วย
  • Store สำหรับจัดเก็บ state ซึ่งประกอบไปด้วย
    • State
    • Reducer ทำหน้าที่คำนวณ state ต่อไป
    • Dispatch(action) สำหรับส่ง action ต่าง ๆ ไปที่ store
  • UI/View สำหรับการแสดงผล
แสดงดังรูป react-03 Redux มี principle 3 เรื่องที่ต้องเข้าใจ ประกอบไปด้วย
  1. Single Source of Truth นั่นคือจะมี Store เพียวตัวเดียวเท่านั้น
  2. State is read-only นั่นคือไม่สามารถแก้ไข state ได้โดยตรง ต้องส่ง action ผ่าน method dispatch() เท่านั้น
  3. Mutation as Pure function นั่นคือ Reducer จะไม่ทำการแก้ไขข้อมูลใด ๆ เลย จะรับ input เป็น current state และ action จากนั้นจะส่ง next state กลับมาให้
ข้อดีที่ชอบมาก ๆ สำหรับ Redux คือ สามารถทดสอบได้ง่าย เนื่องจากเราสามารถทดสอบเรื่องของ state ที่เปลี่ยนไปได้เลย โดยไม่ต้องสนใจว่าจะแสดงผลถูกหรือไม่ แต่ก็ต้องแลกมาด้วย learning curve ที่สูงเช่นกัน แต่โดยรวมแล้วมีข้อดีมากกว่าข้อเสียนะ รวมทั้งมีเครื่องมือช่วยเหลือในการพัฒนาด้วย นั่นคือ Redux DevTool ซึ่งเป็น Google Chrome extension ซึ่งสามารถ download มาใช้กันได้เลย การติดตั้งนั้นสามารถทำผ่าน npm ได้เลย [code] npm install --save react-redux npm install --save-dev redux-devtools [/code] แนะนำให้ดู Course Getting start with Redux นะครับ ซึ่งผู้สร้าง Redux มาสอนด้วยตัวเอง แถมยังมีการพูดถึงเรื่องอื่น ๆ อีก ซึ่งต้องไปศึกษาเพิ่มเติมอีกแล้ว เช่น Relay สำหรับ code ตัวอย่างและ slide อยู่ที่ โดยแนวคิดของ Redux นั้นสามารถนำไปใช้กับระบบอื่น ๆ ได้ เช่นการพัฒนา Mobile application ซึ่งผมเคยเขียน blog ไว้แล้ว ในเรื่องสรุปเรื่องของ Redux สำหรับ Mobile Application

React Native สำหรับการพัฒนา Mobile application

ทำให้สามารถพัฒนา mobile app ทั้ง Android และ iOSด้วย JavaScript เท่านั้น ซึ่งช่วยลดเวลาในการพัฒนา mobile app ลงไป มันก็มีทั้งข้อดีและข้อเสีย แต่ก็เป็นทางเลือกหนึ่งที่น่าสนใจเช่นกัน react-05 เริ่มต้นใช้งานก็ไม่ยากเท่าไร ให้ทำการติดตั้งและลองสร้าง app ง่าย ๆ กันดู แต่การใช้งานจริง ๆ ก็ไม่ง่ายนะ และทำการ run บน iOS ดังนี้ [code] $npm install -g react-native-cli $react-native init AwesomeProject $cd AwesomeProject $react-native run-ios [/code] การทำงานแสดงดังรูป react-02 โดยสิ่งต่าง ๆ ที่จำเป็นต้องรู้ประกอบไปด้วย
  • ผลการทำงานบน iOS และ Android จะไม่เหมือนกันทั้งหมด
  • แนะนำให้จัดการ Layout ด้วย Flexbox
  • มี DevTool ให้อยู่แล้ว สามารถกด CMD + D บน Emulator ได้เลย
  • มี Hot reload ซึ่งจะทำการ reload ในส่วนที่เปลี่ยนแปลงเท่านั้น ทำให้การทดสอบและพัฒนาเร็วมาก ๆ
แต่ก็มีข้อเสียพอสมควรนะ เช่น
  • ตัว framework มันเปลี่ยนแปลงเร็วมาก ๆ ตอนนี้ version 0.32 แล้ว และ 0.33 rc ออกมาให้ลองใช้แล้ว
  • ผู้ใช้งานเอง ไม่ศึกษาและเรียนรู้ !!
  • Component ต่าง ๆ ยังน้อยอยู่ นั่นสะท้อนให้เห็นขนาดของ community นั่นเอง
  • โดยที่สามารถค้นหา component ต่าง ๆ ได้จาก JS-coach :: React native
ส่วนการเรียนรู้แนะนำให้ไปดู project ต่าง ๆ เช่น ใครบ้างล่ะที่ใช้งาน React Native ? สามารถดูเพิ่มเติมได้ที่ The React Native Showcase โดย code ตัวอย่างของ session นี้อยู่ที่ Github::React native bkk example

Discussion ช่วงท้ายของงาน

react-04 หัวข้อที่น่าสนใจก็คือ การศึกษา React ว่าทำอย่างไรกันบ้าง ? ซึ่งส่วนใหญ่จะมีวิธีการศึกษาคล้าย ๆ กัน คือ เรียนรู้จาก code ที่มีอยู่ และ ตัวอย่างก่อน เพื่อทำให้เข้าใจความสามารถต่าง ๆ จากนั้นให้เริ่มสร้าง project ด้วยตัวเองทั้งหมด อีกเรื่องที่น่าสนใจคือ การ migrate และโน้มน้าวให้บริษัทและทีมมาใช้ ReactJS กัน เป็นเรื่องที่หลาย ๆ บริษัทและทีมต้องใส่ใจกันให้มาก ประกอบไปด้วย
  • เริ่มเขียนใหม่หมดเลย
  • ค่อย ๆ ทำไปทีละส่วน
  • ถ้าเป็นระบบเก่าแนะนำให้ทำการวางแผน migrate ดี ๆ ด้วย
ขอขอบคุณสำหรับงานดี ๆ มีเรื่องให้ศึกษาและนำไปใช้งานเพียบเลย ไปหัดเขียนก่อนนะครับ มีกลุ่ม ReactJS Developer Thailand ให้เข้าร่วมอีกนะ

[Refactoring code] ว่าด้วยเรื่อง Creation Method

$
0
0

refactoring-00

refactoring-00 เนื่องจากทำการ review code ของระบบที่พัฒนาด้วยภาษา Swift แล้วพบว่าการสร้าง object บางตัวนั้น สามารถสร้างได้หลายแบบ ทำให้มี constructor จำนวนมาก !! ซึ่งมันเป็น Code Smell อย่างหนึ่ง ดังนั้นได้เวลาปรับปรุง code ให้ดีขึ้นแล้วนะ

มาดูตัวอย่าง code กันนิดหน่อย

[gist id="fdb5acaaa0cb7a8d796a382bdb66fdb2" file="Before.swift"] คำถาม ใครเคยเจอ code แบบนี้บ้าง ? ถ้าเคยเจอ แก้ไขปัญหากันอย่างไร ? บางคนอาจจะบอกว่า ไม่น่าจะมีปัญหาอะไรนะ ซึ่งก็ไม่ผิดอะไร บางคนอาจจะบอกว่า ก็เขียน comment ไปสิ บางคนอาจจะบอกว่า ... ปัญหาสำคัญของ code ข้างต้นคือ ใน constructor แต่ละตัวนั้น มันทำงานอะไรกันแน่ ทำไมต้องแยกกันด้วยล่ะ ? แน่นอนว่า ต้องมีเหตุผลของมัน แต่ผู้ใช้งานต้องงงอย่างแน่นอน ว่าจะสร้าง object ด้วยตัวไหนดี
ดังนั้นถึงเวลา Refactor code กันแล้วนะ !!

โดยการ Refactor code ที่จะใช้คือ Creation Method

มีเป้าหมายหลักเพื่อทำให้การสร้าง object อ่านง่าย และ เข้าใจได้ง่ายขึ้น ซึ่งแต่ละ method จะมีชื่อที่ชัดเจนว่า ทำอะไร เพื่ออะไร [gist id="fdb5acaaa0cb7a8d796a382bdb66fdb2" file="After.swift"] นักพัฒนาอย่าลืม Refactor code หรือ ปรับปรุง code ให้ดีขึ้นด้วยนะครับ Reference Websites หนังสือ Refactoring to pattern Code smell

ทำความรู้จักกับ 3R principle

$
0
0

3r-00

3r-00 อ่านเจอบทความเรื่อง 3R principles of programming เป็นแนวปฏิบัติ 3 อย่างเพื่อช่วยทำให้ code ที่เหล่านักพัฒนา software สร้างขึ้นมา มีความ clean มีความง่ายต่อการอ่าน มีความง่ายตอการทำความเข้าใจ มีความง่ายต่อการดูแลรักษา ไม่ซับซ้อนมากนัก จึงทำการแปลและสรุปส่วนที่น่าสนใจมานิดหน่อย

3R principle ประกอบไปด้วย

  • Responsibility
  • Reusability
  • Readability

เริ่มด้วย Responsibility หรือหน้าที่ความรับผิดชอบนั่นเอง

ว่าในแต่ละ class ว่าในแต่ละ method/function นั้นควรมีหน้าที่การทำงานอะไรบ้าง ลองคิดดูสิว่า ถ้าในแต่ละ class/method/function มีหน้าที่การทำงานที่เยอะมากมาย มีหน้าที่การทำงานที่ซับซ้อน จะส่งผลให้ code โดยรวมออกมาซับซ้อนและยุ่งเหยิงกันมากเพียงใด ตัวอย่างเช่น ในแต่ละclass มี 5-20 method ในแต่ละ method/function มี code มากกว่า 100 บรรทัด ส่งผลให้ใน class หนึ่งมี code มากกว่า 500-2,000 บรรทัด !! เชื่อเถอะว่า มันไม่สนุกอย่างแน่นอน โดยเรื่องของ Responsibility นั้นมาจาก S ใน SOLID principle นั่นก็คือ Single Responsibility Principle (SRP)

ต่อมาคือผลที่ตามมาจากข้อแรกคือ Reusability

เมื่อเราทำการแยกส่วนการทำงานต่าง ๆ ออกจากกัน ด้วยหน้าที่การทำงานเฉพาะของ component/class/method/function นั้น ๆ แล้ว มันก็จะง่ายต่อการ reuse แล้ว ไม่พอนะ ยังง่ายต่อการทดสอบอีกด้วย
มีคำถามที่น่าสนใจว่าเราจะ Reuse กันเมื่อไร ? ตอบง่าย ๆ คือ เมื่อมันถูกใช้ซ้ำ ๆ ไงล่ะ ดังนั้นจงทำให้เกิดการใช้ซ้ำ ๆ ก่อน แล้วจึงคิดถึงการ reuse อย่าไปเสียเวลาเพื่อคิดว่า เราจะออกแบบอย่างไรเพื่อให้ reuse กันได้นะ

ส่วนการ reuse ได้ดีนั้น ในแต่ละ component/class/method/function ควรที่จะ Readability ด้วยเสมอ

ทั้งการตั้งชื่อที่สื่อถึงการทำงานจริง ๆ รวมไปถึงโครงสร้างการทำงานด้วยเช่นกัน มิฉะนั้น code เหล่านั้นจะ reuse ยากมาก ๆ
บ่อยครั้งมักพบว่า code ของระบบงานต่าง ๆ ต้องใช้เวลาในการเพิ่มและแก้ไขมากขึ้นเรื่อย ๆ ตามจำนวน feature และอายุของระบบ สาเหตุหลัก ๆ ก็คือ เรื่องการอ่าน code ไม่รู้เรื่องและ ไม่เข้าใจ นั่นคือปัญหาเรื่อง Readability
ดังนั้นลองถามตัวเราเองสิว่า code ที่เราเขียนในปัจจุบันมันอ่านและเข้าใจง่ายหรือไม่ ? และอย่าลืมว่า code ที่เราเขียนขึ้นมานั้น เขียนเพื่อให้คนอื่นเข้าใจนะ เนื่องจาก code เหล่านี้ยังต้องถูก maintain ต่อไป แนะนำให้ทำการเรียนรู้ และ ฝึกฝน จากนั้นลองนำแนวปฏิบัติ 3R ไปประยุกต์ใช้งานดูครับ การเขียน code มันสนุกนะ
วันนี้คุณ 3R แล้วหรือยัง ?

[Android] :: ทำการทดสอบ Custom View ด้วย Robolectric กันนิดหน่อย

$
0
0

3988212

robo-00 พอดีมีคำถามมาจากน้อง ๆ ที่เขียน Android app ว่า ถ้าต้องการทดสอบพวก Custom View โดยไม่ต้องเปิดหรือทดสอบผ่าน Activity ได้ไหม ? ตอบไปแบบไม่คิดว่า ทดสอบยังไงหว่า ไม่ผ่าน Activity !! แต่เมื่อคิดให้ดี ๆ ก็นึกออกว่า สามารถทดสอบด้วยการใช้ Robolectric เมื่อไปค้นหาเจอบทความเก่าหน่อยแต่อธิบายได้ดี เรื่อง Android: Unit testing custom views เลยเอามาลองใช้งานดูนิดหน่อย

ในการทดสอบใด ๆ ก็ตามผ่าน Activity จะพบปัญหามากมาย

ทั้งการทดสอบที่ช้า ทั้งการ setup ข้อมูลต่าง ๆ มากมายก่อนการเปิด Activity ดังนั้นสิ่งที่ควรทำคือ ลดความซ้ำซ้อนของแต่ละ Activity ลงไปก่อน หมายถึงต้องนำ logic ต่าง ๆ ออกไปจาก Activity หนึ่งในนั้นคือ การใช้งาน Custom View นั่นเอง และแน่นอนว่า การทดสอบก็ต้องทดสอบทำได้เช่นเดียวกัน ซึ่งน่าจะทำให้การทดสอบง่ายและรวดเร็วขึ้น ที่สำคัญไม่ต้องทดสอบผ่าน Activity หลักอีกด้วย

ลองมาดูตัวอย่างของ Custom View กันหน่อย

ทำหน้าที่ง่าย ๆ คือ แสดง progress bar เพื่อแสดง progress ของการทำงานของระบบ เมื่อทำงานเสร็จจะหยุดการแสดง progress bar ผ่าน method ที่ชื่อว่า stopLoadingAndSetText() และจะแสดงข้อความตามที่ต้องการออกมาด้วย Code ของ Custom view ซึ่ง extend มาจาก RelativeLayout [gist id="20725a7e236465b4509f21f025a4054a" file="LoadingView.java"] ส่วนของไฟล์ layout เป็นดังนี้ [gist id="20725a7e236465b4509f21f025a4054a" file="loading_view.xml"] จากนั้นเราลองมาดูสิว่า จะทดสอบการทำงานอย่างไร ? สิ่งที่เราต้องการคือ ไม่เปิด Activity จริง ๆ ขึ้นมา ดังนั้นเราไม่ต้องการ UI Testing นั่นเอง เพราะว่า มันช้าน่าดู !! แต่เราต้องการทดสอบเฉพาะ custom view หรือจากตัวอย่างคือ LoadingView สามารถทำการทดสอบด้วย Robolectric ได้ เนื่องจากมันไม่ต้องการ emulator หรือ device จริง ๆ เลย รวมถึงไม่ต้องใช้ mocking framework ใด ๆ อีกด้วย ซึ่งคิดว่าน่าจะตรงกับความต้องการ ดังนั้นมาดูขั้นตอนการใช้งานกันดีกว่า เริ่มจากการเพิ่ม library เข้าไปในไฟล์ build.gradle ดังนี้ [gist id="20725a7e236465b4509f21f025a4054a" file="build.gradle"] ต่อมาเริ่มเขียน test แรกกันเลย เป็นการตรวจสอบการทำงานของ Loading View เริ่มด้วยการแสดงเฉพาะ Progress bar ส่วนข้อความไม่แสดง แต่หลังจากเรียกใช้ method stopLoadingAndSetText() แล้ว Progress bar จะหายไป และ แสดงข้อความแทน

แต่ก่อนอื่นต้อง setup  เพื่อใช้งาน Robolectric ก่อน

ซึ่งเป็นจุดที่น่าจะยากสุด ๆ สำหรับการใช้งานแล้ว จุดที่น่าสนใจคือ การ setUp() นั่นเอง ซึ่งทำงานดังนี้
  • ทำการสร้าง Activity Controller ขึ้นมา เพื่อใช้สำหรับการสร้าง custom view
  • สร้าง custom view ผ่าน LayoutInflate จากไฟล์ layout ที่สร้างไว้จากข้างต้น
  • ทำการสร้าง view object ที่ต้องการ
แสดงดัง code [gist id="20725a7e236465b4509f21f025a4054a" file="LoadingViewTest.java"] จากนั้นจึงเริ่มเขียน test แรกดังนี้ [gist id="20725a7e236465b4509f21f025a4054a" file="LoadingViewTest02.java"] ลองทำการ run ชุดการทดสอบว่า ทำงานตามที่คาดหวังหรือไม่ !! แต่การทดสอบนั้นยังไม่จบ เนื่องจากเรายังขาด ? test เพื่อตรวจสอบว่า ข้อความที่แสดงตรงตามที่ต้องการหรือไม่ ดังนั้นเขียน test ได้ดังนี้ [gist id="20725a7e236465b4509f21f025a4054a" file="LoadingViewTest03.java"] ให้ทำการ run test ทั้งหมดอีกรอบ จะแสดงผลการทำงานดังนี้ robo-01 หรือทำการ run ผ่าน grade wrapper ด้วยคำสั่ง [code] $./gradlew clean testDebugUnitTest [/code] จะแสดงผลการทำงานดังรูป ซึ่งใช้เวลาในการทดสอบนานใช้ได้เลยนะ robo-02 ดู code ตัวอย่างเต็ม ๆ ได้ที่ Github::Up1:Demo with Robolectric

วิเคราะห์ code ภาษา Swift ด้วย SonarQube

$
0
0

sonar-swift-00

sonar-swift-00 ว่าง ๆ ช่วงฝนตกมานั่งวิเคราะห์ code ของภาษา Swift ด้วย SonarQube กันหน่อย ถ้าไปดูใน SonarQube จะพบว่ามี plugin ให้ใช้แล้ว แต่ว่ามันเป็น commercial หรือเสียเงินนั่นเอง ดังนั้นจึงไปลองหาของฟรีและไปพบกับ Sonar Swift จึงนำมาทดลองใช้กันหน่อย

เริ่มต้นด้วยการดูหน่อยสิว่า Sonar Swift มันมีอะไรให้ใช้บ้าง ?

  • การทดสอบทั้ง Unit test และ UI Test ผ่าน xcodebuild
  • และทำรายงานสรุปผลการทดสอบด้วย xcpretty
  • เรื่องของ code coverage ใช้งาน Slather
  • ตรวจสอบ issue ต่าง ๆ ด้วย SwiftLint ซึ่งสามารถดูเพิ่มเติมได้จาก blog การใช้งาน SwiftLint
  • ตรวจสอบเรื่อง complexity หรือความซับซ้อนของ code ด้วย Lizard
  • อีกทั้งยังสามารถตรวจสอบเรื่อง code ที่ซ้ำซ้อน และข้อมูลพื้นฐานของ code ได้

การติดตั้ง plugin

ทำการ download ไฟล์ backelite-sonar-swift-plugin-0.2.4.jar จากนั้นนำไปวางใน $SONARQUBE_HOME/extensions/plugins ของ SonarQube จากนั้นทำการ start หรือ restart service ของ SonarQube แล้วเข้าไปตรวจสอบว่า plugin ติดตั้งเรียบร้อยหรือไม่ ในเมนู System -> Update Center ถ้าติดตั้งสำเร็จจะแสดงดังรูป sonar-swift-01

มาถึงการใช้งานกันบ้าง

ใน Xcode project ต้องทำการสร้างไฟล์ sonar-project.properties ขึ้นมา สำหรับกำหนด configuration ต่าง ๆ ของ project เพื่อส่งผลการวิเคราะห์ไปยัง SonarQube แสดงดังนี้ [gist id="ee53ffe28b7ff7ae173eee0e552f6a37" file="sonar-project.properties"] สามารถดู code ตัวอย่างพร้อม configuration ได้ที่ Github::Demo Sonar Swift

จากนั้นเริ่มต้นวิเคราะห์ code ด้วยคำสั่ง

[code] $sh run-sonar-swift.sh [/code] ผลการทำงานให้เปิด SonarQube จะแสดงผลดังนี้ sonar-swift-02 ยังไม่พอนะ ยังสามารถทำงานร่วมกับ Fastlane ได้อีกด้วย เพียงเท่านี้เราก็สามารถวิเคราะห์ code ที่พัฒนาด้วยภาษา Swift แบบง่าย ๆ ได้แล้วครับ ทำให้เรารู้ได้เลยว่า ควรแก้ไข code อะไร และ ตรงไหนได้บ้าง น่าจะทำให้การเขียน code สนุกยิ่งขึ้นนะ

แก้ไขปัญหา Apache Maven ทำงานช้าด้วยการ build เฉพาะส่วนที่เปลี่ยนแปลง

$
0
0

maven-00

maven-00 เนื่องจากงานที่ดูอยู่เป็นระบบที่พัฒนาด้วยภาษา Java ส่วนโครงสร้างและ build tool ที่ใช้งานเป็นหลักคือ Apache Maven โดยในระบบประกอบไปด้วย module ต่าง ๆ มากมาย ส่งผลให้เมื่อมีการเปลี่ยนแปลงหนึ่งครั้ง จะต้องใช้เวลาในการ build ใหม่นานมาก ๆ (Clean build)
ดังนั้นจึงมีแนวคิดว่า ถ้าทำการ build เฉพาะจุดหรือ module ที่มีการแก้ไข น่าจะทำให้การ build เร็วขึ้น มาเริ่มลงมือกันดีกว่า

เริ่มจากต้องรู้ก่อนว่ามีไฟล์ไหนเปลี่ยนแปลงบ้าง ?

เนื่องจากจัดการ version ของ source code ด้วย git จึงใช้คำสั่งง่าย ๆ ดังนี้ [code] $git pull origin master $git diff --name-only HEAD^! [/code] ผลที่ได้คือ จะแสดงชื่อไฟล์ทั้งหมดที่มีการเปลี่ยนแปลงจากการ pull ครั้งล่าสุด จะทำการบันทึกผลลงไฟล์ [code] Module01/file1.java Module02/file2.java Module02/file3.java Module03/file4.java Module04/file5.java Module04/file6.java [/code]

จากนั้นทำการตรวจสอบว่ามี module ไหนทำการเปลี่ยนแปลงบ้าง ?

สังเกตจากผลของการทำงานจะขึ้นต้นชื่อ module ดังนั้นจึงทำการเขียน code นิดหน่อยเพื่อตรวจสอบว่า Module ใดเปลี่ยนแปลงบ้าง แสดง code ตัวอย่างดังนี้ [code] gitStatus = open('git-update') for statusLine in iter(gitStatus): if statusLine.startswith(“Module01”): ... elif statusLine.startswith(“Module02”): ... elif statusLine.startswith(“Module03”): ... elif statusLine.startswith(“Module04”): ... [/code]

จากนั้นทำการ build ในแต่ละ module ไปเลย

ซึ่งเขียน code ได้ดังนี้ [code] os.system("cd Module01 && mvn clean install") os.system("cd Module02 && mvn clean install") os.system("cd Module03 && mvn clean install") os.system("cd Module04 && mvn clean install") [/code] ผลที่ได้คือ ระบบการ build ด้วย Apache Maven ทำงานได้รวดเร็วขึ้นอย่างมาก ทำให้เราได้รับ feedback จากการ build เร็วขึ้นไปอีก สนุกจริง ๆ เลย

[Robot Framework] สร้าง Image เอาไว้ทดสอบระบบ web ด้วย Docker

$
0
0

retro-robots-vector-hires-1184x592

retro-robots-vector-hires-1184x592 ในการทดสอบระบบ Web application ด้วย Robot framework หนึ่งในปัญหาและสิ่งที่ต้องทำซ้ำ ๆ เสมอคือ
  • การติดตั้ง python
  • การติดตั้ง library ต่าง ๆ เช่น robot framework และ selenium2library ผ่าน pip
ยังไม่พอนะ ยิ่งนำการทดสอบไปทำงานร่วมกับระบบ Continuous Integration ด้วยแล้ว ก็ยิ่งลำบากในการติดตั้งอีก เช่น
  • การ configuration
  • การทดสอบแบบ Headless ผ่าน Xvfb virtual display
ซึ่งทั้งหมดนี้ทำบ่อยจนน่าจะเบื่อแล้ว ดังนั้นมาลองทำ image ด้วย Docker ไว้ใช้กันดีกว่า

เริ่มต้นด้วยสิ่งที่ต้องการประกอบไปด้วย

  • ระบบปฏิบัติการใช้ Alpine เพราะว่าเล็กดี
  • ติดตั้ง python และ pip
  • ติดตั้ง robot framework
  • ติดตั้ง selenium2library สำหรับทดสอบระบบ web application
  • ติดตั้ง firefox และ google chrome รวมทั้ง chrome driver
  • ติดตั้ง Xvfb virtual display
ดังนั้นจึงสร้าง Dockerfile ไว้ดังนี้ [gist id="ea2db1bed29f2145b55382561607274d" file="Dockerfile"]

โดยก่อนที่จะทำการสร้าง container มาใช้งานนั้น

ต้องทำการกำหนดค่าต่าง ๆ เหล่านี้ก่อน
  • กำหนดค่าต่าง ๆ สำหรับ Xvfb เช่น ความละเอียดของหน้าจอ
  • ทำการ start Xvfb
  • ทำการ run ชุดการทดสอบ ซึ่งอยู่นอก container ดังนั้นจึงต้องส่งเข้ามาเอง
  • หยุดการทำงานของ Xvfb
สามารถเขียน shell script ได้ดังนี้ [gist id="ea2db1bed29f2145b55382561607274d" file="run.sh"]

เมื่อทุกอย่างเรียบร้อยก็ทำการสร้าง image ด้วยคำสั่ง

[code] docker build -t docker-robot-framework . [/code]

จากนั้นทำการ run container เพื่อทดสอบระบบงานด้วย robot framework

โดยชุดการทดสอบตัวอย่าง จะอยู่ใน folder ชื่อว่า robots ซึ่งอยู่นอก container ดังนั้นจึงต้องกำหนด volume เข้าไปด้วยเสมอ ใช้งานด้วยคำสั่ง [code] docker run --rm \ -e ROBOT_TESTS=/robots/ \ -e BROWSER=firefox \ -v $(pwd)/robots:/robots \ -ti docker-robot-framework [/code] ผลการทำงานเป็นดังนี้ result-robot-01 เพียงเท่านี้ก็สามารถนำไปใช้งานแบบสบาย ๆ แล้วครับ ตัวอย่างของ Dockerfile อยู่ที่ Github::Robot Alpine Docker ปล. ยังมีปัญหากับ google chrome นะ

คำแนะนำดี ๆ สำหรับ Android Developer 

$
0
0

android-02

android-02 จากประสบการณ์การพัฒนา Android app อันเล็กน้อย เลยนำมาสรุปไว้นิดหน่อยรวมกับข้อมูลจาก website ต่าง ๆ ซึ่งอาจจะเป็นประโยชน์บ้างสำหรับ Android Developer เพื่อที่จะไม่ต้องมาผิดซ้ำรอยกันอีก มาเริ่มกันเลยดีกว่า

Don’t Reinvent the Wheel

น่าจะเป็นเรื่องที่พูดถึงกันอย่างมาก เนื่องจากการแก้ไขปัญหาพื้นฐานต่าง ๆ นั้น ถูกสร้างเป็น library ให้ใช้งานกันเยอะมาก ๆ ดังนั้นลดการสร้างการทำงานพื้นฐานด้วยตนเองลง เน้นไปที่ business logic ของ app ให้มากขึ้น ในปัจจุบันก็มีที่รวบรวม Android Library มากมาย เช่น แต่บางเรื่องเราต้องรู้ด้วยว่า สิ่งที่นำมาใช้นั้น เราต้องการมากเพียงใด ? สิ่งที่นำมาใช้นั้น มันมากเกินความจำเป็นหรือไม่ ? บางครั้งเราทำการแก้ไข code ของสิ่งที่นำมาใช้ ถึงขั้นที่จำ code เดิมไม่ได้กันเลย คำถามคือ เขียนใหม่ขึ้นมาเองน่าจะดีกว่านะ !!

ตั้งสติก่อนเลือก Library ใด ๆ มาใช้

เนื่องจาก library มีจำนวนมาก แม้จะทำงานในเรื่องเดียวกัน คำถามคือ จะเลือกอย่างไรดีล่ะ ? จาก link เรื่อง Must have libraries เป็นจุดเริ่มต้นที่ดี ลองไปดู library บน github ด้วยนะว่า จำนวน star เยอะไหม ? มี issue ที่ยังไม่ทำการแก้ไข หรือ ปิดเยอะไหม ? มีคนใช้งานเยอะไหม ? เพื่อทำให้มั่นใจว่า สิ่งที่นำมาใช้มันเสถียรเพียงพอต่องานของเรา ที่สำคัญอย่าลืมว่า เราเข้าใจมันจริง ๆ หรือไม่ ? อย่าใช้เพียงคนอื่นบอกว่าดี ถ้าเราไม่รู้และไม่เข้าใจว่า library ทำงานอย่างไรแล้ว การนำมาใช้งานมันมีแต่ผลเสีย !! คำแนะนำ สามารถทดลองใช้งาน library ของ Android ผ่าน DryRun ได้นะ

ให้เวลาสำหรับการอ่าน code ให้มาก ๆ

ถ้าถามว่าใช้เวลาในการอ่าน code มากเท่าไรดีล่ะ ? ตอบง่าย ๆ เลยคือ มากกว่าเวลาในการเขียน code ถ้า developer คนใดยังไม่ทำ เริ่มได้เลยนะ
อ่านเพื่อเรียนรู้ อ่านเพื่อให้เข้าใจ อ่านเพื่อสะท้อนตัวเราเอง อ่านเพื่อให้เราโต อ่านเพื่อให้เราพัฒนา

ต่อมาก็เรื่อง Coding standard !!

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

โครงสร้างของ Android project ก็สำคัญมากเช่นกัน

การเลือกโครงสร้างของระบบให้ดี ก็เป็นสิ่งหนึ่งที่สำคัญอย่างมาก มิเช่นนั้นแล้วโครงสร้าง code จะมั่วมาก ๆ ส่งผลให้ยากต่อการดูแลรักษาทั้งแก้ไข และ ปรับปรุง รวมทั้งต้องใช้เวลาดูแลรักษาเยอะอีก !! ดังนั้นแนะนำให้ลองเลือกโครงสร้างดี ๆ ตั้งแต่ต้น แต่ระวังเรื่องของ Over-engineer นะครับ !! เพราะว่าบางครั้งสิ่งที่ดี อาจจะไม่เหมาะสมก็เป็นได้ โครงสร้างของระบบมีเยอะเลย เช่น MVC, MVP, MVVM และ VIPER เป็นต้น หรือไปอ่านและศึกษาเพิ่มเติมได้จาก

เรื่องของ Proguard มันจำเป็นอย่างยิ่ง

ก่อนนำ APK ขึ้น Play store นั้นต้องผ่าน pro guard เสมอนะ จะช่วยลดจำนวน code ที่ไม่จำเป็นต้องใช้งานลงไปแล้ว ยังช่วยทำให้ code ของ app อ่านไม่รู้เรื่องอีกด้วย เนื่องจาก APK ของ app อาจจะโดน reverse engineer มาดู code ก็ได้นะ แต่ถ้า app ของคุณต้องการความปลอดภัยสูง ก็แนะนำให้ใช้ DexGuard ด้วย

App ไหนยังไม่ติด Analytic กันบ้าง ?

ผมคิดว่า มีน้อย app ที่ยังไม่ติด Analytic เพื่อดูเรื่อง
  • พฤติกรรมการใช้งาน
  • Performance ของ app
  • Crash report ต่าง ๆ
แต่ถ้ายังขอแนะนำ Firebase และ Fabric รวมทั้งการ optimize app เช่นการตรวจเรื่อง memory leak ด้วย Leak Canary ซึ่งจะช่วยลดเวลาในการค้นและแก้ไขลงไปเยอะมาก ๆ

ลดเวลาการ Build app ของ Gradle ลงกันบ้าง

ปัญหาหลักของ Android app ขนาดกลางและใหญ่ คือ Build Time ที่นานมาก ๆ !! แต่ก็ยังอดทนนั่งรอกัน ดังนั้นสิ่งที่นักพัฒนาต้องลงมือทำกันก็คือ ลดเวลาการ build ของ Gradle ลงซะ ลดเวลาให้ได้มากที่สุดเท่าที่จะเป็นไปได้ เช่น
  • ลดจำนวน Library และ code ที่ไม่ได้ใช้ออกไป
  • พยายามให้จำนวน method ไม่เกิน 65K (ทำยากมาก ๆ)
แนะนำวิธีการลดเวลาการ build ดังนี้

อีกเรื่องที่ผมจะจำไม่ลืมเลยคือ ให้พัฒนาและทดสอบ Android app บน Device คุณต่ำ ๆ กัน

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

ทดสอบ ทดสอบ ทดสอบ และ ทดสอบ

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

สุดท้ายขอให้หยุดการ Copy and Paste code

ไม่ใช่บอกว่ามันไม่ดี แต่ขอให้เข้าใจก่อนว่า code ชุดนั้นมันทำอะไรได้ หรือ ไม่ได้บ้างก่อนนำไปใช้งานจริง และให้เวลากับการ contribute กลับไปยัง library ต่าง ๆ ที่คุณใช้ หรือ community ของ Android บ้างครับ ทั้งหมดนี้น่าจะพอมีประโยชน์บ้างไม่มากก็น้อยนะครับ ปล. ยังมีเรื่องอื่น ๆ ที่ต้องศึกษาอีกนะ เช่น
  • Refactoring
  • Design pattern
  • Kotlin อีกทางเลือกของการพัฒนา Android app ที่พลาดไม่ได้
  • การใช้งาน Git และ Github/Bitbucket
  • เรื่องของ User Interface และ User Experience
  • จัดการกับ Android Fragmentation
  • ว่าด้วยเรื่องของ Security
Reference Websites Experience 2 years in Android development Become good android developer Clean Architecture

ประโยคที่ต้องถูกตีความ เมื่อนักพัฒนาพูดออกมา

$
0
0

designer-developer

designer-developer ฝนตกช่วงค่ำ ๆ เลยเปิดบทความอ่านเล่น ๆ เจอบทความที่น่าสนใจเรื่อง Software Engineer Cheat Sheet ว่าด้วยเรื่องการแปลความหมายจากสิ่งที่นักพัฒนา software พูดกัน ว่าจริง ๆ แล้วมีความหมายอย่างไร มีหลายข้อที่โดนใจเลยสรุปไว้นิดหน่อย ว่าแต่มีข้อไหนโดนใจคุณบ้างล่ะ ? ทำแบบนี้ไปก่อนนะ เดี๋ยวค่อยกลับมาแก้ไข มีค่าเท่ากับ ต้องใช้แบบนี้แหละนะ ไม่เปลี่ยนหรอก งานนี้มันไม่ชัดเจนเลยนะ มีค่าเท่ากับ ไม่รู้จะทำอย่างไร หรือ ไม่สามารถ copy and paste ได้ ถ้ามีคำถามจากนักพัฒนาว่า ระหว่างทำงานถูกต้อง กับ ทำงานให้รวดเร็ว จะเลือกอะไร ? เดาได้เลยว่า จะไม่มีทั้งคู่ แค่ให้เสร็จยังยากเลย ไม่สามารถทดสอบในส่วนนี้ได้ หมายถึงมันสามารถทดสอบได้ แต่ไม่ทำ ไม่สามารถประเมินเวลาของงานนี้ได้ หมายถึงไม่รู้ว่าจะประเมินอย่างไร ถ้าตอนเย็น ๆ มีการถกเถียงเรื่อง feature กัน นักพัฒนาบางคนอาจจะบอกว่า feature นี้ ผู้ใช้งานไม่น่าจะให้ความสนใจหรอกนะ ทำแค่นี้แหละพอแล้ว หมายความว่า วันนี้ ... มีนัด ขอไปก่อนล่ะ เดี๋ยวไม่ทัน เดี๋ยวค่อยไปทำใน phase 2 เลยนะ หมายถึง เดี๋ยวก็ลืม ๆ feature นี้กันไปเอง เราน่าจะแก้ไข bug ที่มีความสำคัญสูง ๆ ก่อนนะ หมายถึง ขอกลับไปพักผ่อนก่อนนะ ไม่ไหวแล้ววว เรามี technical debt มากเลยนะ หมายถึง เราทำการ copy and paste มากเกินไป ok เสียงสูง ๆ หมายถึง ไม่เห็นด้วย แต่ต้องทำ
ยังมีประโยคไหนที่นักพัฒนาชอบพูดบ้างนะ

[Robot Framework] การแก้ไขปัญหาการทดสอบระบบบน Firefox 48

$
0
0

ff-00

ff-00 วันนี้ทำการ update Firefox หลังจากที่ไม่ได้ update มานาน ๆ ๆ ๆ มาก ทำให้พบกับปัญหาการทดสอบระบบ web บน Firefox 48 ด้วย Robot Framework อาการที่พบเจอเป็นดังนี้ เปิด Firefox ขึ้นมาได้ แต่ไม่เข้าไปยัง url ที่ต้องการ บางครั้ง Firefox ก็ปิดตัวเองไปเลย งานเข้าสิครับ จะแก้ไขกันอย่างไรดีล่ะ ? แสดงผลการทำงานดังรูป ff-01 Error message เป็นดังนี้ [code] [ WARN ] Keyword 'Capture Page Screenshot' could not be run on failure: No browser is open WebDriverException: Message: Can't load the profile. Profile Dir: /var/folders/t5/8kg23s_97z9dw44tfc1d6dqw0000gn/T/tmp4y9Zfw/webdriver-py-profilecopy If you specified a log_file in the FirefoxBinary constructor, check it for details. [/code]

เริ่มจาก version ของ library ที่ใช้งานกันก่อน

  • Python 2.7
  • Robot Framework 3.0
  • Selenium2Library 1.8.0
  • Selenium 2.53.6

มาค้นหาต้นเหตุของปัญหากันหน่อย

ข้อมูลจาก Firefox developer อธิบายว่า ตั้งแต่ Firefox 47 เป็นต้นมานั้น ได้เปลี่ยน Firefox WebDriver ใหม่ชื่อว่า Marionette มีผลทำให้ Firefox WebDriver เดิมใน Selinium 2 ใช้งานไม่ได้นั่นเอง

มาแก้ไขปัญหากันดีกว่า

วิธีการนี้สำหรับคนหัวแข็ง ไม่ยอมทำการ update อะไรเลย ดังนั้นการแก้ไขจึงต้องทำเยอะหน่อยนะ !! มีขั้นตอนดังนี้ 1. ทำการ Download Geckodriver version 0.8.0 มาใช้งาน โดยทำการ download และ extract จากนั้นนำไปใส่ไว้ใน PATH ของระบบ 2. ทำการ run ชุดการทดสอบจะเจอ error ดังนี้ [code] WebDriverException: Message: 'wires' executable needs to be in PATH. [/code] ให้เปลี่ยนชื่อไฟล์จาก geckodriver เป็น wires ซะ !! 3. ยังไม่พอนะ ต้องแก้ไขใน script ของ Robot Framework ก่อนเปิด Browser เพื่อทดสอบดังนี้ [code] ${ff default caps} Evaluate sys.modules['selenium.webdriver'].common.desired_capabilities.DesiredCapabilities.FIREFOX sys,selenium.webdriver Set To Dictionary ${ff default caps} marionette=${True} Set To Dictionary ${ff default caps} binary=/Applications/Firefox.app/Contents/MacOS/firefox [/code] คำอธิบาย
  • ทำการกำหนด marionette ให้เป็น True คือเปิดการใช้งาน
  • binary คือ Path ของ Firefox นั่นเอง
เพียงเท่านี้ก็สามารถทดสอบได้แล้ววววว !!! ชีวิตดูลำบากมาก ๆ ว่าไหม ?

ถ้าไม่อยากแก้ไขปัญหาตามข้างต้น สามารถแก้ไขได้อีก 2 วิธีคือ

วิธีที่ 1 ใช้ Firefox ที่ต่ำกว่า version 47 สบาย ๆ วิธีที่ 2 ใช้งาน Selenium 3 beta ซะ เนื่องจากทำการปรับปรุงครั้งใหญ่  ตัวอย่างเช่น
  • ทำงานร่วมกับ Java 8 ได้
  • สนับสนุนการทำงานร่วมกับ Firefox ผ่าน Gecko Driver
  • สนับสนุนการทำงานร่วมกับ Safari ซึ่งใช้งานผ่าน Apple’s Safari Driver
  • สนับสนุนการทำงานร่วมกับ Edge ซึ่งใช้งานผ่าน Microsoft WebDriver
  • ส่วน IE 9 และ 10 ก็ยังทำงานได้อยู่ ส่วนต่ำกว่านั้นก็แล้วแต่เวรแต่กรรม ซึ่งใช้งานผ่าน InternetExplorerDriver
ดังนั้น update เถอะนะ [code] $pip install -U selenium==3.0.0b2 [/code] แต่เมื่อ run การทดสอบจะเกิด error ดังนี้ [code] WebDriverException: Message: 'geckodriver' executable needs to be in PATH. [/code] ดังนั้นนั้นให้ทำการ Download Geckodriver version 0.10.0 มาใช้งาน โดยทำการ download และ extract จากนั้นนำไปใส่ไว้ใน PATH ของระบบ เพียงเท่านี้ก็สามารถทดสอบระบบ web บน Firefox 48 ได้แล้ว
ส่วนผมเลือกวิธีใช้งาน Selenium 3 beta นะครับ

ทำการตั้งค่า XCode ให้ง่ายต่อการเขียน Test ขึ้นมาบ้าง

$
0
0

icon256

xcode-b-00 เนื่องจากได้แบ่งปันเรื่องการทดสอบแบบอัตโนมัติสำหรับ iOS app ซึ่งแน่นอนว่า พัฒนาบน XCode นั่นเอง โดยการ setting หรือตั้งค่าปกติของ XCode นั้น ไม่ค่อยเอื้อต่อการทดสอบมากสักเท่าไร เนื่องจากจะสลับหน้าและ tab ต่าง ๆ ไปมา น่าปวดหัว ดังนั้นเรามากำหนดค่าใน XCode กันนิดหน่อย โดยความสามารถที่จะใช้งานคือ Behaviors และ Tabs ดังนั้นมาเริ่มกันเลย

กำหนด Behaviors ให้เราใช้งานง่ายขึ้น

ทำการกำหนด Start stage เพื่อแสดงผลการทำงานอย่างชัดเจน และแยกออกไปเป็น tab ใหม่ชื่อ Log ให้อัตโนมัติ จะได้ไม่ต้องเปลี่ยน view ไปมา ซึ่งมันไม่สะดวกเลย สามารถกำหนดค่าได้ดังนี้ ไปที่ Xcode -> Preferences -> Starts ดังรูป xcode-b-01 จากนั้นทำการ build ( Command + B ) จะแสดงผลดังนี้ xcode-b-02

จากนั้นทำการตั้งค่าให้การเขียน Test ง่ายขึ้น

โดยใช้งานผ่าน Assistant Editor ซึ่งอยู่ใน tab ชื่อว่า Coding จะแสดงสองหน้าจอซ้ายขวา โดยซ้ายคือ code test และขวาคือ code ที่เราสร้างขึ้นมา (หน้าจอต้องกว้างหน่อยนะ) แสดงดังรูป xcode-b-03 เมื่อผลการทดสอบผ่านทั้งหมด สามารถกำหนดให้ซ่อน navigator ด้านซ้ายมือ และซ่อน debugger ไปซะ และยังแสดง code ใน tab Coding เหมือนเดิม แสดงการตั้งค่าดังรูป xcode-b-05 และเมื่อการทดสอบไม่ผ่าน ให้ทำการแสดง Issue navigator เพื่อแสดงให้เห็นถึงปัญหาได้อย่างชัดเจน หรือจะแสดง Test navigator ก็ได้นะ แสดงการตั้งค่าดังรูป xcode-b-06 จากนั้นทำการทดสอบในกรณีทดสอบไม่ผ่าน จะแสดง issue ขึ้นมาทางด้านซ้ายทันที ทำให้ไม่ต้องสลับหน้าไปมา แสดงดังรูป xcode-b-07
จากการตั้งค่าต่าง ๆ ในส่วนของ Behaviors นี้ น่าจะช่วยทำให้นักพัฒนาสามารถใช้งาน XCode ได้อย่างมีประสิทธิภาพมากขึ้น รวมทั้งสนุกในการเขียน Test มากขึ้นนะครับ

[Appium] การติดตั้งสำหรับทดสอบ iOS app

$
0
0

appium-00

appium-00 Appium คือ framework สำหรับการทดสอบ mobile app ทั้ง Android และ iOS ซึ่งก่อนเริ่มใช้งานก็ต้องติดตั้ง software ต่าง ๆ ดังนั้นมาทำการติดตั้งสำหรับทดสอบ iOS app กัน Software ที่ใช้งานประกอบไปด้วย

เริ่มด้วยการติดตั้ง Appium Desktop App ก่อน (Appium)

หลังจากติดตั้งแล้วเริ่มใช้งานดังรูป appium-01 หรือถ้าต้องการจัดการเรื่องต่าง ๆ ผ่าน command line ก็สามารถติดตั้งผ่าน NPM ด้วยคำสั่ง [code] $npm install -g appium $appium [/code] จากนั้นทำการกำหนดค่าต่าง ๆ เพื่อให้สามารถทดสอบ Mobile app ได้ ทั้ง Android และ iOS app โดยในบทความนี้เฉพาะ iOS app เท่านั้น เพื่อให้สามารถทดสอบ app ได้ทั้ง Emulator และ device จริง ๆ มาเริ่มกันเลย

1. สำหรับทดสอบบน Emulator

เริ่มด้วยการ configuration ค่าต่าง ๆ ที่ appium server ต้องการตัวอย่างเช่น
  • App Path
  • Device
  • Platform
  • Full reset เพื่อให้ทำการ uninstall และ install app ทุกครั้งในการทดสอบ
แสดงดังรูป appium-02 สิ่งที่จะเหนื่อยหน่อยคือ App Path ถ้าต้องการให้สามารถทดสอบบน Emulator ได้ต้องทำการ กำหนด App Path ไปยัง Application ที่เราต้องการจาก XCode ดังนี้ เข้าไปยัง XCode เพื่อเปิด App ใน Finder แสดงดังรูป appium-03 แต่ folder ที่เปิดขึ้นมาใน Finder นั้นมันผิด !! ดังนั้นให้ทำการเปลี่ยนไป Folder ที่ถูกต้อง ไปที่ Finder -> Go -> Enclosing Finder จากนั้นให้ทำการเลือก Application ใน Folder iphonesimulator ซึ่งเราจะใช้ Application นี้ใน App Path นั่นเอง แสดงดังรูป appium-04 เมื่อทุกอย่างเรียบร้อย ให้ทำการกดปุ่ม Launch เพื่อ Start Appium Server ขึ้นมา แสดงดังรูป appium-05 จากนั้นให้เริ่มการทดสอบด้วย Inspector หรือรูปแว่นขยายนั้นเอง เพื่อใช้ inspect element ต่าง ๆ ของ App ทำให้ง่ายต่อการเขียน code เพื่อทดสอบต่อไป ถ้าทุกอย่างเป็นไปด้วยดี จะแสดงดังรูป appium-06

2. สำหรับทดสอบบน Device จริง ๆ

มีเรื่องให้ปวดหัวนิดหน่อย เนื่องจากต้องติดตั้ง software เพิ่มนิดหน่อยคือ ideviceinstaller สำหรับใช้ติดตั้ง iOS app ไปยัง device จริง ๆ โดยในบทความนี้จะใช้ iPhone ด้วยคำสั่ง [code] $brew install ideviceinstaller [/code] จากนั้นทำการกำหนดค่าต่าง ๆ ใน Appium server 
  • App Path ให้ทำการเลือก Application จาก folder Debug-iphoneos หรือไฟล์ ipa ก็ได้
  • กำหนด device ด้วย UUID
สิ่งที่ยากหน่อยคือ UUID ของ device สามารถหาค่า UUID ได้จากการใช้คำสั่ง [code] $instruments -s devices [/code] หรือดูได้จาก XCode ผ่าน menu Windows -> Devices ดังรูป จะแสดง device และ emulator ทั้งหมด appium-07 แสดงการ configuration ดังนี้ appium-08 จากนั้นให้ทำการ Launch และ Inspector ดูนะ จะพบว่าสามารถเปิด app บน device จริง ๆ ได้ และใช้งาน inspector ได้ปกติ เหมือนกับบน Emulator เลย ปล. ถ้ามีปัญหาเรื่องของ Instrument ก็ให้ทำการ restart เครื่อง device แล้วปัญหาจะหายไปนะครับ !!! [code] Error launching instruments: Instruments crashed on startup [/code]

สุดท้ายแล้ว

อย่าลืม Enable UI Automationใน Emulator และ Device ด้วยนะ เพียงเท่านี้เราก็พร้อมแล้วสำหรับการทดสอบ iOS app ด้วย Appium ซึ่งสามารถเขียน code สำหรับการทดสอบได้หลายภาษามาก ๆ เช่น
  • Ruby
  • Python
  • Java
  • JavaScript
  • PHP
  • C#
  • Robotframework
ขอให้สนุกกับการทดสอบ Mobile app ด้วย Appium นะครับ

จะหลีกเลี่ยง code ที่ …อย่างไรดี ?

$
0
0

house-of-fear

house-of-fear ปัญหาที่นักพัฒนาพบเจอเป็นประจำก็คือ Legacy code (Code ที่ไม่มี test) ซึ่งมีคุณสมบัติเฉพาะตัวนั่นก็คือ พังง่าย !! อาการประมาณว่า แก้ไขตรงนั้นนิดตรงนี้หน่อยแล้วส่วนอื่นพังไปด้วย !! เหมือนกับการแก้ไข bug เพียงตัวเดียวแล้วได้ bug มาอีกเป็นฝูง โดย code เหล่านี้นักพัฒนาต้องเจ็บตัวกันมาทุกคน ไม่ว่าจะมากหรือน้อยก็ตาม เพื่อทำการแก้ไข และ ปรับปรุง code เหล่านี้ให้ดีขึ้น
คำถามที่น่าสนใจคือ แล้วเราจะหลีกเลี่ยง code แบบนี้ได้อย่างไร ?
ปล. ปัจจุบันผมก็ยังคงอยู่กับ code เหล่านี้อยู่ เพียงแต่เราจะจัดการมันอย่างไร เพื่อลดความเจ็บปวดลง เพื่อวันข้างหน้าที่ดีกว่า
อ่านเจอบทความเรื่อง How to avoid brittle code จึงนำมาแปลและสรุปวิธีการจัดการ Legaay code กันหน่อย ซึ่งน่าจะพอมีประโยชน์ต่อนักพัฒนาบ้างนะ

เริ่มต้นด้วยการ update สิ่งต่าง ๆ อยู่อย่างเสมอ

ตัวอย่างเช่น IDE ที่ใช้งาน เจอว่าจะใช้ IDE version เก่า ๆ ไม่ยอม update version ใหม่ ๆ ด้วยเหตุผลคือ เดี๋ยวงานเข้า !! ประเด็นหลักคือ ขี้เกียจ และ กลัวว่าจะต้องทำการแก้ไข เพื่อทำให้กลับมาใช้งานได้เหมือนเดิม รวมไปถึงพวก library และ framework ต่าง ๆ เนื่องจากผู้สร้างจะทำการแก้ไขข้อผิดพลาด ตลอดจนแก้ไข technical debt ต่าง ๆ ให้อีกด้วย แต่เราไม่ !!
ดังนั้นอย่างกลัวที่จะเปลี่ยนแปลง อะไรที่มันทำแล้วเจ็บก็ลงมือทำบ่อย ๆ เดี๋ยวก็รู้และเข้าใจไปเองว่าต้องทำอย่างไร เพื่อลดความเจ็บปวด และแน่นอนว่า จะดีขึ้นเรื่อย ๆ
สรุปคือ อะไรที่มันทำแล้วเจ็บก็ทำมันบ่อย ๆ เพื่อลด และ หลีกเลี่ยงความเจ็บปวด ผมคิดว่า เป็นหนทางที่ดีมาก ๆ และจงเรียนรู้กับความผิดพลาดและเจ็บปวดด้วยนะ ถ้าเราทำอยู่เป็นประจำแล้ว ก็ไม่จำเป็นต้องมาขอเวลาในการ update โน่นนี่นั่นอีกต่อไปนะครับ
แต่มีคำถามว่า เมื่อทำการ update แล้วจะส่งผลกระทบต่อระบบอย่างไรบ้าง ? แน่นอนว่า ตอบได้ยากมาก ๆ เนื่องจาก Legacy code คือ code ที่ไม่มี test

ดังนั้นสิ่งที่ต้องทำคือ เขียน test ขึ้นมานะ (Automated test)

ซึ่งผมจะเน้นในเรื่องของ Unit test เพื่อทำให้เราแน่ใจและมั่นใจว่า เมื่อมีใครก็ตามทำการแก้ไข code แล้ว จะไม่ส่งผลต่อการทำงานของ code ส่วนอื่น ๆ หรือถ้าส่งผลกระทบก็จะรู้ได้อย่างรวดเร็ว ดังนั้นจงตอบคำถามต่อไปนี้
  • เราเขียน unit test แล้วหรือยัง ?
  • unit test ที่เขียนมันครอบคลุม code เพื่อทำให้เรามั่นใจหรือไม่ ?
  • ชุด unit test ทั้งหมดทำงานได้อย่างรวดเร็วหรือไม่ ?
  • ชุด unit test สามารถทดสอบบนเครื่องของนักพัฒนาทุกคนได้หรือไม่ ?

ถ้าต้องการเปลี่ยนแปลงหรือถอดระบบเดิมออกไป เพื่อใส่ของใหม่เข้าไป !!

เป็นสิ่งปกติมาก ๆ สำหรับระบบที่มีอายุสูง ๆ จะต้องมีคนดูแลจำนวนมาก หรือมี tech lead เยอะ ๆ เพื่อดูแลในส่วนต่าง ๆ แน่นอนว่าต้องมีการเปลี่ยนแปลงหรือแทนที่ด้วย technology ใหม่ ๆ ดังนั้นจึงมีแผนที่สวยงามสำหรับการเปลี่ยนแปลงดังนี้
  1. สร้าง abstraction layer หนึ่งขึ้นมาอยู่หน้า component เก่า
  2. สร้าง component ใหม่ขึ้นมา เพื่อจะมาแทนที่ของเก่า
  3. โดยการใช้งานจะผ่าน abstraction layer นี้เสมอ เพื่อให้จัดการว่าจะไปทำงานที่ component เก่าหรือใหม่
  4. จากนั้นจะเริ่มประกาศหรือแจ้งออกไปว่าจะไม่ใช้งาน component เก่าแล้วนะ
  5. เมื่อเวลาผ่านไปสักพักจะทำการลบ component เก่าออกไป
  6. แน่นอนว่าabstraction layer ก็ต้องถูกลบออกไปด้วย !!! แต่ ...
เรากลับพบว่าขั้นตอนเหล่านี้ล้มเหลวอย่างไม่เป็นท่า เนื่องจากมันเป็นการยากมาก ๆ ที่จะลบ component เก่าออกไปทั้งหมด รวมทั้ง abstraction layer ก็ไม่สามารถลบออกไปได้อีก ดังนั้นสิ่งที่ควรตกลงร่วมกันก็คือ Timebox ของ abstraction layer และ component เก่า ว่าจะใช้งานนานเท่าไร (ยิ่งนานยิ่งลบออกยาก) เพื่อกำหนดกรอบเวลาในการทำงาน ไม่ใช่ทำไปเรื่อย ๆ ไม่ใช่ว่าคอยหลบปัญหาไปเรื่อย ๆ ไม่ใช่ว่ามีข้ออ้างไปตลอด

เรื่องต่อมาคือ เราจัดการ Technical Debt กันหรือไม่ อย่างไร ?

มิฉะนั้น code เหล่านี้มันจะกลับมาทำร้ายคุณ และ คนรอบข้างเองนะ เนื่องจากเราชอบพูดว่า เดี๋ยวเอาไว้ก่อน เนื่องจากเราชอบพูดว่า เดี๋ยวค่อยกลับมาทำ เนื่องจากเราชอบพูดว่า เผื่อเอาไว้ก่อน เนื่องจากเราชอบพูดว่า ทำ ๆ ไปก่อน เนื่องจากเราชอบพูดว่า ทำอันโน้นก่อนก็ได้ และเมื่อเวลาผ่านไป เรากลับพบว่า มีสิ่งที่ต้องทำรออยู่เพียบเลย !!
คำถามที่น่าสนใจคือ แล้วที่ผ่านมาเราทำอะไรกันอยู่ แต่เมื่อเราต้องการแก้ไข Technical debt เหล่านั้น ซึ่งมีจำนวนเยอะมาก ๆ
ทีมก็ไม่อยากจะแก้ไข เพราะว่ามันเยอะมาก ๆ แก้ไขไม่ได้หรอกนะ แต่ตอนสร้างสามารถทำได้ !! ส่วนทีม business ก็มองว่าแก้ไขแล้ว ก็ไม่ได้ประโยชน์อะไรนะ feature ก็ไม่ได้เพิ่มขึ้น งานก็ไม่คืบหน้า
ดังนั้นทุกคนจึงรู้สึกว่า มันยากเกินไป ทำไม่ได้หรอก สุดท้ายคือ ปล่อยมันไป !!
แต่สิ่งที่ทีมพัฒนาดี ๆ เขาทำกันก็คือ ถ้ารู้ว่าสิ่งใดที่มันทำให้เกิด Technical Debt ขึ้นมาแล้ว จะไม่ทำสิ่งนั้นซ้ำ ๆ ขึ้นมาอีก นั่นหมายถึง ถ้าของเก่าไม่ลดหรือถูกแก้ไข ก็อย่าสร้างของใหม่เพิ่มขึ้นมา ที่สำคัญคือ ทีมต้องตกลงร่วมกันว่า Technical Debt เหล่านั้นเป็นของทีม ไม่ใช่หน้าที่ของใครคนใดคนหนึ่ง ดังนั้นทุกคนในทีมต้องช่วยเหลือกัน ช่วยกันแก้ไข นั่นหมายถึงทุกคนต้องมีความไว้เนื้อเชื่อใจซึ่งกันและกันด้วย ทีมพัฒนาที่ดีต้องเข้าใจและจัดเรียงงานตามความสำคัญทาง business ทีม business ที่ดีต้องรู้ว่าจะต้องทำการส่งมอบ product ที่มีคุณค่าออกไป ดังนั้นทั้งสองฝ่ายจึงต้องคุยกันในเรื่องของ
  • ความเสี่ยงต่าง ๆ
  • ค่าใช้จ่ายต่าง ๆ
  • ประโยชน์ต่าง ๆ
เนื่องจากถ้าเราไม่สามารถส่งมอบ product ได้แล้ว เมื่อนั้นแหละที่ Technical Debt จะขึ้นมาเป็นปัญหาทาง business และแน่นอนว่า มันส่งผลไม่ดีต่อทุกฝ่าย ดังนั้นมาจัดการ Technical Debt กันเถอะนะ
อย่าลืมว่า code ที่เขาเขียนขึ้นมานั้น มีไว้สำหรับอ่าน และมีไว้สำหรับการดูแลรักษาในอนาคตต่อไป ดังนั้นมาสร้าง code ที่ดี ๆ ขึ้นมาเถอะนะ
สุดท้ายแล้ว เราได้เรียนรู้อะไรจาก Legacy code เหล่านี้กันบ้าง ? หรือว่าสร้างมันขึ้นมาในทุก ๆ ระบบที่เข้าไปเกี่ยวข้อง !!

ว่าด้วยเรื่อง Tab กับ Space ในการเขียน code !!

$
0
0

tabs-spaces

เห็นมีการพูดถึงเรื่องของการใช้ Tab และ Spacebar ใน code ซึ่งในความเป็นจริงมันคือเรื่องของ Coding standard ที่ทีมพัฒนาต้องตกลงร่วมกัน ว่าจะเดินไปในทิศทางไหน โดยในปัจจุบันมีเอกสารหรือแหล่งอ้างอิงจำนวนมาก จึงทำการสรุปมาไว้นิดหน่อย มาเริ่มกันเลย

เรื่อง Coding Standard Guideline เป็นสิ่งสำคัญมาก ๆ

สิ่งที่นักพัฒนาต้องให้ความสำคัญของ Readability ของ code เนื่องจากเราไม่ได้เขียน code เพื่อตัวเราเองเท่านั้น แต่เพื่อให้คนอื่นอ่านและทำความเข้าใจได้ง่ายด้วย ดังนั้นเรื่องของรูปแบบในการเขียน code จำเป็นต้องเป็นไปในทิศทางเดียวกัน โดยในปัจจุบันมี Guideline ต่าง ๆ มากมาย ตัวอย่างเช่นในภาษา Java ส่วนภาษาอื่น ๆ ก็เยอะเช่น ในแต่ละตัวล้วนมีแนวทางของตัวเอง ดังนั้นเราควรเลือกและตกลงร่วมกันซะ ตัวอย่างเช่น
  • การใช้ Tab และ Indent
  • ขนาดความยาวของบรรทัด
  • การตั้งชื่อตัวแปร
  • การจัดการ Exception ต่าง ๆ

เมื่อค้นหาข้อมูลเพิ่มเติมพบว่า

จากงาน Github Data Challenge ทำการสรุปวิเคราะห์ code จาก github ไว้อย่างน่าสนใจ ซึ่งแยกออกตามภาษาโปรแกรม เช่น JavaScript, Java, Python, Scala, Ruby, C# และ PHP มาดูตัวอย่างกันหน่อย มาดูผลของ Tab vs. Spacebar ในแต่ละภาษากัน tabs-spaces

มาดูรายละเอียดสำหรับภาษา Java กัน

เรื่องของ Space vs. Tab จะอยู่ที่ 66% ต่อ 33% แสดงดังรูป code-01 ต่อมาเรื่องของ block statement ว่าด้วยเครื่องหมายปีกกาเปิดนั่นเอง
  • 58% อยู่ในบรรทัดเดียวกัน คั่นด้วย space เดียว
  • 37% อยู่ในบรรทัดใหม่
  • 5% อยู่ในบรรทัดเดียวกันแต่ไม่มี space คั่น
code-02 ต่อมาเรื่องความยาวต่อบรรทัด code-03 การตั้งชื่อต้องมี prefix หรือไม่ ส่วนใหญ่ไม่มีนะ code-04
  ดังนั้นลองกลับมาถามตัวเราสิว่า รูปแบบของทีมเราเป็นอย่างไร ? ได้ทำการพูดคุยตกลงร่วมกันหรือไม่ ? อย่างไร ?
สุดท้ายสำหรับชาว Golang บอกว่าใช้ go fmt สิ จะมาเถียงกันทำไม !! ปิดท้ายด้วย Tab vs. Spacebar แบบฮา ๆ กันครับ https://www.youtube.com/watch?v=SsoOG6ZeyUI Reference Websites https://github.com/outsideris/popularconvention http://blog.takipi.com/tabs-vs-spaces-how-they-write-java-in-google-twitter-mozilla-and-pied-piper http://www.businessinsider.com/google-silicon-valley-tabs-spaces-debate-2016-8

สรุปการแบ่งปันเรื่อง Automated Deployment สำหรับ Mobile App

$
0
0

mobile-app

mobile-app เพิ่งไปแบ่งปันเรื่องระบบ Automated deployment สำหรับ Mobile app มา โดยประกอบไปด้วยส่วนต่าง ๆ เช่น
  • ระบบ API หรือ Backend
  • ระบบ Mobile หรือ Frontend ทั้ง Android และ iOS
มีทั้ง process และเครื่องมือที่ใช้งาน จึงนำมาสรุปไว้นิดหน่อย มาเริ่มกันเลย

ส่วนการทำงานของ Backend หรือ API

สิ่งที่ขาดไม่ได้เลยก็คือ Continuous Integration และ Continuous Deployment นั่นหมายความว่า เมื่อมีการเปลี่ยนแปลง source code และ resource ต่าง ๆ แล้ว จะมีระบบที่ทำงานแบบอัตโนมัติตั้งแต่
  • จัดเตรียม Environment
  • Build process
  • Testing process
  • Deployment process
สามารถใช้จำนวนครั้งการ dpeloy ต่อวัน เพื่อวัดผลการทำงานได้เลย ซึ่งทำให้ทีมพัฒนารับรู้ feedback ต่าง ๆ ได้อย่างรวดเร็ว

ส่วนการทำงานของ Frontend หรือ Mobile

เริ่มต้นด้วย process การทำงาน ซึ่งมีหลายรูปแบบ โดยที่ผมขอแนะนำคือ รูปการทำงานแบบนี้ นำมาจากบทความเรื่อง Automating Mobile Deployment จากทีมพัฒนา AutoCAD 360 1-kpky4g4coe_tql3zuqb9zw โดยการทำงานนั้นสามารถนำแนวคิด Continuous Integration และ Continuous Deployment มาปรับใช้ได้ แต่ในส่วนของการ deploy ต้องรอการ review ในกรณีของ iOS app รวมทั้ง process ต่าง ๆ สำหรับ Mobile app นั้น ยังไม่เสถียรเหมือนกับ Web application และ API (Backend) เท่าไรนัก ยกตัวอย่างเช่น User Interface Testing โดยส่วนใหญ่จะเน้นไปที่ User Experience (UX) คำถามที่น่าสนใจคือ ทดสอบกันตอนไหน ? รวมทั้ง process ต่าง ๆ เหล่านี้มักจะใช้เวลานาน ยังไม่พอนะ พอเอามาพัฒนาและทดสอบ ยิ่งยากและนานเข้าไปใหญ่ แต่ต้องอยู่ในกรอบเวลาที่คนไม่ได้ทำเป็นคนกำหนด !! เช่น
  • เมื่อเพิ่ม Animation ต่าง ๆ เข้ามา
  • ต้องทำการ deploy app
  • ต้องทำการ login
  • ต้องทำการเตรียมข้อมูลต่าง ๆ
  • ต้องการ clear ข้อมูลต่าง ๆ
นี่ยังไม่รวมถึงการทดสอบว่า feature ทำงานได้หรือไม่นะ !!

มีเครื่องมืออะไรช่วยบ้างล่ะ ?

ในการพัฒนา Android และ iOS นั้นมีเครื่องมือช่วยเยอะมาก ๆ (แต่มักไม่นำมาใช้งานกัน !!) ตัวอย่างเช่น User Interface Testing ก็มีให้เลือกมากมาย เช่น
  • Android
    • UI Automator
    • Espresso
    • Appium
    • Calabash
    • Robotium
  • iOS
    • UI Testing + XCTest
    • Appium
    • Calabash
    • Flank
ซึ่งเครื่องมือเหล่านี้ทำงานแบบอัตโนมัติได้อีกด้วย แน่นอนว่ายังต้องมีการทดสอบแบบ Manual เนื่องจากมี scenario ต่าง ๆ ที่ต้องทดสอบมากมาย รวมทั้งเรื่อง User Experience ต่าง ๆ ของการใช้งาน ซึ่งต้องเน้นไปที่กรณีที่จำลอง หรือ ทดสอบแบบอัตโนมัติไม่ได้ หรือ ยาก เพื่อให้เหมาะสมต่อการทดสอบบ้าง

การสร้างระบบ Continuous Integration Server

สำหรับ Mobile app นั้นมันไม่ใช่เรื่องง่ายเลย แต่ก็สามารถทำได้ โดยประกอบไปด้วยสิ่งต่าง ๆ ดังต่อไปนี้ ระบบการ Build ทำงานดังนี้
  • เมื่อทำการเปลี่ยนแปลง source code มายังระบบ Source Control เช่น Git เป็นต้น
  • ระบบ Continuous Integration จะทำการดึง source code มาทำงาน
  • ขั้นตอนการทำงานประกอบไปด้วย compile, unit testing, UI testing และ Code Analysis
  • ถ้าทำงานผ่านจะทำการสร้าง Artifact file ออกมาเช่น APK สำหรับ Android และ IPA สำหรับ iOS
  • จากนั้นทำการ upload Artifact file ไปยัง Server กลางเพื่อทดสอบต่อไป เช่น TestFight, HockerApp, Google Play Beta/Alpha เป็นต้น
สิ่งที่น่าสนใจและต้องใส่ใจคือ การทดสอบ จะถูกแบ่งออกเป็น 3 ส่วนหลัก ๆ คือ
  • Unit testing สำหรับทดสอบการทำงานของ code สำหรับ Mobile app
    • Android ใช้งาน Unit4 และ Android Instrument test
    • iOS ใช้งาน XCTest, Quick และ Nimble
  • Integration testing สำหรับทำการทดสอบการทำงานร่วมกันระหว่าง Frontend และ Backend
  • End-to-End testing สำหรับทดสอบการทำงานทั้งระบบ
    • Android ใช้งาน UI Automator, Espresso, Appium และ Calabash
    • iOS ใช้งาน UI test, Appium และ Calabash

โดย process และเครื่องมือต่าง ๆ เหล่านี้

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

เมื่อ Github เพิ่ม feature สำหรับ project management เข้ามาให้ใช้งานแบบฟรี ๆ

$
0
0

github-00

github-00 จากงาน Universe Conference นั้นทาง Github.com ได้ประกาศ feature ใหม่ ๆ ออกมา มีเป้าหมายเพื่อให้การพัฒนาและดูแล software ให้ดีและง่ายยิ่งขึ้น ประกอบไปด้วย
  • เครื่องมือสำหรับ Project management เพื่อจัดการ issue ต่าง ๆ ให้ง่ายขึ้น
  • การจัดการ Pull request
อยู่ในรูปแบบ Kanban board เช่นเดียวกับ Trello ซึ่งพัฒนาอยู่บน Waffle.io และ Zenhub ดังนั้นมาลองใช้งานดูกัน

เริ่มด้วยการสร้าง Project ใน Repository กันก่อน

github-01 มาสร้าง Project ใหม่กัน github-03 จากนั้นทำการสร้าง Column ต่าง ๆ หรือ workflow ได้เลย github-04

จากนั้นทำการเพิ่มงานต่าง ๆ และ card ต่าง ๆ เข้ามา

โดยนำมาจาก Issue นั่นเอง ซึ่งทำให้เราเห็น issue ต่าง ๆ ดีขึ้น สะดวกขึ้น แถมยังย้าย card ไปยัง column ต่าง ๆ ได้อีกด้วย (Drag and Drop) github-07 สามารถเพิ่ม Note เข้าไปในแต่ละ column ได้อีกด้วย github-05 รวมทั้งสามารถแก้ไขได้ และ ยัง convert ไปเป็น Issue ได้อีกด้วย github-06 เพียงเท่านี้เราก็สามารถจัดการงานต่าง ๆ ของระบบได้แล้ว ขาดแต่เรื่อง report เท่านั้นเอง !! สามารถดู VDO เพิ่มเติมได้ https://www.youtube.com/watch?v=C6MGKHkNtxU

และยังมี feature อื่น ๆ อีกมากมาย เช่น

  • Two-factor Authentication
  • การจัดการ permission ที่ดีขึ้น
  • Platform integration ที่ง่ายขึ้น
  • Github GraphQL API Early Access
  • Github community ทำให้นักพัฒนาดู activity ต่าง ๆ ได้ง่ายและสะดวกขึ้น ลองเข้าไปที่ profile ดูนะครับ
github-02 ขอให้สนุกกับการใช้งาน Github ครับ
Viewing all 2000 articles
Browse latest View live