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

สรุปการสร้าง Smart Contract บน Ethereum ของทีมชาวนา

$
0
0

demo_00

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

ก่อนที่จะไปไกลมาดูขั้นตอนการพัฒนาระบบดีกว่า

ซึ่งทำได้จริง ๆ เพียง
  • การสร้างข้อมูลชาวนา (Farmer)
  • การแสดงข้อมูลชาวนา
  • การสร้างข้อมูลการปลูกข้าวของชาวนา (Story/Activity)
  • การแสดงข้อมูลการปลูกข้าว

โดยการพัฒนาเริ่มจากการออกแบบ Smart Contract ใน Ethereum ก่อน

แน่นอนว่าต้องเขียนด้วยภาษา Solidity มาเริ่มสร้าง Contract กันเลย

1. ตั้งชื่อ Contract ว่า BetterFarmerContract

[gist id="5c596215e24e1ad09f1f56dc9fa8c6af" file="1.sol"]

2. กำหนดโครงสร้างข้อมูลของชาวนาและข้อมูลการปลูกข้าว

กำหนดโดยใช้ struct นั่นเอง [gist id="5c596215e24e1ad09f1f56dc9fa8c6af" file="2.sol"] สิ่งที่พบก็คือ เราไม่สามารถ return Struct ที่เราสร้างออกมาได้ แต่สามารถเรียกผ่านตัวแปร public ได้ นั่นก็คือ ถ้าต้องการดึงข้อมูลชาวนาและข้อมูลการปลูกข้าวทั้งหมด ต้องดึงข้อมูลผ่านตัวแปร farmers และ stories
ปล. การออกแบบยังแย่มาก ๆ นะ แต่ก็ทำให้เข้าใจภาษา Solidity มากยิ่งขึ้น

3. ทำการกำหนด function การทำงาน หรือให้ใช้งานนั่นเอง

โดยประกอบไปด้วย
  • การสร้างข้อมูลของชาวนา
  • การดึงข้อมูลของชาวนาแต่ละคน
  • การสร้างข้อมูลการปลูกข้าวของชาวนาแต่ละคน
  • จำนวนข้อมูลการปลูกข้าวทั้งหมดของชาวนาแต่ละคน
[gist id="5c596215e24e1ad09f1f56dc9fa8c6af" file="3.sol"] ต้องทำการทดสอบผ่าน Browser Solidity ให้ผ่านก่อนนะ แสดงดังรูป demo_01 จากนั้นทำการ deploy contract บน Ethereum Wallet หรือ Mist ได้เลย จะได้ค่า contract address และ contract interface ในรูปแบบ JSON ซึ่งนำค่านี้มาใช้ในการ connect ต่อไป demo_02

4. ทำการพัฒนาระบบงานด้วย web3.js

สิ่งที่น่าสนใจมี 2 เรื่องคือ
  • การสร้างข้อมูลทั้ง farmer และ story/activity
  • การดึงข้อมูลของ farmer และ story/activity
โดยสิ่งที่ต้องการในการสร้างระบบงานคือ สำหรับการสร้างข้อมูล farmer และ story จะให้ทำการสร้าง transaction หรือ block ใหม่ขึ้นมา ส่วนการดึงข้อมูลไม่ต้องสร้าง transaction หรือ block ขึ้นมา ดังนั้นจึงส่งผลต่อการเขียน code ด้วย web3.js ดังนี้ ตัวอย่างการสร้าง Story/Activity ขึ้นมา แสดงดัง code [gist id="5c596215e24e1ad09f1f56dc9fa8c6af" file="4.js"] คำอธิบาย ถ้าเราต้องการให้ทำการสร้าง block หรือ transaction ขึ้นมา ต้องใช้งานผ่าน function sendTransaction() โดยจะทำการสร้าง transaction และส่ง transaction id หรือ hash ออกมาให้ แต่สิ่งที่สำคัญก็คือ transaction นั้นจะยังไม่ถูก confirm จาก node อื่น ๆ !! ดังนั้นถ้าไม่รอจะทำให้ข้อมูลไม่เปลี่ยนแปลง สิ่งที่ต้องแก้ไขก็คือ ผมต้องการให้ระบบงาน รอไปจนกว่า transaction จะถูก confirm จาก node อื่น ๆ ด้วยการสร้าง function ชื่อว่า waitForTransationToBeMined() ขึ้นมา แต่ให้ลองตรวจสอบ 15 รอบเท่านั้น เพื่อไม่ให้ระบบรอนานจนเกินไป โดย code นำมาจากบทความเรื่อง The Blockchain Explained to Web Developers เมื่อ transaction ใหม่ถูก confirm แล้วก็ทำการดึงข้อมูลมาแสดงผล โดยข้อมูลที่ต้องการคือ story/activity ทั้งหมดของชาวนานั้น ๆ ซึ่งเป็น list ของ struct (สามารถออกแบบได้หลายแบบนะ) แต่ที่ผมออกแบบคือ ไปดึงข้อมูลจากตัวแปรชื่อว่า stories [gist id="5c596215e24e1ad09f1f56dc9fa8c6af" file="5.js"] คำอธิบาย ก่อนอื่นต้องดึงข้อมูลจำนวน story/activity ของชาวนาที่ต้องการ แน่นอนว่า ไม่เกิด transaction หรือ block ใหม่ขึ้นมา จากนั้นทำการวน loop เพื่อดึงข้อมูลของแต่ละ story/activity ออกมา ทำให้เรียนรู้ว่า การจะเข้าถึงโครงสร้างข้อมูลแบบนี้เป็นอย่างไร !! และสิ่งที่สำคัญมาก ๆ คือ การทำความเข้าใจกับภาษา Solidity รวมทั้งการออกแบบ data model/structure ของ contract นั่นเอง เพียงเท่านี้ก็สามารถสร้างระบบแบบง่าย ๆ ได้แล้ว และในงาน Blockchain hackathon ก็มีระบบงานที่น่าสนใจ เช่น
  • ระบบ refer ของโรงพยาบาล
  • เกมส์เศรษฐี
  • ซื้อขายสินค้า

สรุปสิ่งที่ได้รับจากงาน iOSDevTH Meetup #7

$
0
0

ios-00

ios-00 วันนี้มีโอกาสไปร่วมงาน iOSDevTH Meetup #7 ของกลุ่ม iOS Developer Thailand จัดที่บริษัท Ascend ตึก AIA รัชาภิเษก มีหัวข้อที่น่าสนใจ 2 หัวข้อคือ
  1. Concurrency on iOS
  2. iOS development at scale

โดยในหัวข้อแรกผมมาช้าจึงไม่ได้จดอะไรมากนัก

เป็นหัวข้อที่ยากที่ลึกน่าดู แต่น่าสนใจมาก ๆ ซึ่งสามารถดูเพิ่มเติมได้จาก Github แน่นอนว่าห้ามพลาดเด็ดขาด เพราะว่าเป็นเรื่องที่สำคัญมาก ๆ ทั้งการจัดการทำงานแบบ Synchornous และ Asynchornous ต้องใช้เวลาย่อยนานมาก ๆ ios-meetup-01

มาในหัวข้อที่สองนั้นเรื่อง iOS development at Scale

เนื้อหานั้นเรียบง่ายมาก ๆ แต่ผมคิดว่ามันคือธรรมชาติของการพัฒนาเลยนะ เนื่องจากการพัฒนาที่ดีคือ ต้องเรียบง่ายและมีเหตุผล

โดยเริ่มที่ Feature development มันคือการเลือก feature ที่จะพัฒนานั่นเอง

เริ่มจากคำที่ทุกคนรู้จักกันดีนั่นก็คือ คำว่า MVP (Minimal Viable Product) อธิบายสั้น ๆ ได้ใจความว่า คือ feature ที่ระบบขาดไปไม่ได้เลย แน่นอนว่า น้อยไปก็ไม่ได้ เนื่องจากไม่มี feature อะไรใช้เลย มากไปก็ไม่ดี เนื่องจากใช้เวลาการพัฒนามากเกินไป ต่อมาว่าด้วยเรื่องขนาดของทีมพัฒนา ซึ่งมากคนมากความ ดังนั้นควรมีจำนวนไม่มาก ถามว่ามีเท่าไร ? ก็เท่าที่จะพัฒนา feature นั้น ๆ ได้ เนื่องจากเมื่อมากคนก็มากความ แถมต้องมีคนอื่นมาช่วยจัดการอีก วุ่นวายไปหมด รวมทั้งการพูดคุยที่จะต้องมากขึ้นแบบทวีคูณ และงานที่ถูกมอบหมายให้นั้นต้องไม่น้อยไปหรือมากไป พอให้กดดันกันบ้าง ที่สำคัญความสามารถและวินัยของคนต้องดีด้วยนะ !!

เรื่องต่อมาคือ Engineering practices สำหรับการพัฒนา

เป็นเรื่องที่ฟังดูแล้วง่าย ๆ แต่น่าสนใจ (ทำได้ยากมาก ๆ)

1. แต่ละส่วนของการทำงานต้องมีขนาดเล็ก (Small)

เช่นขนาดของ class ต้องเล็ก ๆ นั่นคือ class จะมี property หรือ state ที่น้อย แต่ละ class มีหน้าที่การทำงานไม่มาก ส่งผลให้การพัฒนาง่ายขึ้น ส่งผลทำให้การ debug ง่ายขึ้น ช่วยทำให้ปัญหาต่าง ๆ ลดลง ตัวอย่างเช่น การแสดง counter ปกติเราสร้างเพียง ViewController ก็จบแล้ว ถ้าเราลองแบ่งส่วนการทำงานตามหน้าที่ ก็น่าจะแบ่งออกเป็นส่วนต่าง ๆ ดังนี้
  1. ส่วนการแสดงผลคือ View class
  2. ส่วนการประมวลผลเรื่อง counter คือ Counter class หรือ Model
  3. ส่วนเชื่อมต่อทั้ง View และ Model คือ ViewController
  4. แต่ละส่วนเชื่อมต่อกันด้วย delegate
ทำให้แต่ละ class มีขนาดเล็ก ง่ายต่อการดูแลรักษา รวมทั้งการทดสอบอีกด้วย ไม่ว่าเป็น architecture แบบไหนก็ยืดถือแนวทางนี้เช่นกัน ทั้ง MVC, MVP, MVVM, VIPER, Redux

2. สั้น ๆ คือ Performance มันคือ feature ของระบบงาน

ดังนั้นจะไม่ทำหรือไม่สนใจไม่ได้เลย วันนี้คุณทำ profiling แล้วหรือยัง

3. Make it work, Make it right, Make it fast

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

4. เป็นสิ่งที่โดนใจก็คือ จะนำอะไรมาใช้ กรุณาเข้าใจมันให้ดี ๆ ก่อนเสมอ !!

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

5. อย่า hack code มากนัก !!

ลองถามตัวเราเองสิว่า hack code หรือ library ที่นำมาใช้เยอะหรือไม่ มิเช่นนั้นมันจะกลับมาทำร้ายเราเอง เช่น ไม่สามารถ upgrade version ได้

6. แบ่งปันความรู้ (Knowledge sharing)

เรื่องการแบ่งปันความรู้ในทีมในองค์กรเป็นสิ่งที่สำคัญมาก ๆ ไม่ว่าจะอยู่ในรูปแบบไหนก็ตามทั้ง wiki หรือ เอกสาร เช่น ปัญหาและการแก้ไข การใช้งาน component ต่าง ๆ

7. Automate งานที่ทำให้ได้เยอะที่สุดเท่าที่จะเป็นไปได้

เช่น script การทำงานต่าง ๆ ทั้ง การ build การ compile การทดสอบ การ deploy การ release การ review code โดยการทำการแบบอัตโนมัติจะช่วยลดงานต่าง ๆ ลงไป ส่งผลให้มีเวลาไปทำอย่างอื่นที่สำคัญกว่า เช่นการพัฒนาและปรับปรุงระบบงานให้ดีขึ้น

8. ควรต้องมี Engineer Book

เมื่อทีมมีขนาดใหญ่ขึ้น บริษัทมีขนาดใหญ่ขึ้น ปัญหาที่ตามมาคือ การสอน การ training เป็นเรื่องที่ยากขึ้น ดังนั้นถ้ามีหนังสือเพื่ออธิบายและบอกสิ่งต่าง ๆ เช่น
  • การติดตั้ง software ที่จำเป็น
  • การ configuration ต่าง ๆ
  • Coding style guide
  • รูปแบบการทำงาน
ซึ่งเรื่องต่าง ๆ เหล่านี้มันคือพื้นฐานและธรรมชาติของการพัฒนาเลยนะ

[Swift] ทำการ validate ข้อมูลด้วยแนวคิดของ Composite pattern

$
0
0

ios-refactory

ios-refactory วันนี้ทำการ review code ของ iOS app ที่พัฒนาด้วยภาษา Swift พบว่ามีส่วนการ validate หรือตรวจสอบข้อมูลจำนวนมาก และรูปแบบ code ที่เขียนบ่อย ๆ เป็นดังนี้
  • ค่าต้องไม่ว่าง
  • ข้อมูลต้องมีรูปแบบที่ถูกต้องเช่น email , ความยาวของข้อมูล, เป็นตัวเลข เป็นต้น
  • ข้อมูลของ password ซึ่งต้องมีทั้งตัวเลข ตัวพิมพ์เล็กและพิมพ์ใหญ่
  • และอื่น ๆ อีกมากมาย
คำถามก็คือ code ที่เขียนเป็นอย่างไร ? คำตอบก็คือ if-else-if-else ไปเรื่อย ๆ ไงล่ะ !!

คำถามต่อมาก็คือ

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

เริ่มต้นด้วยการกำหนดผลของการ validate ข้อมูล

ซึ่งมี 2 แบบคือ valid และ invalid สามารถเขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="1.swift"]

ในตัวอย่างทำการ validate ข้อมูลของ username

ซึ่งมีการตรวจสอบ 3 กรณีคือ
  1. เป็นค่าว่าง
  2. สั้นเกินไป คือ ความยาวน้อยกว่า 5
  3. ยาวเกินไป คือ ความยาวมากกว่า 10
สามารถเขียน code เพื่อกำหนด error ทั้งสามกรณีได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="2.swift"]

สิ่งที่ต้องการคือ ในการ validate แต่ละกรณีให้แยกออกจากกัน

เพื่อทำให้แต่ละส่วนทำงานอย่างใดอย่างหนึ่งไปเลย (Single Responsibility) ทำให้แต่ละส่วนทำงานมีขนาดที่เล็ก แต่ยังต้องการให้มีรูปแบบและโครงสร้างเดียวกัน จึงทำการสร้าง protocol ของ Validator ไว้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="3.swift"] จากนั้นทำการสร้าง Validator สำหรับการ validate ข้อมูลในแต่ละกรณีไป

กรณีที่ 1 ตรวจสอบค่าว่าง (Empty)

เป็น validator ที่ใช้สำหรับตรวจสอบค่าว่างของข้อมูล ตั้งชื่อไว้ว่า EmptyValidator เขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="4.swift"]

กรณีที่ 2 ตรวจความยาวของ username ว่าสั้นเกินไปหรือไม่

เป็น validator เฉพาะของ username เท่านั้น ตั้งชื่อไว้ว่า UsernameTooShortValidator เขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="5.swift"]

กรณีที่ 3 ตรวจความยาวของ username ว่ายาวเกินไปหรือไม่

เป็น validator เฉพาะของ username เท่านั้น ตั้งชื่อไว้ว่า UsernameTooLongValidator เขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="6.swift"]

เมื่อได้ validator ครบทุกตัวแล้ว ก็มีปัญหาตามมาคือ จะใช้งานอย่างไรดีล่ะ ?

เพื่อให้ได้ตามที่ต้องการคือ สามารถเพิ่ม ลบ และแก้ไขได้ง่าย ดังนั้นจึงทำการสร้าง struct/class สำหรับใช้จัดการกลุ่มของ validator ทำให้สามารถจัดการได้ง่ายขึ้น เขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="7.swift"] จากนั้นทำการสร้างตัวรวม validator สำหรับ username ขึ้นมา และใช้งานดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="8.swift"]

พบว่าด้วยวิธีการนี้ ทำให้เราสามารถสร้างชุด validator ของข้อมูลได้ง่ายขึ้น

ทั้งการเพิ่ม ลบ และแก้ไข ที่สำคัญสามารถเขียนชุดการทดสอบได้ง่ายมาก ๆ อีกด้วย ถึงแม้จะแลกมาด้วยความซับซ้อนที่เพิ่มขึ้น (ควบคุมได้)
Simple not easy !!

ทำการ Review my SSO app ::ต้องใส่ใจเรื่อง security ของ API กันเยอะ ๆ

$
0
0

app-00

app-00 เช้านี้เห็นมีการ share เรื่องระบบ API (Application Programming Interface) ของระบบ my SSO app ซึ่งเมื่อได้เข้าไปลองใช้งานและทำการ decompile code ดูก็พบว่า เป็นไปตามจาก post ข้างต้น
ในฐานะของนักพัฒนาคนหนึ่งคิดว่า เป็นสิ่งที่ทีมพัฒนาต้องให้ความสนใจและใส่ใจ ไม่ว่าจะด้วยเหตุผลใด ๆ ก็ตามเรื่องของ security เบื้องต้นของ app ไม่น่าจะพลาดมากมายขนาดนี้

มาดูว่าระบบเป็นอย่างไร ?

การพัฒนาใช้ Ionic framework สำหรับการพัฒนาแบบ hybrid app นั่นเอง ซึ่งทำให้ง่ายต่อการพัฒนาและพัฒนาครั้งเดียวได้ทุก platform code ที่พัฒนาคือ JavaScript ใน Angular framework นั่นแหละ และใช้ plugin เพิ่มเติมสำหรับการส่ง email เท่าที่ดูคือส่งไปหา helpdesk !! ที่สำคัญ code เหล่านี้มันก็อยู่ในมือถือของผู้ใช้ทุกคน ดังนั้นผมเลยเปิด code มาวิเคราะห์กันหน่อย โครงสร้างของ app ประกอบไปด้วย
  • Router
  • Controller
  • Service
  • Directive
ซึ่งเป็นโครงสร้างมาตรฐานของ Angular อยู่แล้ว

เริ่มที่ Controller เป็นส่วนควบคุมการทำงานต่าง ๆ

ทั้ง app ก็มีเพียง controller เดียวนี่แหละ แต่ละ function ก็จัดอยู่ในรูปแบบที่เรียกว่า Callback hell แสดงดังรูป app-01 ถ้าถามในมุมมองของการ maintain ก็น่ากลัวนิดหน่อย !! ส่วนข้อมูลต่าง ๆ จะเก็บไว้ใน local storage เช่น login แล้วเป็น admin หรือไม่ ? ทำการเก็บข้อมูล user id และ user name !!

ต่อมาดูที่ Service ซึ่งเปิดมาครั้งแรกอาจจะต้องตกใจกันนิดหน่อย !!

จะเจอ ip ทั้ง test server และ localhost ใช้สำหรับการพัฒนา ส่วน production server ต้องเห็นอยู่แล้วเป็นปกติ พออ่าน code ลงมาเรื่อย ๆ ต้องสะดุดกับการเรียกใช้งาน APIs ซึ่งดูแล้วมันคือการส่ง HTTP GET และ POST แบบง่าย ๆ ไม่มีการส่งค่า token หรือ key อะไรไปเลย วิเคราะห์ง่าย ๆ คือ อยากได้ข้อมูล user information ก็ส่ง id ไปเลย ไม่ได้สนใจว่าใครจะเป็นคนร้องขอ ดังนั้นจึงลองเอา url มา copy ใส่ browser ก็ได้ข้อมูลออกมาเลย !! ส่วน id ก็ลองสุ่มมั่ว ๆ ก็ได้ข้อมูลออกมา ซึ่งเป็นสิ่งที่น่ากลัวอย่างมาก
คำถามคือ แล้วตรวจสอบ Authorization อย่างไร ? เท่าที่เห็นคือเก็บค่าใน local storage ไว้เท่านั้น !!
ปล. ตอนนี้หน้า API เป็นแบบนี้แล้วนะ (ปิดระบบนั่นเอง) แสดงว่าทีมพัฒนาได้เห็นข่าวนี้หรือปัญหานี้แล้ว ซึ่งเป็นเรื่องที่น่าชื่นชมอย่างมาก app-02 แต่หน้า Error ยังไม่แก้ไขนะ นี่มัน .NET นะเนี่ย app-03

ถามว่าจะแก้ไขอย่างไร

เริ่มต้นด้วยการ Authentication และ Authorization นะครับ Authentication คือการระบบตัวตนเช่นการ login Authorization คือการตรวจสอบสิทธิ์ในการใช้งาน resource ต่าง ๆ แต่ระบบ API ของระบบ my SSO นั้นมันเปิดเผยอย่างแรงครับ ไม่มีทั้ง Authentication และ Authorization เลย มีแต่ในระดับ app เท่านั้น !! ซึ่งแน่นอนว่า ในกรณีนี้ไม่ได้ช่วยอะไรเลย อย่าลืมว่า framework ที่ใช้พัฒนาคือ hybride และ source code ก็อยู่ในมือของผู้ใช้ทุกคน ดังนั้นมันสุ่มเสี่ยงต่อการโจมตีอย่างมาก !!

ของฝากสำหรับทีมพัฒนาระบบงาน

ถ้าต้องการข้อมูลเพิ่มเติ่มสำคัญการออกแบบและพัฒนา ผมแนะนำบทความเรื่อง
ปล. เรื่องของ security เป็นอีกหนึ่งเรื่องที่นักพัฒนา Software ต้องให้ความสำคัญนะครับ เพราะว่า Security มันคือ function การทำงานที่ต้องมีอยู่ในทุก ๆ feature
Reference Websites https://www.owasp.org/index.php/Mobile_Top_10_2016-Top_10

มาทำการตรวจสอบ Memory Leak ใน Android app กัน

$
0
0

memory-leak-00

memory-leak-00 สำหรับ Android app นั้นปัญหาที่ทำให้ app crash น่าจะมีอยู่สองปัญหาใหญ่ ๆ คือ
  1.  NullPointerException (NPE)
  2. OutOfMememoryError (OOM) หรือ Memory Leak
ทั้งสองปัญหานั้นมีต้นเหตุมาจากประสบการณ์ของนักพัฒนาล้วน ๆ ซึ่ง NullPointerException นั้นสามารถแก้ไขได้ง่ายกว่า ถ้าเขียน code สำหรับการดักจับปัญหาให้ดี ๆ พร้อมทั้งใช้ความสามารถของภาษาเช่น Optional เป็นต้น แต่ว่า OutofMememoryError หรือ Memory Leak นั้น มันเป็นสิ่งที่ตรวจสอบยากกว่าเยอะ แต่ก็ใช่ว่า จะไม่สามารถตรวจสอบและค้นหาได้เลย เนื่องจากปัจจุบันมีเครื่องมือในการทำ profiling มากมาย มาดูว่า เราจะค้นหาและแก้ไขปัญหานี้กันอย่างไร

เริ่มต้นด้วย Error ที่จะเจอแสดงผลดังนี้

[gist id="23cd52fd5b238cc0e685e4f4762223d3" file="1.txt"] สำหรับ Android app นั้นมันเกิดขึ้นได้ง่ายมาก ๆ ถ้านักพัฒนาไม่มีความรู้ความเข้าใจมากนักและไม่ระมัดระวังเพียงพอ มีต้นเหตุหลัก ๆ ดังนี้
  • ใช้ memory แล้วไม่คืนกลับไปยังระบบ
  • มีการใช้ memory มากกว่าที่มีหรือที่จองไว้

มีอะไรบ้างละที่ทำให้เกิดปัญหา Memory Leak ใน Android

เก็บข้อมูลแบบ global ใน Context object มาเกินไป คำถามคือ คุณรู้ไหมว่า App คุณนั้นเก็บข้อมูลอะไรไว้ใน Context บ้าง ? ถ้าไม่รู้จงทำให้รู้ซะ ต่อมาเรื่องของ Activity เนื่องจาก Activity นั้นเป็น subclass ของ Context ดังนั้นปัญหาจาก Context จึงส่งต่อมาด้วยเสมอ ใน Activity มีข้อมูลอะไรที่เป็น static หรือไม่ ? ปัญหาหลัก ๆ เลยก็เช่น View, Drawable เป็นต้น ยังไม่พอนะ ยังมีพวก static variable ต่าง ๆ ที่นักพัฒนาอาจจะรู้และไม่รู้ รวมทั้งการ bind/unbind service ต่าง ๆ รวมทั้งการ register/unregister service ต่าง ๆ รวมทั้งขาดความรู้และเข้าใจ framework/library ที่นำมาใช้งานอีกด้วย ยังไม่เรื่องการใช้งาน extenal resource อื่น ๆ อีก เช่น Network เป็นต้น ลองคิดดูสิว่า ถ้าส่ง request ไปบ่อย ๆ ลองคิดดูสิว่า ถ้ารอ response นาน ๆ หรือเขียน code ไม่ดี ให้ทำการวน loop รอไปเรื่อย ๆ !!
ดังนั้นอย่าเก็บข้อมูลหรือ state ที่เกี่ยวข้องกับ Life cycle ของ Activity ไว้นาน ๆ จะเห็นได้ว่า เราต้องเข้าใจ Life Cycle ของ Activity ให้ดีด้วยนะ

ในการทำงานจริง ๆ นั้น Android Studio ก็มีเครื่องมือไว้ให้ใช้แล้วนะ

นั่นก็คือ Memory Monitoring ทำให้เราเห็นว่า App ที่เราพัฒนานั้น มีการใช้งาน memory อย่างไรบ้าง ? ถ้าพบว่ากราฟการใช้งาน memory ของ App เป็นดังรูป ก็ขอให้รู้เลยว่าคุณกำลังจุดระเบิดเวลาไว้แล้วนะ !! เนื่องจากยิ่งให้งาน App ไป จำนวน memory ที่ใช้งานยิ่งเยอะ ไม่เคยคืน memory ให้ระบบเลยนะ memory-leak-01 ยังไม่พอนะ Android Studio ยังให้เราเข้าไปดูรายละเอียดใน Heap dump ได้อีก ซึ่งทำให้เห็นข้อมูลชัดขึ้น แน่นอนว่า สามารถดูในแต่ละช่วงของเวลาได้เลย จากนั้นจึงนำมาเปรียบเทียบต่อไป memory-leak-02 จากตัวอย่างจะพบว่า String object เยอะมาก ๆ ซึ่งมันคือระเบิดเวลาดี ๆ นี่เอง !! memory-leak-03 เมื่อเราเจอปัญหาสิ่งที่ต้องทำคือ การแก้ไข เพื่อทำให้การใช้ memory มีประสิทธิภาพมากขึ้น นั่นคือใช้เสร็จแล้วก็ต้องคืน แสดงดังรูป memory-leak-04

สุดท้ายนี้คงไม่มีนักพัฒนาคนไหน

จะพัฒนา app ที่พังง่าย ๆ ออกไปให้ลูกค้าใช้งานหรอกนะ !! … Your app หยุดแล้ววววว .. คำถามคือ วันนี้นักพัฒนาทำ profiling ของระบบแล้วหรือยัง ? ถ้ายังจงทำซะ และยังมี library อื่น ๆ ที่น่าสนใจอีกนะเช่น Reference Websites http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html https://developer.android.com/training/displaying-bitmaps/index.html

คำสั่งใน command line ที่ใช้บ่อย ๆ สำหรับการพัฒนา Android app

$
0
0

android-command-line-00

android-command-line-00 ในการพัฒนา Android application นั้นส่วนใหญ่จะทำงานอยู่บน Android Studio แต่ในการทำงานจริง ๆ นั้น สิ่งที่นักพัฒนาต้องใช้งานเป็นคือ command line ใน Android Studio ก็มี command line หรือ terminal ให้ใช้นะ ลองหัดใช้งานดูกันได้
แต่สิ่งที่ยากคือ มีคำสั่งอะไรให้ใช้งานบ้าง ? ดังนั้นมาดูกัน

เริ่มด้วยสิ่งแรกที่น่าจะต้องใช้กันบ้างคือ Gradle

ใครบ้างที่ไม่เคยพิมพ์คำสั่ง gradlew ใน command line ? ถ้าไม่เคยนี่ ถือว่าบาปมาก ๆ ดังนั้นทำก่อนเลย คำสั่ง gradlew คืออะไร ? มันคือ Gradle Wrapper หรือสิ่งที่มาหุ้มการทำงานของ gradle นั่นเอง จะทำการอ่านข้อมูลจากไฟล์ /gradle/wrapper/gradle-wrapper.properties [gist id="cc18f483b8a7a5c14ea540e6c73aca48" file="gradle-wrapper.properties"] ดังนั้นถ้าไม่เคยใช้งาน จะทำการ download gradle ตามสิ่งที่กำหนดไว้ใน distributionUrl อาจจะเจอปัญหาเรื่อง JAVA_HOME และ ANDROID_HOME กันอีก ก็ต้องแก้ไขกันต่อไป android-command-line-02 คำสั่งที่ควรต้องรู้เช่น [code] $gradlew tasks //สำหรับแสดง task ทั้งหมดที่ใช้ได้ $gradlew test //สำหรับทดสอบในระดับ unit test $gradlew cAT //สำหรับทดสอบ Instrumentation test $gradlew assemble //สำหรับสร้างไฟล์ APK $gradlew install //สำหรับติดตั้ง app บน device $gradlew test --offline //สำหรับการ run ใน offline mode [/code]

ต่อมาเป็นสิ่งที่ผมใช้บ่อย ๆ คือ การค้นหา library ด้วย ALFI

ซึ่งสามารถ copy มาใส่ในไฟล์ build.gradle ได้เลย เช่นค้นหา library ชื่อ glide android-command-line-01

ต่อมาทำการทดสอบ Library ต่าง ๆ ผ่าน DryRun

ปกติการนำ library ที่ developer คนอื่น ๆ ทำไว้นั้น บ่อยครั้งเราต้อง
  • ทำการ download จาก github
  • ทำการ sync และ download library
  • ทำการ run project หรือ sample project ดู
  • ทำการทดสอบตามที่ต้องการ
  • ทำการลบทิ้งไปเมื่อมันไม่ใช่
ขั้นตอนการทำงานเหล่านี้สามารถลดด้วยการใช้ DryRun นั่นเอง ด้วยคำสั่งง่าย ๆ คือ [code] $dryrun <url ของ project> [/code]

ต่อมาสำหรับคนที่เขียน Unit test

ปกติแล้วนั้นถ้าสังเกตุให้ดี ๆ ในการ run unit test นั้น จะไม่แสดงผลการทำงานใด ๆ ออกมา ยกเว้นผลการทำงานรวมว่า ผ่าน หรือ ไม่ผ่าน คำถามคือ ถ้าอยากเห็นว่าแต่ละ test case เป็นอย่างไร ? คำตอบคือ ก็ไปดูใน report ไงล่ะ !! แต่มันไม่น่าจะใช่นะ สิ่งที่ต้องการคือ แสดงผลการทำงานใน command line หรือ terminal นี่แหละ ดังนั้นสิ่งที่แนะนำคือ การ configuration ในไฟล์ build.gradle ดังนี้ [gist id="cc18f483b8a7a5c14ea540e6c73aca48" file="build.gradle"] ผลการทำงานเป็นดังนี้ [code] $gradlew test [/code] android-command-line-04

สิ่งสุดท้ายคือ การจัดการ logcat ให้ดูง่าย ๆ

ถ้าใช้งานผ่าน Android Studio น่าจะต้องเข้ามา custom ที่ Preference กันบ้าง android-command-line-05 สำหรับ command line ก็มีนะคือ pidcat ใช้งานง่าย ๆ คือ [code] $pidcat <package name ของ app> [/code] แสดงผลการทำงานดังรูป android-command-line-07  
สุดท้ายแล้ว Developer ที่ดีควรต้องเรียนรู้การใช้งาน command line เพื่อเพิ่ม productivity ของการพัฒนานะ
ปล. ยังมี adb อีกนะ !!

ว่าด้วยเรื่อง Spaghetti Pattern ในชุดการทดสอบ

$
0
0

spaghetti

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

ในบทความนี้จะอธิบายเกี่ยวกับรูปแบบของ Spaghetti Pattern ในชุดการทดสอบ

ว่าเป็นอย่างไรบ้าง ? ว่ามีข้อดีอะไรบ้าง ? ว่ามีข้อเสียอะไรบ้าง ? ในการพัฒนาที่เขียนชุดการทดสอบจะพบว่า จำนวนของชุดการทดสอบจะมากขึ้นเรื่อย ๆ ที่สำคัญมักจะมีรูปแบบ code ที่เรียกว่า anti-pattern มากขึ้นเช่นกัน โดย anti-pattern นั้นคือ รูปแบบของ code ที่เจอเป็นปกติ เป็นวิธีการที่ทำงานได้ เหมาะมาก ๆ พัฒนาได้เร็วมาก ๆ ในขณะนั้น !! แต่เมื่อดูให้ดีพบว่า ทำให้เกิดผลกระทบมากมาย หรือทำให้ชุดการทดสอบพังง่ายมาก ๆ
แต่ถ้าถามว่า มีวิธีการแก้ไขปัญหา หรือ สิ่งที่ดีกว่าหรือไม่ ? ตอบได้เลยว่า มีสิ แต่ ... นักพัฒนาส่วนใหญ่จะบอกว่า ไม่ ไม่มีเวลา เดี๋ยวค่อยกลับทำทีหลัง ไว้มีเวลาค่อยมาแก้ไข ทำให้เสร็จก่อนนะ
สุดท้ายคือ ไม่เคยกลับมาแก้ไขเลย (Later is Never) นี่แหละคือ anti-pattern ที่เกิดขึ้น ซึ่งเป็นแนวคิด และ วินัยของนักพัฒนาที่ไม่ดีเลยนะ ผมคิดว่า นักพัฒนาส่วนใหญ่ไม่เป็นแบบนี้กันหรอกนะ

โดยที่ anti-pattern มีมากมายเช่น

  • Spaghetti Pattern
  • สำหรับ UI testing การเลือก locator ก็สำคัญ
  • ใช้ XPath และ CSS selector มาก ๆ ก็แย่ เพราะว่าเปลี่ยน UI ทีก็พังที !!
  • การใช้ absolute path เยอะ ๆ ก็ทรมาน
  • ถ้าต้องทดสอบชุดการทดสอบแบบ sequential หรือ เรียงลำดับกันก็ไม่น่าจะใช่ เพราะว่า ช้ามาก ๆ
  • แต่ละ test case ต้องทำงานต่อเนื่องกันเสมอ
  • Code ของการทดสอบแต่ละ test case เยอะ ๆ หรือเอาทุกอย่างมากองรวมกัน น่าจะไม่ใช่แนวทางที่ดี
คำถามคือ ถ้าใครเขียนชุดการทดสอบแล้วเป็นลักษณะนี้ บอกได้เลยว่า ต้องเจอปัญหามากมายอย่างแน่นอน สุดท้ายอาจจะทำให้ท้อใจท้อกาย จนทำให้เลิกเขียนเลิกใช้ไปในที่สุด แล้วก็จะบอกว่า มันไม่ work นะ !!
คำถามคือ สิ่งที่บอกว่าไม่ work มันมาจากไหน ? ลองตอบกันดูนะ

มาดูรายละเอียดของ Spaghetti Pattern กันบ้าง

หลัก ๆ มาจากขาดประสบการณ์ในการออกแบบ พูดง่ายว่า ออกแบบได้แย่มาก ๆ ทั้งในแง่ architecture ของระบบ ทั้งในแง่โครงสร้างของ code ทั้งในแง่โครงสร้างของการทดสอบ ตัวอย่างเช่น ชุดการทดสอบมีขนาดใหญ่ ชุดการทดสอบนัวเนีย พัวพันกันไปหมด ชุดการทดสอบหนึ่งต้องรอผลจากการทดสอบหนึ่ง ๆ ชุดการทดสอบซ้ำ ๆ ในเรื่องเดิม ๆ ชุดการทดสอบแก้ไขได้ยากมาก ๆ ชุดการทดสอบไม่ได้อธิบาย business flow อะไรเลย ชุดการทดสอบไม่สามารถทดสอบซ้ำได้ มีตัวแปรระดับ global ในการทดสอบ ซึ่งแต่ละการทดสอบต้องใช้งานร่วมกัน !!
ถ้าระบบงานทำงานช้า ก็แก้ไขชุดการทดสอบให้รอไปสิ !! แบบนี้เจอเยอะมาก ๆ
อธิบายการทำงานยากมาก ๆ ไป ๆ มา ๆ ต้องมานั่ง debug ชุดการทดสอบเหล่านั้นอีก !!
นี่ก็คือรูปแบบคร่าว ๆ ของ Spaghetti นะ มีใครตกอยู่ในสถานการณ์แบบนี้บ้าง ? หรือว่ากำลังลงมือสร้างขึ้นมา ?

แต่ว่ามันก็มีข้อดีนะ ไม่เช่นนั้นคงไม่ทำกัน !!

สามารถเริ่มต้นทำได้เร็ว นั่นคือ Make it work ซึ่งดีมาก ๆ ถ้ามันทำงานได้แล้ว สิ่งที่ต้องตามมาเสมอก็คือ Make it right และ Make it fast แต่พบว่ามักจะไม่ทำกันนะสิ เพราะว่าของมัน work แล้ว ดังนั้นจึงไปทำงานอื่นต่อเถอะนะ !! ช่วยทำให้เขียน code น้อยลง เนื่องจากชุดการทดสอบอื่น ๆ ทำไว้แล้ว ดังนั้น เราก็แค่รอผลการทำงานจากชุดการทดสอบอื่นก่อน จากนั้นจึงนำผลมาใช้งานต่อไป !! ดูเหมือนจะดีนะ เนื่องจากมันคือการ reuse ของที่มี ลดจำนวน duplication code ลงไปมาก ๆ แต่กลับทำให้ชุดการทดสอบผูกติดกันแน่นมาก ๆ ส่งผลให้การทดสอบช้า เนื่องจากต้องรอ ที่สำคัญทดสอบแบบ parallel ไม่ได้อีก !!

สุดท้ายแล้ว ลองกลับไปดูกันหน่อยว่า ชุดการทดสอบที่เขียนขึ้นมาเป็นอย่างไรกันบ้าง ?

มีลักษณะตาม Spaghetti Pattern หรือไม่ ? ถ้าใช่ก็ปรับปรุงเถอะนะ จะได้ไม่เป็นภาระต่อไป แต่ถ้าใครยังไม่เขียนก็กรุณาเขียนด้วยนะ

สรุปการแบ่งปันเรื่อง Functional Interface ใน Java 8

$
0
0

think

think ใน Java 8 นั้นมี feature ที่น่าสนใจมากมาย แน่นอนว่า ความสามารถต่าง ๆ นั้นถูกสร้างขึ้นมา เพื่อลดปัญหาที่เกิดจากตัวภาษา เช่น
  • Lambda
  • Functional Interface
  • Default method ใน interface
เมื่อนำมารวมกับแนวคิดต่าง ๆ จาก Design Pattern ทำให้เห็นภาพต่าง ๆ ชัดเจนมากขึ้น

เริ่มต้นจากแนวคิดที่ได้จากหนังสือ Design Pattern

  • เน้นไปที่ interface เป็นหลัก ไม่ใช่เน้นที่ implementation นะ
  • Composition over Inheritance
นั่นคือในการออกแบบส่วนการทำงานนั้น ให้กำหนด interface ก่อนว่าจะเป็นอย่างไร จากนั้นจึงทำการ implement ในรายละเอียดต่อไป โดยในการ implement ให้เน้นเรื่อง composition มากกว่า inheritance แต่อธิบายไปก็ไม่เห็นภาพ ดังนั้นมาเขียน code กันดีกว่า

ตัวอย่างแรกคือ การบวกลบคูณหาร

เพื่อเป็นการทดสอบความเข้าใจในความสามารถของภาษา ถ้าเราใช้แนวคิดจากข้างต้น สามารถสร้าง interface ชื่อว่า Calculator ได้ดังนี้ [gist id="abde422c8c64db8f75902dc73f1468d5" file="1.java"] จากนั้นทำการสร้างบวกลบคูณหาร จาก interface นี้ ด้วย Lambda แบบสั้น ๆ นิดหน่อย ดังนี้ [gist id="abde422c8c64db8f75902dc73f1468d5" file="2.java"] รูปแบบของภาษาจะแปลก ๆ หน่อยแต่ก็ต้องเรียนรู้กันนะ

ตัวอย่างต่อมา น่าจะทำให้เข้าใจเรื่อง Design Pattern มากยิ่งขึ้น

เป็นตัวอย่าง code ที่เจอมาก ๆ ใน code คือ Logger !! จะอธิบายแบบ step-by-step เพื่อให้เห็นปัญหา และ แนวทางในการแก้ไขปัญหา ทั้ง inheritance ทั้ง composition ทั้ง Functional interface ใน Java 8 มาเริ่มกันเลย

ขั้นตอนที่ 1 สร้าง Logger อย่างง่ายมาใช้งานก่อน

แน่นอนว่า เริ่มจาก interface นั่นแหละ และทำการแสดง log message ออกไปที่ console สามารถเขียน code ได้ดังนี้ [gist id="abde422c8c64db8f75902dc73f1468d5" file="3.java"]

ขั้นตอนที่ 2 ถ้าต้องการใส่ filter ใน logger จะต้องทำอย่างไร ?

[gist id="abde422c8c64db8f75902dc73f1468d5" file="4.java"] แน่นอนว่า เราต้องการใส่ filter ได้หลายรูปแบบตามที่ต้องการ ดังนั้นสิ่งที่สำคัญมาก ๆ คือ การคิด (Thinking before Coding) ว่าจะออกแบบ จะสร้างออกมาอย่างไรดี ? โดยแนวคิดที่ผมพอจะคิดได้เป็นดังนี้

แนวคิดที่ 1 คือ Inheritance

ถ้าเทียบใน Design pattern คือ Template method pattern นั่นเอง ดังนั้นเราต้องสร้าง abstract class ขึ้นมา เพื่อกำหนด template ของ Logger ที่มี filter สามารถเขียน code ได้ดังนี้ [gist id="abde422c8c64db8f75902dc73f1468d5" file="5.java"] ดังนั้นใครที่ต้องการใช้งานก็ให้สร้าง class ที่ extend จาก abstract class นี้ซะ ตัวอย่างคือ TestLogger จะทำการแสดง log message เฉพาะที่ขึ้นต้นด้วยคำว่า Test เท่านั้น สามารถเขียน code ได้ดังนี้ [gist id="abde422c8c64db8f75902dc73f1468d5" file="6.java"]

แนวคิดที่ 2 คือ Composition

เป็นแนวคิดที่หนังสือ Design pattern แนะนำให้คิดและออกแบบก่อน เนื่องจากเป็นวิธีการที่เรียบง่ายกว่า โดยทำการสร้าง class สำหรับรวม Logger และ Filter ไว้ ด้วยการ injection dependency ต่าง ๆ เข้าไป จากตัวอย่างเป็นการใช้ Constructor Injection ดังนี้ [gist id="abde422c8c64db8f75902dc73f1468d5" file="7.java"] การใช้งานก็ไม่ยาก [gist id="abde422c8c64db8f75902dc73f1468d5" file="8.java"] มาถึงตรงนี้น่าจะทำให้เห็นว่า ระหว่างแนวคิด Composition และ Inheritance นั้นเป็นอย่างไร ? อะไรยากกว่า ? อะไรง่ายกว่า ? ซึ่งมันขึ้นอยู่กับบริบทหลาย ๆ อย่างนะครับ จากตัวอย่างมันเอื้อให้แนวคิด composition เท่านั้นเอง

แนวคิดที่ 3 ใช้ความสามารถของ Java 8 คือ default method ใน interface

เป็นวิธีการที่ Java Developer น่าจะต้องรู้จักไว้บ้างนะ ถ้ายังไม่รู้ก็รู้ไว้ซะ จะใช้งานหรือไม่ ก็ไม่เสียหายอะไร สิ่งที่ต้องการให้เห็นคือ ตัวภาษา Java พยายามจะแก้ไขปัญหาของภาษามันเอง โดยจากตัวอย่างนี้ เราไม่ต้องสร้าง class อะไรมาเลย ใช้เพียง default method ใน interface กับความสามารถของ Functional Interface เลย เขียน code ได้ดังนี้ [gist id="abde422c8c64db8f75902dc73f1468d5" file="9.java"] ส่วนการใช้งานก็เหมือนกับ composition นั่นเอง เห็นไหมว่า วิธีการนี้ช่วยลดและแก้ไขปัญหาไปพอสมควร ทำให้เราเห็นวิธีการแก้ไขปัญหาอีกมุมนะครับ

คำถามคือ จะใช้แบบไหนดี ?

คำตอบคือ ทีมคุณไง ว่าสามารถดูแลรักษา code แบบไหนได้ดี และที่สำคัญเขียนชุดการทดสอบคลุมหรือยัง ? จะได้ไม่กลัวในการเปลี่ยนแปลง

เป้าหมายหลัก ๆ ของการแบ่งปันครั้งนี้เพื่อ

  • เข้าใจ feature ต่าง ๆ ใน Java 8 ว่ามีที่มาอย่างไร และช่วยอะไรบ้าง ?
  • เข้าใจว่าปัญหาคืออะไร และมีความพยายามแก้ไขอย่างไร
  • Design pattern คือสิ่งที่บอกปัญหาของภาษานั้น ๆ
  • Design pattern เกิดจากปัญหาที่เกิดขึ้นซ้ำ ๆ จึงมีคนคิด solution ไว้ให้ คำถามคือ คุณเห็นปัญหาหรือยัง ? ถ้ายังอย่างเพิ่งนำมาใช้
สำหรับ Java Developer วันนี้คุณรู้จัก feature ต่าง ๆ ใน Java 8 แล้วหรือยัง ?
สำหรับ source code ตัวอย่างอยู่ที่ Github:: Up1:: Demo โดย slide อยู่ที่นี่ [slideshare id=69918048&doc=sck-design-pattern-161207151218&w=640&h=480]

ตัวอย่างการวางโครงสร้างระบบด้วย Spring Boot

$
0
0

spring-boot-00 เนื่องจากต้องทำการแนะนำและวางโครงสร้างระบบงานที่พัฒนาด้วยภาษา Java โดยสิ่งที่ต้องการคือ ระบบ REST APIs ง่าย ๆ ซึ่งทางเลือกในภาษา Java ก็มีมากมายทั้ง
  • Servlet 3
  • JAX-RS
  • Jersey
  • Spring MVC
  • Spring Boot
  • Drop Wizard
คำถามแรกคือ จะเลือกอะไรดีล่ะ ? คำตอบคือ ความต้องการของระบบเป็นอย่างไร ? ความสามารถของทีมเป็นอย่างไร ? ตอบด้วยคำถาม นี่มันกวนจริง ๆ นะ !! ถ้าทีมมีความรู้และความเชี่ยวชาญไม่มาก แนะนำว่าแค่ Servlet 3 + JSON + JDBC ก็พอแล้ว มันเหลือเฟือมาก ๆ

แต่ในระบบนี้ผมเลือกที่จะเสนอและแนะนำ Spring Boot

เนื่องจากช่วยทำให้เราเริ่มต้นพัฒนาระบบได้ง่าย (ถ้ามีความเข้าใจมันนะ) เนื่องจากเตรียมชุดของ library ที่จำเป็นไว้ให้แล้ว เนื่องจากถูกออกแบบมาให้สร้าง REST APIs ได้ง่าย ที่สำคัญ start service ได้ง่าย ๆ อีกด้วย มี Embedded Webserver ให้ด้วยนั่นก็คือ Tomcat/Jetty มี feature ที่สำคัญอีกคือ Metric และ Healthcheck ของ service มี embedded database ไว้ให้ทดสอบคือ H2 database เข้ากับแนวคิด Microservice มากเลย แต่ปัญหาเดิม ๆ ของ Spring framework ก็คือ Library ต่าง ๆ เยอะ ดังนั้นในการเริ่มต้นก็ต้อง download library ผ่าน Apache Maven ซึ่งใช้เวลานานพอสมควร ขนาดของไฟล์ JAR/WAR มีขนาดใหญ่ เนื่องจากมี library เยอะนั่นเอง แค่เริ่มต้นระบบก็มีขนาดไป ประมาณ 50 MB แล้วนะ (REST + JDBC + ลืมเอา hibernate ออก) ส่วนความซับซ้อนของตัว Spring framework เอง ไม่ต้องพูดถึง ดังนั้นนั้น ก่อนใช้งานต้องเข้าใจมันให้ดีก่อนนะ เพื่อให้เราสามารถจัดการกับความซับซ้อนเหล่านั้นได้

มาเริ่มต้นวางโครงสร้างระบบกันดีกว่า

เริ่มจากการแบ่งระบบเป็น module ย่อย ๆ ดังนี้
  • REST สำหรับ code ของ controller สำหรับกำหนด service ต่าง ๆ เพื่อรับ request และ ส่ง response กลับไป
  • Model สำหรับจัดการข้อมูลจากระบบต่าง ๆ ทั้ง database, external service
โดยในแต่ละ module ต้องมีชุดการทดสอบด้วยเสมอ แน่นอนว่า Spring framework ตอบโจทย์ทั้งหมด ดังนี้
  • สำหรับ REST จะมี MockMvc เอาไว้ทดสอบ
  • สำหรับ Model นั้นใช้งาน JDBC ซึ่งมี Embedded database คือ H2 database ให้ใช้งาน แต่ในระบบตัวอย่างผมใช้ MariaDB ไปเลย
ในการทดสอบของ Spring framework จะทำงานผ่าน SpringJUnit4ClassRunner ซึ่งเป็นการทดสอบในระดับ integration/system test อาจจะใช้เวลามากขึ้นมาหน่อย แต่สิ่งที่ได้รับกลับมาถือว่าคุ้มมาก ๆ ส่วนการตั้งชื่อ package นั้น จะทำการแยกด้วยชื่อ feature ส่วนภายใน package จะประกอบไปด้วย package ย่อย ๆ อะไรก็ตามใจ ข้อดีคือ ทำให้เราเห็น code ทั้งหมดของ feature นั้น ๆ โดยไม่ต้องกระโดดข้าม package ไปมา ตัวอย่างของ Model เป็นดังรูป spring-boot-01 ความต้องการหลักคือ ชุดการทดสอบ ระบบนี้จะทำการเชื่อมต่อไปยัง database ตรง ๆ ผ่าน JDBC กันเลย ที่สำคัญ Spring framework นั้น จะทำการสร้าง table และข้อมูลขึ้นมาให้ทุกครั้งก่อนการทดสอบ เพียงทำการสร้างไฟล์ใน resoources คือ
  • schema.sql สำหรับสร้าง table
  • data.sql สำหรับสร้างชุดข้อมูลเริ่มต้น
ทำให้การเตรียมข้อมูลสำหรับการทดสอบง่ายขึ้นไปอีก ส่วน configuration ของ database อยู่ในไฟล์ application.properties (เปลี่ยนชื่อก็ได้นะ) ในตัวอย่างผมใช้ MariaDB นะ สร้างด้วย Docker ไปเลย สามารถเขียน code ได้ดังนี้ [gist id="b480580de49a4380aa76c08483f301b2" file="UserRepositoryTest.java"] ปล. @SpringApplicationConfiguration มัน deprecated ไปแล้วนะ !!

ต่อมาคือ REST module ซึ่งจัดโครงสร้างคล้าย ๆ กับ Model

แต่ไม่มี JDBC นะ !! ในตัวอย่างจะใช้ Embedded Web Server คือ Apache Tomcat สิ่งที่สนใจก็เช่นเดิมคือ การทดสอบนั่นเอง โดยส่วนนี้จะทำการทดสอบด้วย MockMvc นะ เป็น integration test กันทั้งสายของ feature นั้น ๆ เลย ดังนั้นการเตรียมระบบและข้อมูลจึงมีความสำคัญมาก ๆ สามารถเขียน code ได้ดังนี้ [gist id="b480580de49a4380aa76c08483f301b2" file="FeatureControllerTest.java"] ชีวิตในการพัฒนาระบบด้วยภาษา Java ก็ยาวนิดหน่อย แต่ก็ไม่ได้ยากหากมีความพยายามเพียงพอ

เพียงเท่านี้ก็สามารถตั้ง project structure ด้วย Spring Boot แบบง่าย ๆ ได้แล้วนะครับ

สิ่งที่ต้องคำนึงถึงเสมอคือ ถ้าคุณตั้ง project structure ได้แล้ว จะทดสอบระบบกันอย่างไร ? จะติดตั้งกันอย่างไร ? ต้องคิดถึงก่อนจะเริ่มเขียน code บรรทัดแรก หรือก่อนเริ่ม feature แรกเลยนะครับ จากนั้นจึงลงมือทำและพิสูจน์ให้ได้ ไม่ใช่มานั่งเทียนเขียน architecture ที่ดูสวยหรูกัน !!!
พูดได้ ก็ต้องทำให้เห็นเช่นกัน

สุดท้ายก็ run สิครับด้วยคำสั่ง mvn clean install

ขอให้โชคดีครับกับ Spring Boot นี่คือหนึ่งแนวทางในการแก้ไขปัญหาครับ หรือว่ามันคือการสร้างปัญหากันแน่ !! ตัวอย่างของ code อยู่ที่ Github::Up1::Demo Spring Boot ต่อจากนี้เราก็เอา Docker มาจัดการ Spring Boot ต่อไปนะครับ

สิ่งที่ควรคำนึงสำหรับการสร้าง Docker Image กับ Java

$
0
0

มีโอกาสต้องนำ Docker มาใช้ในระบบงานที่พัฒนาด้วยภาษา Java จากการลงมือทำพบว่า มันไม่ใช่เรื่องง่ายเลย สำหรับการนำระบบงานที่พัฒนาด้วยภาษา Java มาใส่ในโลกของ Container ดังนั้นจึงทำการสรุปสิ่งที่ต้องคำนึงไว้นิดหน่อย น่าจะเป็นประโยชน์สำหรับคนที่กำลังจะเริ่มนะ

1. เริ่มด้วยการเลือก Image ของ JDK (Java Development Kit) ที่มีขนาดเล็ก ๆ

จากการทดลองใช้ image จาก OpenJDK 8 พบว่า
  • OpenJDK แบบ default ซึ่งใช้ os คือ Debian 8 Jessie มีขนาด 643.2 MB (สำหรับ JRE มีขนาด 107.9 MB)
  • OpenJDK แบบใช้ os คือ alpine มีขนาด 145 MB (สำหรับ JRE มีขนาด 107.9 MB)
สิ่งที่คำนึงคือ ขนาดของ image ที่เลือกใช้เป็น base ต้องมีขนาดเล็ก ๆ ไว้ก่อน แต่จัดการได้นะ
จากนั้นเรื่องของ OS (Operating System) ก็สำคัญ จากข้างต้นจะเห็นได้ว่า แต่ละ OS นั้นมีขนาดที่แตกต่างกัน
  • CentOS มีขนาดประมาณ 196 MB
  • Ubuntu มีขนาดประมาณ 127 MB
  • Debian มีขนาดประมาณ 123 MB
  • Alpine มีขนาดประมาณ 5 MB
  • BusyBox มีขนาดประมาณ 1 MB
แนะนำให้เลือก OS ที่มีขนาดเล็ก และ คุณสามารถจัดการได้ง่าย (รู้จักมันดี) เนื่องจากต้องทำการดูแลรักษา เนื่องจากต้องทำการ update version ล่าสุดอยู่อย่างเสมอ ทั้ง OS และ dependency ต่าง ๆ ถ้าเป็น commercial OS ก็ต้องจัดการกันอีกแบบ ปล. สำหรับ Oracle’s JDK นั้นก็มี issue เรื่อง license agreement เหมือนกันนะ ถ้าจะทำการลบไฟล์ที่ไม่ได้ใช้งานออกไป ซึ่งช่วยทำให้ขนาดของ image ลดลงไปอย่างมากมาย ลองไปอ่านบทความนี้เพิ่มได้ Running Java on Docker? You're Breaking the Law

2. ก่อนทำการสร้าง image นั้นใน folder ที่จะสร้างให้มีเฉพาะสิ่งที่ต้องการเท่านั้น

ไฟล์หรือ folder อะไรที่ไม่จำเป็นต่อการสร้าง image ก็ให้ลบทิ้งไปซะ หรือทำการใส่ไว้ในไฟล์ .dockerignore​ ซะ ตัวอย่างสำหรับ Maven project ก็ให้เอา folder target ออกไปซะ หรือพวก configuration ของ IDE หรือพวก configuration ในแต่ละเครื่อง

3. การสร้าง image ของตัวเอง

หลังจากเลือก based image ได้แล้ว ส่วนใหญ่แล้วนั้นเรามักชอบสร้าง image เป็นของตัวเอง ซึ่งจะทำการ configuration ค่าต่าง ๆ ที่ต้องการใช้ แต่แนะนำว่าอย่า hard code ไว้ใน image นะ เช่นทำการกำหนดค่า หรือ path ต่าง ๆ ไว้ในไฟล์ Dockerfile เลย ซึ่งจะทำให้ image ไม่มีความยึดหยุ่น ดังนั้นถ้าอะไรที่ต้องเปลี่ยนบ่อย ๆ ก็ map volume ออกมาซะ หรือกำหนดไฟล์ไว้ให้แก้ไขเลย จะได้จัดการง่ายขึ้นไปอีกนะ

4. เข้าไปดูใน image หน่อยว่าเป็นอย่างไร ?

เพื่อตรวจสอบให้แน่ใจว่า image ที่สร้างขึ้นมา มีโครงสร้างเป็นไปตามที่คาดหวังหรือไม่ หรือเข้าไปแก้ไขไฟล์ต่าง ๆ (ไม่ควรทำนะ สำหรับ image ที่ใช้กันเยอะ ๆ) หรือทำการ debug นั่นเอง สำหรับ container ที่ทำงานอยู่แล้ว สามารถเข้าไปโดยใช้คำสั่ง [code] $docker exec -it <container id> bash [/code] แต่ถ้ายังไม่มี container ก็ใช้คำสั่ง [code] $docker run -it <image> bash [/code] เพียงเท่านี้ก็พอทำให้เราเริ่มต้นใช้ Docker กับ Java ได้แล้วนะ ยังมีเรื่องต้องให้ทำอีกเยอะเลย

แนะนำการพัฒนา Android app ให้ปลอดภัยมากขึ้น

$
0
0

จากเอกสารเรื่อง Best Practice for Security and Privacy ได้อธิบายแนวปฏิบัติต่าง ๆ สำหรับการพัฒนา Android app ให้ปลอดภัย ประกอบไปด้วยเรื่องที่น่าสนใจดังนี้
  • Networking
  • Intent
  • Data storage
  • เรื่องอื่น ๆ เช่น Emulator, Debug, Root, Obfuscation เป็นต้น
ดังนั้นจึงทำการสรุปไว้นิดหน่อย
ปล. มี Android developer คนไหนอ่านและศึกษากันบ้างนะ ?

1. เรื่องของ Network

คงปฏิเสธไม่ได้ว่า Android app ส่วนใหญ่ มีการดึงข้อมูลจาก server ต่าง ๆ ผ่าน internet ดังนั้นเรื่องความปลอดภัยของข้อมูลที่ส่งไปมานั้นมันจึงสำคัญมาก ๆ ลองคิดดูสิถ้ามีคนพยายามมาดักข้อมูลที่ส่งไปมา (Man In The Middle) ระหว่าง Android app กับ server โดยที่ข้อมูลส่งเป็น plain text กันชัดเจนมาก ๆ แถมข้อมูลเหล่านั้นเป็น sensitive data หรือเป็นข้อมูลส่วนตัวของแต่ละคน น่าจะส่งผลไม่ดีอย่างแน่นอน ดังนั้นลองมาตรวจดูสิว่า Android app ของเรานั้นปลอดภัยกันบ้างไหม ?
  • ใช้ HTTPS ไหม ? แต่ถึงใช้ก็ยังไม่ปลอดภัยนะ
  • ข้อมูลที่รับส่งไปมานั้น ทำการเข้ารหัสบ้างหรือไม่ ? encrypt นะ ไม่ใช้ encode !!
แก้ไขข้อมูลเรื่องของ DH  ขอขอบคุณข้อมูลจากบทความเรื่อง ผู้เชี่ยวชาญด้านความปลอดภัยแอพพลิเคชั่นในไทย ?
  • รวมทั้งใช้ SSL pinning เพื่อเสริมความแข็งแกร่งให้มากขึ้น
โดยที่มี library ที่สนับสนุนทั้ง HTTPS และ SSL Pinning เช่น OkHTTP และ Retrofit เป็นต้น
ลองดู app ที่เราพัฒนาสิว่า จำเป็นต้องมีระดับความปลอดภัยของข้อมูลที่รับส่งกันในระดับไหน ?

2. การใช้งาน Intent

ในการติดต่อระหว่าง Android app จะผ่านสิ่งที่เรียกว่า Intent ซึ่งประกอบไปด้วย Explicit intent และ Implicit intent โดยทั้งสองต่างมีข้อดีและข้อเสียดังนี้ Explicit intent ข้อดีคือ ไม่สามารถดักจับข้อมูลที่ส่งไปมาได้ ข้อเสียคือ สามารถใช้ได้เฉพาะใน app เดียวกันเท่านั้น Implicit intent ข้อดีคือ ใช้ที่ไหนก็ได้ ข้อเสียคือ ง่ายต่อการดักจับข้อมูล ดังนั้นถ้าเราใช้งาน Implicit intent โดยที่ไม่ได้เข้าใจ จะทำให้สามารถโดนดักจับข้อมูล หรือ ขโมยข้อมูลได้ง่าย ๆ แต่เราสามารถแก้ไขปัญหานี้ ด้วยการระบบชื่อ package ไปเลยดังนี้ [gist id="8e53a682e2f86601731ab2355a6b48fc" file="1.java"] และถ้ามี service ใด ๆ ไม่ต้องเปิดให้ใครใช้ก็ปิดซะ [gist id="8e53a682e2f86601731ab2355a6b48fc" file="2.xml"]
ดังนั้นถ้าให้ดีแนะนำให้ใช้ Explicit intent เป็นหลักของ app นะครับ

3. เรื่องของ Data Storage

ใน Android app นั้นส่วนใหญ่นักพัฒนา จะทำการเก็บข้อมูลต่าง ๆ ที่ต้องดึงจาก server นั้น มักจะทำการเก็บข้อมูลไว้ในมือถือด้วย เพื่อลดการดึงข้อมูลจากระบบ network ที่สำคัญทำให้ app ทำงานรวดเร็วขึ้นมาก ๆ จะเรียกว่า caching data ซึ่งสามารถทำได้หลายแบบ วิธีการที่ยากต่อการขโมยข้อมูล คือ การสร้างไฟล์ชั่วคราวใน Memory cache ซะ เนื่องจากถ้าต้องการจะขโมยข้อมูลใน Memory cache นั้น ต้องทำการ dump memory เท่านั้น ซึ่งต้อง ROOT access เท่านั้น ข้อมูลที่ต้องเก็บใน caching, database และ shared preference นั้นต้องเข้ารหัสก่อนเสมอ ตัวอย่างเช่นการใช้งาน Cipher เป็นต้น ส่วนข้อมูลที่ต้องเก็บลง SharedPreference ต้องเป็น MODE_PRIVATE เท่านั้น หรือสามารถใช้งาน SecureSharedPreference ก็ได้ อีกอย่างที่สำคัญคือ การเก็บ Key สำหรับ algorithm การเข้าและถอดรหัส เป็นสิ่งที่สำคัญมาก ๆ ถ้า key นี้ถูกขโมยไปได้ง่าย ๆ มันก็แย่เลยนะ แต่ถ้าเก็บไว้ใน app ก็เป็นการยากต่อการซ่อน ดังนั้นสิ่งที่ควรทำคือ สร้างความซับซ้อนในการหาหรือเข้าถึง key นี้ซะ ทั้งการใช้งาน KeyStore แต่มีใน API 18 ขึ้นไป ทั้งการใช้งาน JNI ซึ่งยากต่อการ decompile code ทั้งการซ่อนไว้ในไฟล์ที่ไม่น่าจะอยู่ เช่นซ่อนไว้ในไฟล์รูปภาพเป็นต้น !!
ปล. Algorithm ในการเข้ารหัสข้อมูลมีมากมาย แน่นอนว่าก็สามารถ hack ได้นั่นแหละ แต่ผมคิดว่า ก็ดีกว่าไม่ทำอะไรเลยนะ
วิธีการที่ดีที่สุดคือ อย่าเก็บอะไรไว้ที่มือถือนะครับ !! แต่หลาย ๆ กรณีมันเป็นไปไม่ได้นะ

ยังมีวิธีการอื่น ๆ อีกเช่น

  • ตรวจสอบว่า run อยู่บน Emulator หรือไม่ ?
  • ตรวจสอบว่า device ทำการ ROOT มาหรือไม่ ?
  • ตรวจสอบว่าทำการเปิด debugger ไว้หรือไม่ ? ด้วย code สั้น ๆ Debug.isDebuggerConnected()
  • ก่อนจะ release APK ออกไปใช้ Proguard, DexGuard และ DexProtector กันบ้างหรือยัง ?
  • แนะนำตัวอย่างการใช้งาน Proguard
วันนี้นักพัฒนา Android app สนใจเรื่อง security ของ app กันแล้วหรือยัง ? Reference Websites https://www.owasp.org/index.php/OWASP_Mobile_Security_Project#tab=Top_10_Mobile_Risks https://www.qdtricks.net/android-penetration-testing-apps/ https://medium.com/uptech-team/how-to-make-your-android-application-secured-21c054b371e7#.ek01gzrnz

จัดการ Spring boot application ด้วย Docker

$
0
0

จากบทความเรื่อง การวางโครงสร้างระบบด้วย Spring boot ก็มีถึงกระบวนการ deploy กันบ้าง ซึ่งเลือกที่จะจัดการผ่าน Docker โดยสิ่งที่คิดไว้จะมี 2 container คือ
  1. สำหรับ Database ซึ่งคือ MariaDB
  2. สำหรับการ run ระบบด้วย Spring boot
ดังนั้นมาลงมือทำกันหน่อย เพื่อทำให้กระบวนการพัฒนาและ deploy มันสะดวกสบายมากขึ้น แน่นอนว่า สนุกสนานกันอย่างแน่นอน
ปล. ก่อนที่จะมาใช้ Docker นั้น ขอแนะนำให้ทำการติดตั้งและ configuration แบบปกติให้ได้ก่อนนะครับ ถ้าทำไม่ได้อย่าเพิ่งนำ Docker มาใช้นะ มิเช่นนั้น มันจะงงไปกันใหญ่
มาเริ่มกันเลย

Container ที่ 1 คือ MariaDB

ซึ่งทำการสร้าง container จาก image ของ MariaDB ที่ Docker Hub การสร้าง container สำหรับ MariaDB นั้น สามารถกำหนดได้ง่าย ๆ เหมือนกับ MySQL เลย ดังนี้ [gist id="5ba4a46f5fb1cc37f504ac54aebe6666" file="1.txt"] คำอธิบาย container ชื่อว่า demo กำหนด password ของ root และสร้าง username สำหรับเข้าใช้

Container ที่ 2 คือ Spring boot application ของเรานั่นเอง

ซึ่งมีวิธีการหลายแบบตามความชอบ แต่วิธีการที่เลือกใช้คือ Docker maven plug-in เพราะว่าใช้งาน Apache Maven ในการพัฒนาอยู่แล้ว จะทำการสร้าง image ของระบบงานมาให้ จากนั้นจึงทำการสร้าง container จาก image นี้นั่นเอง วิธีการก็ไม่ยากดังนี้ 1. ทำการเลือก based image ของ Java และสร้าง Dockerfile สำหรับการเพิ่มไฟล์ JAR ของ Spring boot application ชื่อว่า demo-api.jar เข้าไป [gist id="5ba4a46f5fb1cc37f504ac54aebe6666" file="Dockerfile"] 2. เพิ่มขั้นตอนการ build image ใน Apache Maven [gist id="5ba4a46f5fb1cc37f504ac54aebe6666" file="pom.xml"] 3. ทำการ build และสร้าง image ผ่าน Apache Maven ด้วยคำสั่ง [code] $mvn clean package docker:build [/code] ผลที่ได้คือ image นั่นเอง โดยจากตัวอย่างนั้น image ชื่อว่า demo/rest 4. ทำการสร้าง container จาก image จากข้อ 3 สิ่งที่สำคัญก็คือ กำหนด link ไปยัง container ของ MariaDB ด้วย และกำหนด port สำหรับเข้าใช้งานซะนั่นคือ 8080 [gist id="5ba4a46f5fb1cc37f504ac54aebe6666" file="2.txt"] เพียงเท่านี้ก็สามารถสร้าง container ที่เราต้องการขึ้นมาอย่างง่ายดาย และสามารถทำขั้นตอนเหล่านี้ซ้ำแล้วซ้ำเล่าได้เท่าที่ต้องการ ชีวิตของการพัฒนาระบบน่าจะดีขึ้นและสนุกมากขึ้นไปอีกนะ !! หรือถ้าชอบใช้ Docker compose สามารถ config ได้ดังนี้ [gist id="5ba4a46f5fb1cc37f504ac54aebe6666" file="docker-compose.yml"] Reference websites https://spring.io/guides/gs/spring-boot-docker/

Clean Code หนังสือที่นักพัฒนาควรอ่าน

$
0
0

วันนี้มี developer มาถามเรื่องหนังสือเกี่ยวกับ programming ว่าควรจะอ่านหนังสืออะไรบ้าง ?
เล่มแรกที่ผมแนะนำให้อ่านก็คือ Clean Code - A Handbook of Agile Software Craftsmanship
ในหนังสือเล่มนี้อธิบายแนวปฏิบัติที่ดีสำหรับการพัฒนา software ถึงแม้ว่าหนังสือจะเก่าหน่อย แต่เนื้อหาส่วนใหญ่ยังแจ่มมาก ๆ ปล. เป็นหนังสือที่นักพัฒนาต้องอ่านกันเลยนะ ดังนั้นจึงทำการสรุปเนื้อหาหลัก ๆ ไว้นิดหน่อย
  • ว่าด้วยเรื่อง Clean Code เป็นสิ่งที่ developer มืออาชีพต้องทำโดยไม่มีข้อยกเว้น
  • Developer ต้องสร้างระบบที่เรียบง่าย ไม่ว่าภาษาโปรแกรมจะซับซ้อนก็ตาม
  • สิ่งที่คิดและสิ่งที่เขียนออกมาต้องสื่อสารได้อย่างชัดเจนทั้งชื่อและการทำงาน
  • การเขียน code ต้องอ่านง่าย ทั้งโครงสร้างและชื่อ เปรียบได้กับการเขียนหนังสือนั่นเอง
  • เรื่องของ Single Responsibility Principle( SRP) มีความสำคัญอย่างมากสำหรับการออกแบบและพัฒนา
  • เรื่องของ Open Closed Principle (OCP) ก็สำคัญไม่น้อยไปกว่ากัน ช่วยลดผลกระทบจากการเพิ่มและแก้ไข
  • แนวคิด Don’t Repeat Yourself (DRY) เพื่อช่วยลด duplication code ลงไป ซึ่งเป็นปัญหาใหญ่ของการพัฒนา software
  • ให้จำไว้ว่า devloper ใช้เวลาในการอ่าน code มากกว่าการเขียนถึง 10 เท่านั้น ดังนั้นจะลดเวลาของการอ่าน code ลงได้อย่างไร ?
  • การจัดการ exception นั้นถ้าเกิดข้อผิดพลาดขึ้นมา ให้โยน exception ออกไป (อาจจะขัดแย้งกับบางภาษา)
สุดท้ายแล้ว เมื่ออ่านแล้วก็ต้องลงมือทำด้วยนะ
ปล. developer บางคนบอกว่ามีปัญหากับการอ่านหนังสือภาษาอังกฤษ ผลแนะนำให้อ่านและแปลมาเป็นภาษาไทยครับ จากนั้นเอามา review และอธิบายให้คนอื่น ๆ ฟังครับ จะเป็นการอ่านและศึกษาที่สนุกและรวดเร็วอย่างมาก

สรุปสิ่งที่แบ่งปันเรื่อง Software Developement Trends 2017

$
0
0

ได้รับโอกาสให้ไปแบ่งปันมุมมองเรื่อง Software Development Trends 2017 ในงาน IT Trends: Strategic Planning for 2016 จัดโดยสถาบัน IMC ซึ่งมีหัวข้อที่น่าสนใจมากมาย ส่วนในเรื่องของ Software Development Trends 2017 นั้นมีเนื้อหาดังนี้
  • ปัญหาที่พบในการพัฒนา software
  • ว่าด้วยเรื่องกระบวนการคิด
  • ว่าด้วยเรื่องของโครงสร้างองค์กร
  • ว่าด้วยเรื่องของทีม
  • ว่าด้วยเรื่องของเทคโนโลยี
  • ว่าด้วยเรื่องของ programming language trend
เป็นหนึ่งในมุมมองของตัวผมเองที่มีต่อการพัฒนา software มาดูรายละเอียดกันสักหน่อย

ปัญหาหลักที่พบในการพัฒนา software

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

ดังนั้นจึงแนะนำให้เราหยุดคิดกันก่อน (Start with Thinking)

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

โดยที่โครงสร้างขององค์กรมันจะสะท้อนไปยังโครงสร้างของ software ที่พัฒนา

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

มาถึงโครงสร้างของ software ที่พูดถึงกันมาก ๆ คือ Microservice

ข้อดีของ Microservice นั้นดีมาก ๆ แต่ก่อนอื่นลองกลับมาดูระบบงานปัจจุบันก่อนว่าเป็นอย่างไร ทำการจัดกลุ่มของ service ได้หรือยัง ? ทำการสรุป dependency ต่าง ๆ ของแต่ละ service หรือยัง ? ทำการสรุปความซับซ้อนและวุ่นวายของระบบหรือยัง ? ถ้ายัง ลงมือทำก่อนเลย ยังไม่ต้องไปคิดถึงอะไรทั้งนั้น ? ทำให้เรารู้และเข้าใจในสิ่งที่ไม่รู้ก่อน หลังจากนั้นจึงมาทำความเข้าใจกับ Microservice ซึ่งถูกออกแบบว่าให้ fail นั่นหมายความว่า เราไม่ต้องว่าจะ fail ประเด็นหลักคือ เรารู้หรือไม่ว่า service มันจะ fail ? เราสามารถ restart service นั้นกลับคืนมาได้อย่างรวดเร็วหรือไม่ ? ยิ่ง service มีจำนวนมาก การ deploy แบบ manual คงไม่เพียงพอ ดังนั้นเรื่องของ automated deployment จึงสำคัญ ดังนั้นเรื่องของ automated testing จึงสำคัญ ดังนั้นเรื่องของ automated infrastructure จึงสำคัญ รวมไปถึงแนวคิด DevOps, Infrastructure as Code, Continuous Delivery และ Test-Driven Development (TDD)

มาดูเรื่องของ Programming language trend กันบ้าง

พบว่าภาษาที่ได้รับความนิยมยังเป็นกลุ่มเดิม เช่น Java, C, C++, C#, PHP, JavaScript และ Python เป็นต้น แต่กลับพบว่ามีแนวโน้มที่ลดลง นั่นหมายความว่า มีภาษาใหม่ ๆ เกิดขึ้นมา เพื่อแก้ไขปัญหาเฉพาะด้านมากขึ้น หรือที่เรียกว่า Domain Specific Language (DSL) ตัวอย่างเช่น ภาษา Scala, Clojure, Groovy, Rust, Dart, D และ R เป็นต้น แสดงดังรูป

ส่วน programming language อีกกลุ่มที่น่าสนใจก็คือ Data Science

ประกอบไปด้วย
  • SQL
  • Hadoop
  • Python
  • Java
  • R
  • Hive
  • Pig

ส่วนในโลกของ Mobile development ก็สำคัญมาก ๆ

น่าจะหมดไปแล้วสำหรับเรื่องของภาษาในการเขียน ประเด็นสำคัญคือ เรื่องของความปลอดภัยของระบบ (Security) เนื่องจากปัจจุบันเริ่มเข้าสู่ยุดของ Enterprise Mobile App แล้ว ดังจะเห็นได้ว่ามีความต้องการจากองค์กรใหญ่ ๆ เป็นจำนวนมาก ทั้งจาก Banking, Telecom และ Insurance เป็นต้น

อีกทั้งยังมีเทคโนโลยีต่าง ๆ ออกมามาอีกมากมาย

เช่น IoT, Blockchain, Data science, Machine Learning, AR และ VR เป็นต้น คำถามคือ จะเริ่มอย่างไรดี อะไรดี ? คำตอบคืออะไร ? ลองถามตัวเราเองสิว่า ปัญหาที่ต้องการแก้ไขคืออะไร ? ลองถามตัวเราเองสิว่า สิ่งที่ต้องการคืออะไร ? เมื่อรู้ปัญหาและสิ่งที่ต้องการแล้ว จึงลงมือหาวิธีการต่อไป โดย Slide อยู่ที่นี่ [slideshare id=70207379&doc=sck-software-developmenttrends-2017-161216150619&w=640&h=480]

Selenium :: Implicit vs Explicit vs Fluent waiting ใช้งานกันอย่างไร ?

$
0
0

วันนี้มีคำถามเกี่ยวกับการใช้งาน Waiting ใน Selenium สำหรับการรอให้ element มีใน DOM (Document Object Model) สำหรับการรอให้ element มีใน DOM แต่ยังไม่แสดง (Not visible) สำหรับการรอให้ element มีใน DOM แต่ยังไม่สามารถทำอะไรได้ (Not enable, Not clickable) ซึ่งเจออย่างมากสำหรับระบบ frontend ที่พัฒนาด้วยภาษา JavaScript เป็นหลัก คำถามคือ ถ้าใช้ Selenium ในการทดสอบระดับ UI (User Interface) จะต้องทำอย่างไร ? เนื่องจากถ้าเขียนแบบปกติแล้ว test case จะพังง่ายมาก ๆ บางครั้งทดสอบผ่าน บางครั้งทดสอบผิด ทำให้ชุดการทดสอบไม่น่าเชื่อถือเลย คำตอบก็คือ ทำการ delay ไงล่ะ เช่น sleep(5000) คือรอ 5 วินาที ซึ่งเป็นวิธีการที่ง่ายที่สุดแล้ว ใคร ๆ ก็ทำ แต่ข้อเสียคือ จากตัวอย่างต้องรอไป 5 วินาที ลองคิดดูสิว่า ถ้าทำแบบนี้เยอะ ๆ เวลารวมในการทดสอบจะเป็นอย่างไร ? [gist id="d925783ea8e5f706f3bb58c3ce1ef7eb" file="0.cs"] น่าจะใช้เวลามากมาย ซึ่งไม่ค่อยดีต่อการทดสอบแน่ ๆ !! ดังนั้นมาหาวิธีอื่นกันดีกว่านะ

ใน Selenium นั้นมีการรอ (Waiting) ดังต่อไปนี้คือ

1. Implicit waiting 2. Explicit waiting 3. Fluent waiting มาดูรายละเอียดของแต่ละตัวกัน

1. Implicit waiting

เป็นการบอกให้ selenium รู้ว่า เวลาในการหา element แต่ละตัวบนหน้าจอหรือใน DOM เป็นเท่าไร ถ้าหาไม่เจอในเวลาที่กำหนดแล้ว selenium จะทำการโยน exception ออกมา ซึ่ง implicit waiting จะกำหนดก่อนการเปิด browser ขึ้นมา และจะถูกใช้งานในทุก ๆ ครั้งที่หา element ตัวอย่าง code [gist id="d925783ea8e5f706f3bb58c3ce1ef7eb" file="1.cs"]

2. Explicit waiting หรือ Smart waiting

เป็นการรอแบบมีเงื่อนไขที่กำหนด แต่ถ้าไม่เจอ element ตามเงื่อนไนในเวลาที่กำหนด ก็จะทำการโยน exception ออกมา ตัวอย่างของเงื่อนไขเช่น Element นั้นแสดงหรือไม่ ? Element นั้นซ่อนหรือไม่ ? Element นั้น click ได้หรือไม่ ? โดยที่ Explicit waiting จะทำการตรวจสอบค่าใน DOM ประมาณทุก ๆ 500 millisecond [gist id="d925783ea8e5f706f3bb58c3ce1ef7eb" file="2.cs"]

3. Fluent waiting

เป็นการรอขั้นกว่า Explicit waiting นั่นก็คือ การรอแบบมีเงื่อนไขในเวลาที่กำหนด แต่ยังไม่พอนะ เพิ่มความถี่ในการตรวจสอบอีกด้วย (Polling interval) ยังไม่พออีกนะ สามารถ ignore exception ที่เราไม่ต้องการ ทำให้การรอมีความยึดหยุ่นมากขึ้นอีกเยอะ แสดงการทำงานดังรูป จะทำการตรวจสอบทุก ๆ 250 millisecond ตัวอย่าง code [gist id="d925783ea8e5f706f3bb58c3ce1ef7eb" file="3.cs"]

ดังนั้นลองดูสิว่า ระบบที่ทำการทดสอบนั้นเป็นอย่างไร ?

ตัวอย่างเช่น ถ้า element ที่ต้องการหานั้น ต้องสามารถ click ได้ด้วย คำถามคือ คุณจะใช้ implicit waiting หรือไม่ ? ถ้าใช้สิ่งที่ตามมาก็คือ อาจจะหา element เจอ แต่ไม่สามารถ click ได้ เพราะว่า implicit waiting จะจบการทำงานเมื่อเจอ element เท่านั้น ดังนั้นวิธีการที่น่าจะดีกว่าคือ Explicit waiting และ Fluent waiting นะครับ Reference Websites http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp http://toolsqa.com/selenium-webdriver/c-sharp/advance-explicit-webdriver-waits-in-c/ http://toolsqa.com/selenium-webdriver/implicit-explicit-n-fluent-wait/

สรุปข้อมูล library ที่นิยมใช้สำหรับพัฒนา Android App จาก AppBrain

$
0
0

ไปเห็นข้อมูลสถิติของ library ที่ถูกใช้งานบ่อย ๆ สำหรับการพัฒนา Android app จาก AppBrain ซึ่งน่าสนใจดี จึงนำมาสรุปไว้นิดหน่อย โดยผมทำการแยกออกเป็นกลุ่มตามการใช้งานได้ดังนี้
  • UI Component
  • Networking
  • Image loader
  • Database
  • Analytic
  • Crash report
  • Utility
มาดูกันเลย

1. UI Component สำหรับ view component ต่าง ๆ

2. Networking

3. Image loader

4. Database

5. Analytic

6. Crash report

7. Utilities

น่าจะเป็นข้อมูลประกอบการตัดสินใจในการเลือก library มาพัฒนา Android app กันนะครับ

Swift :: สิ่งที่ iOS developer ควรรู้และเข้าใจไว้บ้าง

$
0
0

จากบทความเรื่อง Top 10 Ground Rules for iOS Developers ทำการอธิบายพื้นฐานที่ iOS developer ควรจะต้องรู้ เข้าใจและปฏิบัติตาม ซึ่งมีหลาย ๆ เรื่องที่น่าสนใจ จึงทำการแปลและสรุปบางเรื่องไว้นิดหน่อย

เรื่องที่ 1 คือ Style guide ของการเขียน code

ว่าด้วยเรื่องของรูปแบบของ code รวมทั้ง indent ต่าง ๆ ว่าใช้ space หรือ tab รวมทั้งเรื่องของ {} อีกด้วย ตัวอย่าง code ที่แนะนำ [gist id="df90afe3d63c264974f3b69b3cb17703" file="1.swift"] ข้อมูลเพิ่มเติม Swift style guide จาก github Swift style guide จาก Raywenderlich

เรื่องที่ 2 ลด ละ เลิกการใช้งาน Type? และ Type!

แนะนำให้ใช้รูปแบบนี้แทนนะ เพราะว่าถ้าเป็น nil นี่เละเลยนะ !! ดังนั้นเขียนแบบนี้ดีกว่านะ [gist id="df90afe3d63c264974f3b69b3cb17703" file="2.swift"]

เรื่องที่ 3 ในแต่ละ method ต้องไม่เกิน 20 บรรทัด

รวมทั้งในแต่ละไฟล์ต้องไม่เกิน 200 บรรทัด ส่งผลให้ แต่ละ method มีขนาดเล็ก แต่ละไฟล์มีการทำงานไม่มาก ทำให้อ่านง่าย ทำให้เข้าใจได้ง่าย ลดเรื่อง Gods class และ Massive View Controller (MVC) !!! ดังนั้นเรื่องโครงสร้างของ code จึงสำคัญมาก ๆ ทั้ง MVP, MVVM, VIPER, POP

เรื่องที่ 4 การตั้งชื่อต้องชัดเจน เข้าใจได้ง่าย

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

เรื่องที่ 5 ใช้ guard เถอะนะ

ใช้สำหรับตรวจสอบสิ่งที่เราต้องการ ถ้าไม่เป็นไปตามที่คาดหวังก็จะรู็ได้อย่างรวดเร็ว เป็นสิ่งที่ผมชอบใช้มาก ๆ เพราะว่าเรื่องของ fail fast ตัวอย่างการใช้งาน [gist id="df90afe3d63c264974f3b69b3cb17703" file="3.swift"]

เรื่องที่ 6 ลดการใช้งาน Segues

ถ้าใครใช้ Segues ใน storyboard เยอะ ๆ ส่งผลให้ storyboard เป็นใยแมงมุมกันเลยทีเดียว รวมทั้งทำให้ยากต่อการดูแลรักษาอีกด้วย ดังนั้นแนะนำให้ใช้ Delegate และ Notification ดีกว่านะ หรือใช้พวก RxSwift หรือ ReactiveCocoa ทำให้แต่ละส่วนการทำงานแยกกันชัดเจน
เรื่องสุดท้าย คือ เขียน test หรือยัง ?
 

ความสามารถที่น่าสนใจใน Android Studio 2.3 beta 1

$
0
0

เมื่อวานเพิ่งทำการ update Android Studio 2.3 beta 1 พบว่า project พังสิครับ ทั้ง library ที่ใช้งานต้องทำการ update และสิ่งต่าง ๆ มากมาย ดังนั้นจึงลองไปอ่าน release note ก็มี feature ที่น่าสนใจ รวมทั้งสิ่งที่หายไปก็กลับคืนมา มาดูกันว่ามีอะไรบ้าง

สิ่งแรกคือ Run unit testing with coverage กลับมาแล้ว

หลังจากที่มันหายไปใน version ก่อนนี้ น้ำตามแทบไหล

ต่อมาคือ UI ของ Instant Run ที่เปลี่ยนไป

ทำการแยกปุ่ม Instant Run ออกมาจาก Run app แล้วนะ น่าจะเพราะว่า feature นี้มันไม่ stable เท่าไร ทำให้ผู้ใช้งานสะดวกมากยิ่งขึ้น ไม่ต้องไปเสียเวลาเปิดปิด feature นี้ โดยที่ปุ่ม Run จะเป็นการ run ใน cold swap อยู่นะ ซึ่งเร็วกว่าการ build และติดตั้ง APK แบบเต็ม ๆ ซึ่งจะมีความเสถียรที่ดี

ต่อมาถ้าใคร update แล้วมีปัญหาในการ build

เช่น cache ของ gradle แนะนำให้ใช้งานผ่าน command ดังนี้ [code] $gradlew clean [/code] และทำการ clear cache ของ gradle ด้วย เนื่องจากโดยค่า default แล้วนั้นจะทำการสร้าง cache ไว้ให้ เพื่อประสิทธิภาพการทำงานที่ดีของ gradle แต่บางครั้งก็อาจจะเกิดปัญหาขึ้นมาได้เช่นกัน ใช้คำสั่งดังนี้ [code] $gradlew cleanBuildCache [/code] ปล. เรื่อง cache ของ gradle ยังไม่ปัญหากับ Instant run อยู่นะ จะทำการแก้ไขใน beta 2 !!

ต่อมาเรื่องของ lint ซึ่งทำการเปลี่ยน HTML report เป็น Material design

ซึ่งสวยงามกว่าเดิมมาก ๆ รวมทั้งการแสดง issue และการแก้ไขที่ง่ายขึ้น โดยที่ Lint ใน Android Studio 2.3 มันเปลี่ยนเยอะเลย ถ้าใครไม่เคยใช้ ก็ใช้ผ่านคำสั่ง [code] $gradlew lint [/code] ผลที่ได้คือ report ที่เป็น HTML และ XML

รวมทั้งมีการ update เรื่องของ ConstraintLayout 1.0.0 beta 4 ด้วยนะ

วันนี้ Android Developer ทำการ update Android Studio แล้วหรือยัง ?

เริ่มต้นพัฒนา Android app ด้วยภาษา C# ใน Visual Studio for Mac กัน

$
0
0

หลังจากที่ทาง Microsoft ปล่อย Visual Studio for Mac preview 1 ออกมา ทำให้นักพัฒนาสามารถพัฒนาระบบงานด้วย C#, ASP.NET บน Mac ได้ รวมทั้งสามารถพัฒนา Mobile app ทั้ง Android และ iOS ด้วยภาษา C# แต่ไม่สามารถทำได้ !! แต่ตอนนี้ผมใช้ Visual Studio for Mac preview 2 (7.0 build 560) เราสามารถพัฒนา Android app กันได้แล้ว (นานแล้วนะ แต่เพิ่งเห็น) ดังนั้นมาเริ่มกันเลย

ขั้นตอนที่ 1 สร้าง project สำหรับ Android app

ขั้นตอนที่ 2 ทำการ configuration ของ project

ขั้นตอนที่ 3 มาดู IDE สำหรับการพัฒนากันว่ามีอะไรให้ใช้บ้าง

ก่อนอื่นต้องทำการกำหนด PATH ของ Android SDK, Android NDK, JAVA SDK ใน preferences ให้ถูกต้องก่อน

จากนั้นมาดูโครงสร้างของ project ใน IDE กัน

ประกอบไปด้วย
  • Getting start เป็นเอกสารแนะนำการใช้งาน
  • Package สำหรับเก็บ library ต่าง ๆ โดยเริ่มต้นคือ Android support V4 และ V7
  • Properties สำหรับจัดเก็บไฟล์ AndroidManifest.xml
  • Resources สำหรับจัดเก็บ resource ต่าง ๆ ที่ใช้งานใน app เช่น layout, image และ value ต่าง ๆ
แสดงดังรูป

ทำการเปิดไฟล์ AndroidManifest.xml ขึ้นมา

สามารถกำหนดค่าต่าง ๆ ได้เหมือนการพัฒนาบน Android Studio แต่เพียงมีทั้ง UI และเป็น source ให้เลือกใช้งานตามความต้องการ

ทำการเปิดไฟล์ layout ซึ่งมีนามสกุลเป็น axml

ซึ่งผู้ใช้งานสามารถลาก component ต่าง ๆ มาวางเองได้ รวมทั้งแสดง properties ต่าง ๆ ของ component และสามารถเลือก Device/Theme ได้หมด (หน้าตามันคุ้น ๆ นะ) เมื่อเข้าไปดูใน source ของไฟล์ layout จะพบว่ามันคือ layout ปกติเลย แสดงดังรูป

คำถามคือไฟล์ R อยู่ไหน ?

ใน Visual Studio for Mac นั้นจะอยู่ใน Resources/Resource.designer.cs

จากนั้นมาเขียน code ดีกว่า ต้องเริ่มที่ Activity สิ

รูปแบบของ code ชื่อ method ต่าง ๆ มันคล้าย ๆ เดิมนะ แต่เปลี่ยน syntax เป็น C# เท่านั้นเอง สิ่งที่น่าสนใจคือ การดักจับ action การ Click แสดงดังรูป

เพียงเท่านั้นก็ทำการ Run ทดสอบ App ดีกว่า

ซึ่งจะตัวอย่างนั้นมีเพียงปุ่มให้กดเพิ่มนับเท่านั้นเอง แสดงผลการทำงานดังนี้  
เพียงเท่านี้เราก็สามารถเริ่มต้นพัฒนา Android app ด้วย C# บน Visual Studio for Mac ได้แล้ว ส่วนการใช้งานจริง ๆ ต้องลองกันต่อไปครับ

มาดูสถิติการใช้งาน Library ต่าง ๆ ของ Java project บน Github กันหน่อย

$
0
0

ระหว่างนั่งรอขึ้นเครื่องบินไปต่างจังหวัด เลยมานั่งดูสถิติการใช้งาน Library ต่าง ๆ ของ Java project โดยนำข้อมูลจาก Github.com และ Takipi.com มาใช้ในการวิเคราะห์ ซึ่งได้ผลลัพธ์ที่น่าสนใจดังนี้

ก่อนอื่นใน Github นั้นมี Java project เยอะมาก

โดยทาง Takipi.com นำข้อมูลของ Java project จาก Github

มาทำการวิเคราะห์ ซึ่งเลือกมาจาก Top Java project นั่นเอง ได้ผลลัพธ์ดังนี้ จากข้อมูลพอสรุปได้ว่า
  • Java project ยังคงอุดมไปด้วย logging ทั้ง slf4j, log4j, logback และ common logging
  • Java project มากกว่าครึ่งใช้งาน JUnit และ Mockito ซึ่งใช้สำหรับการทดสอบระบบงาน เป็นสิ่งที่ดีมาก ๆ
  • มีการใช้งาน Google Guava เป็นจำนวนมาก ถ้าใครไม่รู้ศึกษาเพิ่มได้เลยนะ เพราะว่ามี library พื้นฐานที่จำเป็นต่อการพัฒนาจำนวนมาก  ช่วยทำให้ code สะอาดและ productivity ดีขึ้น
  • Apache common project ยังใช้งานเยอะมาก ทั้ง Lang/Long3, HttpClient, FileUpload, DBCP, IO และ Collections
  • Spring framework ยังคงได้รับความนิยมทั้ง MVC, JDBC, ORM, Security และ Spring Boot
  • JSON library ที่ใช้กันคือ Jackson, GSON, JSON, Simple JSON และ XStream (เสียดายที่ใน Java 9 ไม่มี Native JSON)
  • มี Lombok project ติดมาด้วยนะ ช่วยลด code ขยะที่เขียนด้วยภาษา Java ลงไปเยอะเลย

ใน Github นั้น Java project ที่มี star มากที่สุดประกอบไปด้วย

  1. RxJava
  2. Retrofit
  3. OkHttp
  4. Guava
  5. Leak canary
  6. Fast JSON
  7. Realm Java
  8. Dagger
  9. JUnit 4
  10. Spark
สังเกตุไหมว่า Java project ส่วนใหญ่ที่ติด Top 10 นั้น ถูกใช้ในการพัฒนา Android application
คำถามที่น่าสนใจคือ Java developer รู้จัก library ต่าง ๆ จากข้างต้นกันบ้างหรือไม่ ? และนำมาใช้งานกันหรือไม่ ?  
Viewing all 2000 articles
Browse latest View live