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

มาดูรูปอธิบายเกี่ยวกับ Programmer ว่าทำอะไรบ้าง ?

$
0
0

programming_01

อ่านเจอบทความเรื่อง What Is Programming And What Do Programmers Do ? ทำการอธิบายว่าจริง ๆ แล้ว programmer คืออะไร ทำการอธิบายว่าจริง ๆ แล้ว programmer ทำอะไรได้และไม่ได้บ้าง โดยสรุปออกมาเป็น Infographic สวย ๆ เข้าใจง่ายดี เลยนำมาฝากครับ เริ่มด้วย Programming คืออะไร ? programming_01 Programmer ต้องทำอะไรบ้าง เป็นอย่างน้อย ? programming_03 สิ่งที่น่าสนใจคือ สิ่งที่ programmer ส่วนใหญ่ทำไม่ได้
  • ซ่อม computer
  • แก้ไขปัญหา network
  • Hack เครื่อง computer
  • ถ่ายเอกสาร
  • ส่ง Fax
programming_02 สุดท้ายมาลองวัดความเป็น Programmer ในตัวคุณหน่อย ? programming_04

ลด ละ เลิก การสร้าง Logging application กันเถอะ !!

$
0
0

logging

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

เริ่มต้นด้วย code สวยงาม clean clean

[gist id="f6bf7d7816e98cb7f9b6f2531751704c" file="1.java"]

แต่เมื่อต้องเพิ่ม logging เข้าไป ก็จะเป็นดังนี้ !!

[gist id="f6bf7d7816e98cb7f9b6f2531751704c" file="2.java"]

ลองคิดดูสิว่า

  • ถ้าเขียน unit test ไว้ น่าจะพัง แต่อาจจะแก้ด้วยการดักจับ error แล้วไม่ทำอะไรเลย
  • การเขียน log ต้องกระทำกับไฟล์ ซึ่งผ่าน I/O นั่นเอง ไม่น่าจะดีต่อ unit test นะ
  • จะลบออกไปก็ไม่ได้ เพราะว่า product manager ต้องการแบบนี้ !!
  • จะลบออกก็ไม่ได้เพราะว่า เราต้องการข้อมูลเพื่อ audit และ เป็นข้อมูลในการแก้ไขปัญหา

คำถามที่เกิดขึ้นมาคือ

  • เราจะจัดการกับปัญหานี้อย่างไรดี ?
  • ต้องการให้ code มัน clean clean !!
  • ต้องการให้มีการเขียน log
  • ต้องการให้สามารถทดสอบ unit test ได้

มันมีวิธีการหรือเทคนิคอะไรบ้าง ?

  • เปิดปิด log ตาม mode/profile ในการ build ซึ่ง code ต้องเปลี่ยนตามไปด้วย ซึ่งขึ้นอยู่กับตัวภาษาที่ใช้อีกด้วย
  • นำแนวคิด Dependency Injection มาใช้
  • สร้าง Logging สำหรับเรื่องนั้น ๆ ขึ้นมาเลย ทำให้เลือกได้ว่าจะใช้หรือไม่
  • นำแนวคิด AOP มาใช้
  • สร้าง Library เกี่ยวกับ log มาครอบการทำงานของเราอีกชั้น

มาดูตัวอย่างการใช้งาน Dependency Injection

ซึ่งเราสามารถส่ง object ของ Logger เข้ามาได้เอง ทำให้ง่ายต่อการทดสอบ ทำให้ง่ายต่อการเปลี่ยน logger [gist id="f6bf7d7816e98cb7f9b6f2531751704c" file="3.java"] หรือทำการสร้างไฟล์ใหม่ที่ extends มาจาก class เดิม ซึ่งเป็นวิธีการที่แยกการทำงานของแต่ละ class ออกมา ตามแนวคิด Single Responsibility Principle (SRP) [gist id="f6bf7d7816e98cb7f9b6f2531751704c" file="4.java"]

โดยรวมแล้วจะใช้วิธีไหนก็ขึ้นอยู่กับความต้องการ

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

สรุปการใช้งาน Docker ที่น่าจะดี

$
0
0

docker

docker จากที่ไปลงเรียน Course การพัฒนา PHP บน Windows แบบ Build, Ship and Run anywhere ซึ่งจัดการผ่าน Docker นั่นเอง มีสิ่งหนึ่งที่น่าสนใจมาก ๆ คือ คำแนะนำสำหรับการใช้งาน Docker ที่ดี จึงทำการสรุปมาไว้นิดหน่อยดังนี้

1. ในแต่ละ container ควรทำงานเพียงอย่างเดียว

หรือว่ามีเพียง service เดียวที่ทำงาน หรือว่ามีเพียง process เดียวที่ start ขึ้นมา เช่น Container สำหรับ Web server  คือ nginx Container สำหรับ Database server คือ MySQL ดังนั้นอย่าพยายามที่จะ start หลาย ๆ process ขึ้นมาใน container เดียว นั่นคือในแต่ละ image ที่สร้างจะมีเพียงงานเดียวเท่านั้น เป็นหนึ่งในแนวคิด Separation of Concern (SoC) ส่งผลให้เราสามารถจัดการ image ได้ง่ายขึ้น ลองคิดดูเล่น ๆ สิว่า ถ้าใน container หนึ่ง ๆ มีทั้ง web server, database server, monitoring server แล้ว การจัดการจะลำบากเพียงใด

2. อย่าเก็บข้อมูลไว้ใน container นะจะบอกให้

โดยหลักการแล้วนั้นในแต่ละ container ควรเป็นแบบ stateless และไม่ทำการเก็บข้อมูลไว้ใน container ไม่เช่นนั้น container จะโตขึ้นเรื่อย ๆ จนสุดท้ายจะทำให้ container มีปัญหา ซึ่งจัดการได้ยากมาก ๆ ถ้า container นั้นถูก terminate ไป ข้อมูลหายหมดนะครับ !! ลองคิดดูสิว่า ถ้าจะสร้าง container ขึ้นมาใหม่ จะต้องทำการ load ข้อมูลจำนวนมากเข้าออก มันน่าจะไม่ใช่แนวทางที่ดีเลยนะ ดังนั้นสิ่งที่ควรใช้คือ volume mapping นะ เพื่อทำการจัดเก็บข้อมูลนอก container

3. Image ควรมีขนาดเล็ก และมีของเท่าที่จำเป็นเท่านั้น

เช่นถ้าใช้ Dockerfile แล้ว ก็ควรมีไฟล์ .dockerignore ด้วย เพื่อไม่เอาไฟล์อื่น ๆ เข้าไปยัง image ด้วย เช่น log, source code และ artifact อื่น ๆ ที่ไม่จำเป็น

4. อย่าสร้าง image จาก container ที่ทำงานอยู่ !!

เนื่องจากบ่อยครั้งจะพบว่า image เหล่านั้นไม่สามารถสร้างขึ้นมาใหม่ได้อีก หรือไม่สามารถสร้างจาก Dockerfile หรือ จากการ run command line ให้เหมือนเดิมได้เลย สิ่งที่แนะนำเลยก็คือ ทำการแก้ไข Dockerfile หรือ command line จากนั้นทำการลบ container ปิดด้วยการสร้าง container จาก image ตัวใหม่ แต่ก็มีบางกรณีที่ต้องสร้าง image จาก container ที่ทำงานอยู่ ด้วยคำสั่ง docker commit ก็ให้ดูเป็นกรณีไป แต่ไม่ค่อยแนะนำเท่าไรนะ

5. ในการอ้างถึง image ใด ๆ ก็ตามควรระบุ version ให้ชัดเจน

แนะนำว่าอย่าใช้ latest version ด้วยนะ เนื่องจากอาจจะไม่ใช่ image version ล่าสุดก็ได้ หรืออาจจะได้ version เก่ามาอีกก็เป็นได้ ขึ้นอยู่กับความรอบคอบของผู้ดูแล image นั้น ๆ

6. อย่า publish port ทั้งหมดที่ใช้งานใน container ออกมานะ

publish port เท่าที่จำเป็นก็พอ ดังนั้นให้ใช้ -p ก็พอนะ อย่าใช้ -P นะ มันน่ากลัวมาก !!

7. แต่ละ container อย่าติดต่อกันผ่าน IP นะ !!

ในแต่ละ container จะมี IP เป็นของตัวเอง ดังนั้นถ้ามีการติดต่อสื่อสารกันระหว่าง container ห้ามใช้ IP โดยเด็ดขาด เนื่องจากในโลกของ container นั้น เราจะลบหรือสร้างมันได้ตลอดเวลา ที่สำคัญแต่ละ container อาจจะได้ IP ใหม่มาอีกนะสิ !! ลองคิดดูสิว่าถ้าเราใช้ IP ในการติดต่อสื่อสารกัน จะต้องมานั่นแก้ไข IP ในไฟล์ configuration กันเหนื่อยเลยนะ ซึ่งมันไม่คุ้ม และใช้งาน Docker ผิดวิธีแล้วนะ ดังนั้นแนะนำให้ใช้ชื่อผ่านระบบ network หรือผ่าน Load balance แทนนะครับ
ปิดท้ายด้วย ในแต่ละ environment เช่น Dev, Test, UAT, Stage และ Production อย่าใช้ image ที่แตกต่างกันนะ

คำถาม ทำไม developer ในไทยเก่ง ๆ เยอะมาก ๆ แต่ทำไมไม่เป็นที่รู้จัก ?

$
0
0

problem

problem ทำไม developer ไทยถึงไม่ค่อยเป็นที่รู้จักหรือได้รับการยอมรับในระดับโลกบ้างนะ ? เป็นคำถามที่โดนถามมาจากพี่หยี ซึ่งผมก็คิดไม่ออกนะะว่าเพราอะไร ? ดังนั้นเลยอยากจะถาม developer ในไทยหน่อยสิ ว่าคิดอย่างไรกับคำถามนี้ ? ในความคิดเห็นของผมเป็นดังนี้ ถามว่า developer ไทยเก่งไหม ? ตอบได้เลยว่า มาก ๆ ถามว่า developer ไทยไม่ได้ออกไปพบเจอชาวโลกหรือเปล่า ? ประเทศอื่น ๆ เขาก็ไม่ได้ไปไหนนะ !! หรือว่าเราอยู่แต่ในประเทศมากจนเกินไป ถามว่าเป็นเรื่องของภาษาอังกฤษไหม ? ก็น่าคิดนะ เพราะว่าเป็นหนึ่งในปัญหาของคนไทยส่วนใหญ่เลยทีเดียว ดังนั้น ถ้ามีความสามารถทางภาษามากขึ้น น่าจะทำให้เพิ่มโอกาสมากขึ้น ทั้งการอ่าน ทั้งการเขียน ทั้งการพูดเพื่อติดต่อสื่อสาร ถามว่าได้รับการสนับสนุนมาจากภาครัฐไหม ? ก็มีนะทั้ง SIPA ทั้ง Software Park หรือว่ายังไม่เพียงพอ หรือว่าต้องการแรงผลักดันที่มากกว่านี้ หรือว่าต้องการหน่วยงานที่มากกว่านี้ทั้งภาครัฐและเอกชน หรือว่าเราถูกสอนมาให้ใช้ มากกว่า การสร้าง ? น่าสนใจนะ เพราะว่าตั้งแต่เด็กเราถูกสอนให้ทำแบบนั้น ทำแบบนี้ ไม่ต้องไปคิดอะไรมาก จนทำให้เราเคยชินว่า สิ่งที่เราทำอยู่มันเป็นปกติ !! ดังนั้นเมื่อโตขึ้นมา ทำงานเป็น developer ดังนั้นสิ่งที่ developer ทำคือ ใช้ไงล่ะ ไม่ต้องคิดใหม่ ทำใหม่ หรือไปร่วมสร้างอะไรขึ้นมา หรือว่า developer ไทยยังไม่ได้รับการยอมรับจากต่างประเทศ ? ต้องเป็นไปตามมาตรฐานต่าง ๆ หรือไม่ ? ต้องมี certificated ต่าง ๆ หรือไม่ ? หรือว่าการไปต่างประเทศมันมีปัญหาหลายอย่าง ? ซึ่งตรงนี้ผมก็ไม่รู้เหมือนกัน ถามว่า developer ไทยไม่ค่อยแน่นในความรู้พื้นฐานหรือไม่ ? ทำให้ไม่เข้าใจถึงปัญหาต่าง ๆ เช่น data structure, networking, distributed system, computing เป็นต้น ถามว่า developer ไทยทำงานเป็นทีมไม่ค่อยเป็น ชอบฉายเดี่ยว ? ซึ่งเป็นคำถามที่น่าสนใจอย่างมาก ตัวอย่างเช่นการเล่นกีฬาของคนไทย จะเก่งในกีฬาที่มีคนในทีมน้อย ๆ หรือมีเพียงคนเดียว ถามว่า community ในไทยเยอะไหม ? ตอบว่าในปัจจุบันเยอะมากนะ แต่เน้นไปที่การใช้งาน มากกว่าที่ไปที่มาของสิ่งเหล่านั้นหรือไม่
ขาดความรู้หรือไม่ ? ขาดการ contribute หรือไม่ ? ขาดการต่อยอดหรือไม่ ? ขาดการสนับสนุนหรือไม่ ? ขาดความต่อเนื่องหรือไม่ ? ขาดคนลงมือทำหรือไม่ ? หรือว่าเราทุกคนต้องดูว่า เราพูดและวางแผนมากกว่าการลงมือทำหรือไม่ ? สุดท้ายแล้ว เราทำอะไรเพื่อให้ดีขึ้นมาบ้าง ?

ว่าด้วยเรื่อง Asynchronous สำหรับ Android

$
0
0

react-channel-image

react-channel-image การพัฒนา Mobile app ทั้ง Android และ iOS นั้น คงไม่มี developer คนไหนไม่รู้จัก Reactive หรือ Rx แต่กลับพบว่าหลาย ๆ คนยังไม่เข้าใจที่มาที่ไปว่า Rx มันเข้ามาช่วยอะไร ? ก่อนจะมี Rx มีอะไรให้ใช้บ้าง ? ปัญหาคืออะไร ? ดังนั้นก่อนที่จะเริ่มนำ Rx มาใช้งาน กลับมาสู่ความรู้พื้นฐานก่อนดีไหม ในบทความนี้เน้นไปที่ Android ก่อน

พื้นฐานของ Android app

จะทำงานอยู่บน Thread เดียวเท่านั้น หรือเราเรียกว่า UI Thread หรือ Main Thread ใช้สำหรับการ update หน้า View นั่นเอง ทุกอย่างมันดูดีมาก ๆ แต่ในงานจริง ๆ จะพบว่า เมื่อต้องดึงข้อมูลจากส่วนการทำงานอื่น ๆ เช่น Database, API อาจจะใช้เวลาทำงานนาน ๆ ทำให้ผู้ใช้ต้องรอ รอ รอ แล้วก็รอ !!! เนื่องจากมีเพียง Main Thread เดียวเท่านั้น หรือซ้ำร้ายไปกว่านั้น ระบบอาจจะแสดง dialog แสดง ANR (Application Not Response) ออกมา และบอกให้ผู้ใช้งานปิด app ไปซะ แน่นอนทำให้ app มี responsive ที่แย่มาก ๆ anr บางครั้งอาจจะแก้ไขปัญหาแบบแก้ผ้าเอาหน้ารอดไปก่อนเช่น แสดง progress bar เพื่อบอก progress การทำงาน (หมุน ๆ ๆ ๆ) เพื่อแสดงให้ผู้ใช้งานเห็นว่า ระบบยังทำงานอยู่นะ ไม่ได้ตาย หรือทำหน้า splash ขึ้นมาเพื่อซ่อนการทำงาน

แต่สิ่งที่ควรทำคือ แยก process ต่าง ๆ ออกไปทำงานใน Background Thread สิ !!

แน่นอนว่า Android ก็เตรียมไว้ให้เสร็จสรรพแล้ว เช่น
  • Thread
  • IntentService
  • AsyncTask
  • Loader
โดยแต่ละตัวนั้น มีรูปแบบการทำงานและใช้งานที่แตกต่างกัน รวมทั้งมีข้อจำกัดต่าง ๆ อีกด้วย เช่น AsyncTask นั้นก็ให้เกิด callback hell ได้ เมื่อต้องจัดการ flow การทำงานที่ซับซ้อน หรือมีลำดับการทำงานเยอะ การจัดการ error ต่าง ๆ ก็ยาก แต่ทำได้นะ ใช้ความสามารถนิดหน่อย เขียน code เพิ่มมาอีกเยอะพอสมควร ต้องลงแรงเสียเวลาเขียน code มาจัดการเรื่องต่าง ๆ เองทั้ง
  • จัดการ callback ใน Main Thread
  • จัดการ Error ต่าง ๆ
  • แก้ไขปัญหา Callback hell
  • จัดการการทำงานใน background process ให้ง่าย ๆ
โดยรวม ๆ  แล้วยากใช้ได้เลยนะ !!

จากปัญหาต่าง ๆ เหล่านี้นี่เอง

จึงมีคนพยายามสร้าง library มาช่วย ซึ่งหนึ่งในนั้นก็คื Rx นั่นเอง ในภาษา Java ก็มี RxJava ให้ใช้งาน ส่วนใน Android ก็คือ RxAndroid เรื่อง Rx นั้นสามารถดูเพิ่มเติมได้จาก Marble digagram ทำการอธิบายด้วยรูปภาพ ซึ่งเข้าใจได้ง่ายมาก ๆ

การทำงานของ Rx ประกอบไปด้วยส่วนหลัก ๆ ดังนี้

  • Observable
  • Observer
  • Operator (มีเยอะมาก ๆ)
  • Subscriber
  • Scheduler
  • Compose Stream

มาลองใช้งานแบบง่าย ๆ กันหน่อย ด้วย Hello World

เพื่อทำความเข้าใจเกี่ยวกับ RxAndroid กัน มีขั้นตอนดังนี้ ขั้นตอนที่ 1 เริ่มต้นด้วยการสร้าง Observable ขึ้นมาก่อน ซึ่งจะส่งข้อมูลออกมาตัวเดียว คือ List ของเพื่อน(String) [gist id="f00f63170493ef4fcd52512f8ba60e0b" file="1.java"] ปล. การทำงานจะไม่รอจนการ method getFriendList() จะทำงานเสร็จนะ หรือทำงานแบบ Non-Blocking ซึ่งแตกต่างจากรูปแบบการเขียนแบบเดิมนะครับ ที่เป็นแบบ Blocking หรือต้องรอนั่นเอง ขั้นตอนที่ 2 ทำการ subscribe ไปที่ Observable คำถามที่น่าสนใจคือ แล้วเราจะรู้ได้อย่างไร ว่า method getFriendList() ทำงานเสร็จ ดังนั้นสิ่งที่ต้องทำคือ การ subscribe นั่นเอง โดยมี life cycle ดังนี้
  • onCompleted() ถูกเรียกเมื่อการทำงานใน method getFriendList() ทำงานเสร็จสิ้น
  • onError() ถูกเรียกเมื่อเกิด error ขึ้นมา
  • onNext() ถูกเรียกเมื่อ method getFriendList() ทำงานสำเร็จและนำผลการทำงานมาใช้งาน จากตัวอย่างคือรายชื่อของเพื่อนนั่นเอง
[gist id="f00f63170493ef4fcd52512f8ba60e0b" file="11.java"]
ปล. Observable มันสำคัญมาก ๆ นะ เนื่องจากใช้กำหนดพฤติกรรมการทำงานต่าง ๆ ไว้เลย

ลองมาดูอีกสักตัวอย่าง เป็นการดึงข้อมูลจาก REST API ทำการแบบ Asynchronous

เริ่มต้นด้วยการสร้าง Observable ขึ้นมาเช่นเดิม แต่สิ่งที่แตกต่างจากตัวอย่างแรกคือ ไม่สามารถเรียกใช้ Observable.just() ได้ เนื่องจาก REST API มันจะ block การทำงานของ Main Thread ไว้ ดังนั้นเราต้องให้การเรียก REST API ไปทำงานอีก Thread ดังนี้ [gist id="f00f63170493ef4fcd52512f8ba60e0b" file="2.java"] จากนั้นทำการ subscribe ซะ และต้องกำหนด property ในการเรียกใช้เพิ่มนิดหน่อยดังนี้
  • subscribeOn() จากตัวอย่างเป็นการ subscribe บน I/O Thread
  • observerOn() จากตัวอย่างเป็นการ observer บน Main Thread ซึ่งเป็น Thread ที่จะทำงานใน onNext() ข้อดีขคือ ไม่ต้องไปเขียน code สำหรับแสดงข้อมูลบน View ด้วยการใช้ method runOnUIThread() เองอีกต่อไปนะ ง่ายขึ้นเยอะ !!
[gist id="f00f63170493ef4fcd52512f8ba60e0b" file="22.java"] ที่สำคัญมาก ๆ คือ เมื่อ Activity ถูกทำลายแล้ว ต้องทำการ unsubscribe ด้วยนะ มิเช่นนั้นอาจจะเกิดปัญหา memory leak ได้ [gist id="f00f63170493ef4fcd52512f8ba60e0b" file="23.java"] ดูเหมือนง่าย ๆ นะ แต่เมื่อนำมาใช้งานจริง ๆ เจอปัญหาและเหตุการณ์ต่าง ๆ จะพบว่า เราต้องเรียนรู้เพิ่มอีกมากมาย แต่มันคือสิ่งที่ developer ที่ดีต้องทำนะ

เมื่อ Rx เกิดมาเพื่อช่วยปัญหา แต่ตัวมันเองก็มีปัญหาเช่นกัน

ปัญหาที่เจอบ่อย ๆ คือ ใช้งานได้แต่ไม่เข้าใจ รู้เพียงว่าใช้งานแบบนี้แหละนะ รวมทั้งมี learning curve สูงพอสมควร เนื่องจากมันเปลี่ยนวิธีการคิดสำหรับแก้ไขปัญหา ที่สำคัญ Rx ยังมี operation ต่าง ๆ มากมายให้ใช้งาน
ดังนั้นก่อนจะนำไปใช้งานควรศึกษาและทำความเข้าใจก่อนนะ
มีอีกปัญหาหนึ่งคือ การแก้ไขปัญหาหนึ่ง ๆ ด้วย Rx นั้น มีหลากหลายวิธีการ รวมทั้งวิธีการแก้ไขปัญหามันขึ้นอยู่กับระบบของเราอีกด้วย ทำให้ยากต่อการศึกษาและนำไปใช้งานอย่างมาก

สุดท้ายแล้ว

ก่อนจะนำอะไรมาใช้งานต้องเรียนรู้และทำความเข้าใจให้ดีก่อน ดังนั้นให้เวลาบ้าง อย่านำมาใช้เพราะเขาบอกว่าดี พิจารณาไปที่ระบบงานด้วยว่าเหมาะสมหรือไม่ ? ที่สำคัญสำหรับ Android app ยิ่งนำ library มาใช้มาก ก็ยิ่งทำให้เกิดปัญหา 64K ได้ง่ายนะครับ Source code ตัวอย่างอยู่ที่ Github::Up1:Learn Reactive Android

แก้ไขปัญหาเรื่อง Callback hell ใน Swift กันนิดหน่อย

$
0
0

swift-callback-hell

swift-callback-hell วันนี้ทำการ review code ทั้งฝั่ง Android และ iOS(Swift) พบว่า code มีสิ่งที่คล้ายกันมาก ๆ คือ มีการเรียกใช้ REST API ผ่าน network library ซึ่งทำงานแบบ Asynchronous สิ่งที่เกิดขึ้นคือ มี feature ที่ต้องเรียกใช้งาน REST API หลาย ๆ ตัวต่อเนื่องกัน ทำให้เกิด code ในรูปแบบของ Callback ซ้อน Callback หรือ Callback hell นั่นเอง หรือดีขึ้นมาหน่อยคือ flow การทำงานของ code กระโดดไปยัง method อื่น ๆ ต่อไปเป็นทอด ๆ หรือ Chain

ผลที่ตามมาก็คือ

  • Developer เองก็งงกับ flow การทำงาน
  • เมื่อต้องทำการเพิ่ม หรือ แก้ไข จะยากมาก ๆ ดังนั้นทำใหม่ดีกว่า !!
  • เรื่องทดสอบไม่ต้องพูดถึง ยากเอาเรื่อง

มาดูรูปแบบของปัญหากันว่าเป็นอย่างไร ?

รูปแบบที่ 1 เป็น Callback hell แบบสนุกสนานมาก ๆ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="1.swift"] รูปแบบที่ 2 ดีขึ้นมาหน่อย เป็นการเรียก method จาก Callback ไปเรื่อย ๆ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="2.swift"] ทั้ง ๆ ที่ความต้องการเป็นดังนี้ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="3.swift"]

มาดูต้นเหตุของปัญหาสิ

เมื่อไปดู code ของ iOS ที่พัฒนาด้วยภาษา Swift 2.3 พบว่าในการเรียกข้อมูลผ่าน REST API นั้น ใช้ Networking Library ซึ่งทำงานแบบ Asynchronous ทั้ง NSURLSession และ Alamorfire การแก้ไขปัญหามีหลายแนวทางทั้ง เปลี่ยนให้เป็น Synchronous สิ !! ใช้ library เพิ่มสิ เช่น Bolt, Promise และ Rx เป็นต้น โดยสิ่งที่ผมเลือกคือ เปลี่ยนการทำงานให้เป็น Synchronous เลยสิ และนำ Grand Central Dispatch (GCD) มาใช้งาน

วิธีการก็ไม่ยากและไม่ง่าย นั่นคือ

สร้าง method ใหม่ใน NSURLSession ผ่าน extension โดย method ใหม่นี้จะทำงานแบบ Synchronous ดังนี้ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="4.swift"] คำอธิบาย จะทำการรอไปจนกว่าจะทำงานเสร็จสิ้นนั่นเอง ซึ่งสามารถตอบโจทย์ที่เราต้องการ จากนั้นในแต่ละ process การทำงานที่ไปดึงข้อมูลผ่าน REST API ใช้งานผ่าน method ใหม่ดังนี้ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="5.swift"] เพียงเท่านี้ก็สามารถควบคุมการทำงานได้แล้ว แถมได้ code ที่อ่านง่าย แก้ไขง่ายอีกด้วย ปล. 1 ใน Swift 3.0 การใช้งาน GCD ก็จะเปลี่ยนไปโดยสิ้นเชิง ปล. 2 ในการออกแบบ REST API นั้นควรคิดให้มาก ๆ ถ้าต้องให้ client ต้องมาร้อยเรียง service เองมาก ๆ ก็ไม่ใช้การออกแบบที่ดีเลยนะ ที่สำคัญพัฒนายากทั้งฝั่ง API และ Mobile ที่สำคัญยากต่อการ integrate และ ทดสอบอีกด้วย
ดังนั้นมาทำการปรับปรุง code ให้ดีขึ้นกว่าเดิมกันครับ
ตัวอย่าง source code อยู่ที่ Github::Up1::Swift Sync Call

สิ่งที่น่าสนใจใน Technology Radar เดือนพฤศจิกายน 2559 จาก Thoughtworks

$
0
0

tech_radar

tech_radar มาดูผลของ Technology Radar เดือนพฤศจิกายน 2559 จาก Thoughtworks โดยในครั้งนี้มีสิ่งที่น่าสนใจ คือ
  • Docker as a process และ Microservice as a programming model ดังนั้นโลกของ container มันเข้ามาเป็นแนวคิดหลักไปแล้ว
  • AR และ VR เข้ามาสู่กระแสหลัก
  • Holistic ส่งผลกระทบต่อโครงสร้างของทีม
สรุปเฉพาะส่วนที่สนใจคือภาษาโปรแกรมและเครื่องมือในการพัฒนา ที่เหลือลองไปอ่านเพิ่มเติมได้

เริ่มที่ภาษาโปรแกรมและ framework ก่อน

จะพบว่าในส่วนของ Adopt จะมี JavaScript framework เพียบเลย ทั้ง Ember.js, React.js และ Redux แถมยังมี Enzyme ซึ่งเป็น testing library สำหรับ React.js ทางทีมพัฒนาของ Thoughtworks แนะนำให้ลองใช้งาน Phoenix เป็น MVC framework ที่เขียนด้วยภาษา Elixir ซึ่งมันใช้งานง่าย และ ทำงานได้เร็วมาก ๆ ส่วนที่ผมชอบมาก ๆ คือ Quick และ Nimble ใช้สำหรับเขียน Unit test ของ iOS app เขียนใช้รูปแบบเดียวกับ RSpec อีกทั้งยังใช้ได้กับภาษา Swift และ Objective-C ที่สำคับคือ ง่ายต่อการทดสอบส่วนการทำงานแบบ asyncchronous อีกด้วย และยังมีสิ่งที่ต้องยังศึกษาและทำความเข้าใจอยู่อีกเยอะเลย เช่น
  • Vue.js ซึ่งในไทยเริ่มมีการพูดถึงมากขึ้น
  • GraphQL ดูเงียบ ๆ ไปหน่อย
  • ReSwift เป็น library ที่นำเอาแนวคิด Redux มาใช้งานในภาษา Swift
  • Three.js สำหรับการแสดงผลแบบ 3D ผ่าน browser ซึ่งสนับสนุน WebGL
ส่วน Angular 1 ไม่แนะนำให้ใช้แล้วนะ เนื่องจากไม่ได้ maintain อะไรต่อแล้ว

เรื่องต่อมาคือ เครื่องไม้เครื่องมือในการพัฒนา

ในส่วนของ Adopt นั้นมีเครื่องมือใหม่ ๆ เข้ามาคือ Babel และ Grafana ดูแล้วไม่ใช่เรื่องแปลกสักเท่าไร เนื่องจาก Babel มันคือ compiler สำหรับภาษา JavaScript ทำให้เราสามารถเขียน code ด้วย ES6, ES7 แล้วนำไป run บน browser ได้ ดังนั้นสำหรับการพัฒนาระบบด้วย JavaScript นั้น จำเป็นต้อง configuration Babel ให้เป็นนะ ต่อมาคือ Grafana เป็นเครื่องมือสำหรับการแสดงผลการทำงานในรูปแบบ Dashboard ทั้ง CPU, Memory และการทำงานต่าง ๆ ของระบบ ยิ่งปัจจุบันเน้นไปยังเรื่อง Microservice และ DevOps ดังนั้นเรื่อง Dashboard สำหรับ monitoring การทำงานของระบบจึงสำคัญมาก ๆ ส่วนเครื่องมืออื่น ๆ ที่แนะนำให้ลองนำมาใช้งาน
  • Espresso สำหรับ UI test ของ Android app
  • Fastlane เป็น automation tool สำหรับ iOS และ Android app มีตั้งแต่ build-test-deploy
  • Galen เป็น automated testing สำหรับตรวจสอบ responsive ของ web ในหน้าจอต่าง ๆ กัน มีประโยชน์ต่อทีมออกแบบอย่างมาก
  • Pa11y เป็น automated testing สำหรับการตรวจสอบ web accessibility ซึ่งเป็น command line ให้ไช้งานแบบง่าย ๆ ที่สำคัญสามารถนำไปใส่ในระบบ Continuous Integration ได้อีกด้วย
  • FBSnapshotTestcase ให้สำหรับการ screenshot หน้าจอการทำงานของ iOS app ด้วยการ run Unit test ซึ่งมีความเร็วมาก ๆ
  • Scikit-learn เป็น library สำหรับ machine learning ที่พัฒนาด้วยภาษา Python ซึ่งมี module ต่าง ๆ ให้ใช้งานมากมาย เช่น clustering และ regression เป็นต้น

ส่วนเรื่องของเทคนิคและ platform มีที่น่าสนใจคือ

  • Docker
  • Consumer-driven contract testing
  • API as a product
  • Pipeline as a code
  • เรื่องความปลอดภัยก็สำคัญมาก ๆ ทั้ง Threat modeling, HTTP Strict Transport Security(HSTS) และ Linux security modules
สุดท้ายแล้วมีสิ่งที่ต้องศึกษาอีกเพียบเลยครับ !!

มาดูผลสำรวจเรื่อง Enterprise Development Trends 2016 จาก JVM Developer

$
0
0

survey_00

survey_00 ทาง Lightbend ทำสำรวจเรื่อง Enterprise Development Trends 2016 ซึ่งทำการสำรวจจาก JVM(Java Virtual Machine) Developer กว่า 2,500 คน เพื่อทำให้เห็นแนวโน้มของ development และ IT operation รวมทั้งการนำเทคโนโลยีและแนวคิดต่าง ๆ มาใช้งาน ทั้ง Cloud, Container และ Microservice มาดูผลสำรวจที่น่าสนใจกัน

เนื่องจากการพัฒนาระบบงานบน JVM

ส่วนใหญ่จะทำการ deploy ระบบบน Java EE Stack ซึ่งมันมีขนาดใหญ่และกินทรัพยากรอย่างมาก (Heavywight) ผลที่ตามมาคือ deploy ยากและนาน การดูแลก็ลำบาก แต่เมื่อเข้ามาสู่ยุคของ Cloud, Container, Microservice และ DevOps ซึ่งทำให้เกิดรูปแบบใหม่ ๆ ของการพัฒนา Enterprise application ดังนั้นแบบสำรวจนี้จึงเกิดขึ้นมา ซึ่งได้ผลที่น่าสนใจดังนี้

Microservice ได้เข้ามาเป็นสถาปัตยกรรมหลักแล้วนะ

  • 30% ทำการ deploy บน production ไปแล้ว
  • 20% ทำการ pilot ระบบไปแล้ว
  • 25% ทำการ Proof of Concept
survey_01 รวมทั้งเรื่องของ Fast data pattern นั่นคือการประมวลผลข้อมูลแบบ realtime และต่อเนื่อง ซึ่งมีเทคโนโลยีที่ได้รับความนิยมทั้ง Apache Spark, Apache Kafka และ Akka แสดงผลการสำรวจดังรูป survey_011

Lightweight container ได้เข้ามาแทนที่ Java EE App Server แล้วนะ

  • 22% ทำการ deploy บน production ไปแล้ว
  • 22% ทำการ pilot ระบบไปแล้ว
  • 30% ทำการ run บน local machine สำหรับพัฒนา
  • 20% ทำการ Proof of Concept
survey_02 โดยระบบใหม่ ๆ จะใช้งานมากกว่าการ migrate ระบบเดิม ซึ่งเทคโนโลยีที่นำมาใช้ประกอบไปด้วย
  • Docker swarm 37%
  • Kubernates 18%
  • Mesos/Marathon 14%
  • Nomad 7%
survey_022

มาดูการใช้งานระบบ Cloud กันบ้าง

  • 31% ทำการ deploy บน production ไปแล้ว
  • 29% ทำการทดลองเพื่อสร้าง process การทำงาน
survey_03 เมื่อไปดูในรายละเอียดจะพบว่า Scala developer จะใช้งานมากกว่า Java developer เนื่องจากระบบ Java EE App server เก่า ๆ นั้น ไม่สามารถทำงานได้บนระบบ cloud นั่นเอง หรือไม่ก็ยากเหลือเกิน !! โดยรวมแล้วพบว่า Scala developer จะนำแนวคิดต่าง ๆ มาใช้งานมากกว่า Java developer ทั้ง microservice และ container Developer จากบริษัทที่มีขนาดเล็กจะใช้งานมากกว่า

สรุป session ที่เข้าฟังช่วงเช้าสำหรับงาน Barcamp Bangkhen 2016

$
0
0

barcamp-bkk

barcamp-bkk วันนี้มาร่วมงาน Barcamp Bangkhen 2016 ซึ่งจัดที่มหาวิทยาลัยเกษตรศาสตร์ ซึ่งมีคนมาร่วมงานเยอะมาก ๆ ส่วนผมไม่ได้ลงทะเบียนก็เลย walk-in เอาเลย โดยในช่วงเช้าเข้าฟัง session ต่าง ๆ ดังนี้
  • Functional Programming with JavaScript
  • Building Microservice with Docker Swarm
  • What we have learned from building LINE chatbot ?

1. Functional Programming with JavaScript

เป็นการแนะนำวิธีการเขียน JavaScript ในอีกรูปแบบ สิ่งที่ชอบมาก ๆ คือ การนำเสนอ โดยทำการอธิบายรูปแบบการเขียน code แบบเดิมก่อนว่าเป็นอย่างไร จากนั้นจึงทำการอธิบายต่อว่า ถ้าเขียนในรูปแบบของ Functional programming แล้วจะเป็นอย่างไร ซึ่งทำให้เราได้รู้และเข้าใจอย่างชัดเจน โดย code ที่ได้มานั้น จะสั้น กระทัดรัด ซึ่งดูแล้วง่ายดี แต่ก็ต้องแลกมาด้วยการเรียนรู้เพิ่มเติม ซึ่งเป็นสิ่งที่นักพัฒนาต้องทำอยู่แล้ว !! สำหรับใครที่สนใจลองเริ่มศึกษาได้จาก Learn Functional Programming with JavaScript ส่วน Library ที่ใช้งานคือ RxJS

2. Building Microservice with Docker Swarm

ทำการอธิบายการพัฒนาระบบงานด้วยแนวคิดของ Microservice คือทำการแยกส่วนการทำงานออกมาเป็น service เล็ก ๆ แต่ละ service มีหน้าที่การทำงานอย่างชัดเจน ซึ่งต่างจากโครงสร้างของระบบแบบเดิมหรือ Monolith ที่สร้างทุกสิ่งอย่างไว้ที่เดียวกัน ทำให้ยากต่อการขยายระบบ ทำให้ยากต่อการดูแล ทำให้ยากต่อการแก้ไข ดังนั้นมาเปลี่ยนเป็น Microservice กันเถอะ โดย Microservice นั้นก็มีรูปแบบของการออกแบบที่หลากหลาย สามารถดูเพิ่มเติมได้ที่ Pattern :: Microservice Architecture จากนั้นลองพิจารณาดูว่า ระบบงานของเรานั้นเหมาะสมกับรูปแบบไหน ? จากนั้นเป็นการ demo จัดการ Microservice ด้วย Docker Swarm ซึ่ง Docker Swarm คือเครื่องมือสำหรับจัดการ Clustering ของ Container นั่นเอง ช่วยทำให้เราสามารถ scale แต่ละ service แบบง่าย ๆ ได้ เนื่องจาก Docker Swarm จัดการให้ทั้ง
  • การเพิ่มหรือลดจำนวน container ในแต่ละ service
  • ในแต่ละ service จะมี Load Balance ให้
มีคำถามที่น่าสนใจ เช่น การจัดการ volumn การจัดการ network การจัดการ load balance การจัดการ microservice โดยตัวอย่างอยู่ที่ Github:: Microservice with Docker Swarm 101

3. What we have learned from building LINE chatbot ?

เป็นการเล่าประสบการณ์ในการสร้าง LINE chatbot ของวงใน สิ่งที่น่าสนใจมาก ๆ คือข้อแนะนำในการสร้าง Chatbot เริ่มด้วย bot ต้องมีความเป็นคน เป็นเพื่อน ไม่ใช่ตอบคำถามแบบทื้อ ๆ ตอบซ้ำ ๆ ทั้งการแนะนำตัว ทั้งตัวตนที่ชัดเจน โดยการสร้าง bot นั่นเริ่มจากให้คนมาตอบแทนก่อน เพื่อเรียนรู้ว่า ผู้ที่มาคุยกับ bot นั้นต้องการอะไรกันแน่ ทำให้ผู้สร้างสามารถสร้างสิ่งที่ตรงใจออกมามากกว่า แถมยังมีเทคนิคในการตอบคำถามและพูดคุยเพิ่มเติม เช่น
  • ควรมีกลุ่มของคำตอบไว้สำหรับเรื่องหนึ่ง ๆ เพื่อลดการตอบซ้ำ ๆ
  • ใส่ emoticon เข้าไปด้วย เพื่อเพิ่มความน่าสนใจ
  • สามารถให้คำแนะนำ และ บอกได้ว่าขั้นตอนต่อไปต้องทำอะไร
  • ที่สำคัญต้องตอบทุก ๆ คำถามนะ
แถมด้วยสิ่งที่ต้องพิจารณาในการสร้าง Chatbot ประกอบไปด้วย
  • ต้องรู้และเข้าใจข้อจำกัดต่าง ๆ เช่น ขนาดของหน้าจอซึ่งส่งผลต่อสิ่งที่ตอบ จะทำอย่างไรให้เหมาะสม
  • ต้องเรียนรู้พฤติกรรมและเก็บข้อมูลของผู้ใช้งาน ทั้ง localtion และ language รวมทั้ง Analytic ต่าง ๆ
  • ต้องสามารถทำงานได้หลากหลาย platform
  • ต้องทำการ promote bot ของคุณด้วยล่ะ ว่ามีนะ ว่าทำอะไร ช่วยอะไรได้บ้าง
ส่วนหัวข้ออื่น ๆ ที่น่าจะทำต่อไป เช่น การทำให้ bot ฉลาดขึ้นเช่นการใช้ Rule-based engine หรือพวก AI การเรียนรู้ภาษาไทยเช่น การตัดคำ !! แน่นอนว่า คุยให้เหมือนคนมากขึ้น แต่เหนือสิ่งอื่นใด ก่อนจะสร้าง bot ใด ๆ ขึ้นมา ควรต้องกำหนดตัวตน หรือ personality ของ bot ก่อนเสมอ ว่ามีคุณลักษณะอย่างไร ? ว่ามีอุปนิสัยอย่างไร ? ว่าทำอะไรได้บ้าง ? ดังนั้นสร้าง bot ที่มีความสามารถแบบเฉพาะเจาะจงจะเหมาะสมกว่า แน่นอนว่าต้องมีประโยชน์ต่อผู้ใช้งานและ business นะ

ส่วนช่วงบ่ายได้แบ่งปันไป 2 เรื่องคือ

สรุป Plug-in และ Trick ที่ใช้ใน Android Studio ไว้นิดหน่อย

$
0
0

android_studio_00

android_studio_00 ในการใช้งาน Android Studio นั้นมี trick และเทคนิคในการใช้งานมากมาย รวมทั้งมี plugin ที่มีประโยชน์มากมาย ดังนั้นจึงทำการสรุปสิ่งที่ใช้ประจำไว้นิดหน่อย ปล. ใครมีเทคนิคดี ๆ ก็แนะนำกันมาได้นะครับ

1. จัดการสีของตัวอักษรใน Logcat ตาม level

มีประโยชน์เมื่อต้องดูปัญหาหรือการทำงานต่าง ๆ ผ่าน Logcat แน่นอนว่า เป็นสิ่งที่ Android developer ใช้งานเป็นประจำ แต่โดยค่าปกติแล้วนั้น สีของตัวอักษรของแต่ละ level ไม่ได้ต่างกันเลย ทั้ง Assert, Debug, Error, Info, Verbose และ Warning ซึ่งมองและอ่านยากมาก ๆ ดังนั้นให้ทำการแก้ไขซะ โดยเข้าไปที่ Preferences -> Editor -> Android Logcat แสดงดังรูป android_studio_01

2. ทำการกำหนด Coding Style หน่อยนะ

เป็นสิ่งที่ทีมพัฒนาควรกำหนดเป็นข้อตกลงร่วมกัน ทั้งเรื่อง Tab, Space, Braces และอื่น ๆ อีกมากมาย จากนั้นทำการบันทึกแล้ว export ออกไปให้คนอื่น ๆ ในทีมใช้งาน หรือถ้าไม่อยากกำหนดเอง ก็สามารถใช้ Coding Style จากที่อื่นมาใช้ก็ได้เช่น แสดงดังรูป android_studio_02

3. ทำการตั้ง Keyboard shortcut ไว้ด้วย

เพื่อทำให้การเขียน code ง่ายและสะดวกมากยิ่งขึ้น โดยแก้ไขได้ที่ Preferences -> Keymap android_studio_03

4. ถ้าอยากให้ Editor ใหญ่ ๆ ทำไงดี !!

เพื่อเพิ่มพื้นที่การทำงาน และ ลดสิ่งที่รบกวนสายตาลงไป เข้าไปที่เมนู View โดยมี view mode ให้ใช้งาน 3 mode คือ
  • Presentation mode
  • Distraction free mode
  • Full screen
ลองเลือกใช้งานดูนะครับ ปกติผมจะใช้ Distraction free mode

5. สำหรับคนขี้เกียจใช้งาน Live Template ได้เลย

สำหรับ Mac กดปุ่ม Command + J ส่วน Windows และ Linux ใช้ Ctrl + J แสดงดังรูป android_studio_04 แน่นอนว่า เราสามารถทำการ custom Live Template ได้เองนะ โดยไปที่ Preferences -> Editor -> Live Templates แสดงดังรูป android_studio_05
และสำหรับ IntelliJ หรือ Android Studio ผมจะใช้ปุ่ม Command + Enter บ่อยมาก ๆ สำหรับ quick fix !! สำหรับ Windows และ Linux คือปุ่ม ALT + Enter

ส่วน plugin ที่น่าจะต้องติดตั้งไว้บ้าง (มีเยอะก็หนักเครื่อง)

  • ADB Idea ช่วยทำให้จัดการผ่าน adb command ได้ง่ายขึ้นทั้งติดตั้งและลบ app
  • Android method count จะแสดงจำนวน method ของแต่ละ library ให้
  • String manipulation ช่วยในการจัดการข้อมูล ว่าจะให้เป็นรูปแบบไหน
  • Key promoter สำหรับจัดการ key ที่ใช้บ่อย ๆ
  • Builder plugin สำหรับใครที่ชอบพวก builder pattern สำหรับจัดการข้อมูลใน object
  • Android Parcelable code generation เพื่อช่วย generate code ต่าง ๆ ของ Parcelable

[แปล] iOS Test Pyramid จากทีมพัฒนาของ LinkedIn

$
0
0

ios-testing

ios-testing บทความเรื่อง iOS Test Pyramid จากทีมพัฒนาของ LinkedIn ทำการอธิบายวิธีการทดสอบของ iOS app เป็นขั้นตอนการทำงานที่สำคัญในกระบวนการ 3X3 iOS Release ซึ่งทำให้ทีมพัฒนาสามารถ release iOS app ภายใน 3 ชั่วโมงได้ ตั้งแต่การ commit code จนถึงการ publish ขึ้น App Store กันเลย หัวในหลักของการ Release นั่นก็คือ กระบวนการทดสอบแบบอัตโนมัตินั่นเอง โดยเน้นทั้งจำนวน code coverage และเวลาของการทำงานตั้งแต่การ commit จนถึงการ publish app ดังนั้นจึงนำบทความนี้มาแปลและสรุปตามความเข้าใจไว้นิดหน่อย

แนวทางการแก้ไขปัญหาเรื่องการทดสอบ

ทำการแบ่งการทดสอบออกเป็น 3 กลุ่มคือ
  1. Unit test
  2. Layout test
  3. Scenario test หรือ UI test
และทำการทดสอบบน iOS device หลากหลาย version เมื่อผ่านการทดสอบจะทำการ publih app ไว้ใน Alpha release เสมอ

กลุ่มของการทดสอบแสดงดังรูป Test Pyramid

testpyramid1 คำอธิบาย จำนวนของการทดสอบกลุ่ม Unit test และ Layout test จะมีจำนวนมากกว่า Scenario test เนื่องจากเวลาในการทดสอบจะน้อยกว่า Scenario test อย่างมาก ไม่ใช่แค่ทดสอบเร็วเท่านั้น แต่ยังทำให้ทีมพัฒนารู้ปัญหาได้อย่างรวดเร็ว เพื่อลดการ debug ลงไป ทำให้การทำงานมีประสิทธิภาพมากยิ่งขึ้น

จากแนวทางในทดสอบส่งผลต่อโครงสร้างของระบบงาน

ไม่ว่าจะเป็น MVC, MVP, MVVM ซึ่งสามารถสรุปการทดสอบในแต่ละส่วนการทำงานออกมาได้ดังรูป testpyramid2 คำอธิบาย Model มีหน้าที่จัดการข้อมูล หรือเรียกว่า DAL (Data Abstraction Layyer) โดยข้อมูลทั้งจากภายในและภายนอก Presenter มีหน้าที่ทำงานระหว่าง Model กับ View มีขั้นตอนการทำงานดังนี้
  • ทำงานตามการกระทำต่าง ๆ ของผู้ใช้งานผ่าน view
  • ทำการการดึงข้อมูลจาก Model
  • ทำการจัดการรูปแบบข้อมูลก่อนแสดงที่ View
  • สั่งให้ View แสดงผลตามข้อมูล
View ทำการแสดงผล สามารถแสดงได้เอง หรือ ถูกสั่งจาก Presenter รวมทั้งดักจับการกระทำต่าง ๆ จากผู้ใช้งาน ViewController เป็นส่วนการทำงานหลักของ iOS app ซึ่งเชื่อมระหว่าง View และ Model เข้าด้วยกัน ViewModel ทำหน้าที่อยู่ระหว่าง View กับ Model

มาดูรายละเอียดของการทดสอบแต่ละกลุ่ม

1. Unit test เป็นส่วนที่สำคัญมาก ๆ ในการพัฒนา app ทำให้มีความมั่นใจต่อ code ที่สร้างขึ้นมา ทำให้ code มีความน่าเชื่อถือ ปลอดภัย รวมทั้งง่ายต่อการ debug หรือหาจุดที่ผิดพลาด และทำให้รู้ปัญหาหรือ bug ได้อย่างรวดเร็ว โดยที่ unit test นั้นจะทำการทดสอบส่วนการทำงานเล็ก ๆ ที่ทำงานอยู่ในส่วนต่าง ๆ ไม่ว่าจะเป็น
  • Business logic
  • ViewModel เช่นการ convert ข้อมูลในรูปแบบต่าง ๆ
  • การทำงานต่าง ๆ ใน ViewController
  • ทำการตรวจสอบสถานะต่าง ๆ ของข้อมูล
2. Layout test เป็น unit test ชนิดหนึ่ง แต่เน้นไปที่การทดสอบส่วนของ layout ของ View ใน device หรือ configuration ที่แตกต่างกัน รวมไปถึงขนาดของหน้าจอที่แตกต่างกัน โดยที่ในการทดสอบต้องทำการจำลองข้อมูลต่าง ๆ ที่ใช้งาน เช่นจำลองการทำงานของ ViewModel เพื่อทดสอบว่า View สามารถแสดงผลจากข้อมูลรูปแบบต่าง ๆ ได้ถูกต้องหรือไม่ เช่นข้อมูลที่มีความยาวมาก ๆ น้อย ๆ หรือเป็น Null หรือ Empty string รวมทั้งข้อมูลในภาษาต่าง ๆ สีสัน แสดงรูปภาพอีกด้วย 3. Scenario test หรือ UI test ในการทดสอบจะใช้ทั้ง XCTest และ KIF (Keep It Function) สำหรับทดสอบ function การทำงานต่าง ๆ ของ app ในมุมมองของผู้ใช้งาน (Customer testing) เช่น
  • การ swipe, scroll
  • การ validate ข้อมูลและการทำงานต่าง ๆ ตาม function การทำงาน
  • การตรวจสอบการทำงานผ่านระบบ network
  • การบันทึกหน้าจอการทำงาน
โดยในการทดสอบกลุ่มนี้ ต้องทำการ mock ค่าต่าง ๆ ขึ้นมาด้วย เช่น Mock Network, Mock HTTP Server เป็นต้น สำหรับการจำลอง network สำหรับการจำลอง response จาก HTTP Server ทำให้เราสามารถจำลองสถานการณ์ต่าง ๆ ได้ เพื่อทำการทดสอบว่าระบบงานได้ตามที่คาดหวังหรือไม่ ?

ปิดท้ายด้วย Case Study ของทีมพัฒนา ซึ่งน่าสนใจอย่างมาก

แสดงดังรูปสำหรับการก่อนและหลังการ refactor หรือปรับปรุงการทดสอบให้เป็นไปตามแนวคิดข้างต้น testpyramid3 คำอธิบาย ก่อนจะทำการแก้ไขนั้น พบว่า ชุดการทดสอบมันไม่น่าเชื่อถือและเสถียรเลย แถมทำงานช้า แถมไม่ครอบคลุม business logic แถมดูแลรักษายากอีก เนื่องจากทดสอบในระดับ UI หรือ Scenario test เท่านั้น ผลที่ตามมาคือ เวลาการทำงานตั้งแต่ commit code ถึง publish app ขึ้น App Store มันไม่เสถียรเลย แน่นอนว่าทำให้ไม่มีใครเชื่อถือเลย !! จากปัญหาเหล่านี้จึงกลายเป็นเป้าหมายสำคัญ ในการแก้ไขและปรับปรุงรูปแบบการทดสอบ ซึ่งพยายามแยกการทดสอบในส่วนต่าง ๆ ออกไปยังกลุ่มการทดสอบทั้ง Unit test, Layout test และ UI test ผลที่ออกมาคือ ทำให้มีความมั่นใจในส่วนการทำงานต่าง ๆ มากขึ้น ลดเวลาการทดสอบลงไปอย่างมาก ทำให้กระบวนการโดยรวมมีความน่าเชื่อถือ รวมทั้งทำให้รู้เวลาของการทดสอบชัดเจน
คำถามสำหรับ iOS Developer คือ ปัจจุบันเราทดสอบกันอย่างไร ?

สวัสดีกับ Visual Studio for Mac (Preview 1)

$
0
0

screen-shot-2559-11-17-at-10-10-33

vs01 เมื่อคืนนั่งรอทาง Microsoft เปิดให้ download Visual Studio for Mac (Preview 1) ซึ่งมันก็คือร่างใหม่ของ Xamarin นั่นเอง ดังนั้นมาลองใช้งานกันหน่อย ว่าทำอะไรได้บ้าง ?
  • พัฒนา Native mobile app ทั้ง iOS และ Android ด้วยภาษา C#
  • พัฒนาระบบบน Cloud ของ Microsoft ได้เลยนั่นก็คือ Azure
  • พัฒนา Console app ด้วย .Net Core
  • พัฒนา Web app ด้วย .Net Core
  • พัฒนา Web app ด้วย ASP.Net
  • ทดสอบ Mobile app ผ่านระบบ Xamarin Test Cloud
มาเริ่มกันเลยดีกว่า

สำหรับการ Download และ ติดตั้งก็จัดเลยนะ

ใช้เวลาในการติดตั้งเยอะหน่อย เพราะว่าต้องทำการ download component ต่าง ๆ กว่า 4GB ถ้า internet ใครแรง ๆ น่าจะเร็วขึ้น แสดงดังรูป vs02 เมื่อเปิดขึ้นมาก็มี Template ของ project เพียบเลย ซึ่งแบ่งออกเป็น 3 กลุ่มหลัก ๆ คือ 1. Multiplatform 2. .Net Core 3. Other

ส่วนผมก็เริ่มต้นด้วย NUnit Library Project ดีกว่า

เป็น project ที่มี library สำหรับการเขียน test มาให้เลย นั่นคือ nUnit library vs03 จากนั้นเขียน test กันเถอะครับ มันสนุกมาก ๆ vs04

โดยที่ IDE ก็มีความสามารถเยอะเลย

ทั้งสนับสนุน git โดย default จัดการ code ต่าง ๆ ได้ดี มี Fix it ให้ ช่วยทำให้เขียน code ง่ายขึ้น มีการ history, merge, blame code ให้ vs05

สำหรับการจัดการ package ต่าง ๆ ทำงานผ่าน NuGet

แสดงดังรูป vs06

ส่วนปัญหาในการใช้งานก็มีพอสมควร

ตัวอย่างเช่น การพัฒนาระบบด้วย .Net Core ก็มีปัญหาตอน run แสดงดังรูป vs07 แต่ก็แก้ไขด้วยการ update มาใหม่ !! มันแปลกดีนะที่ต้องมานั่ง update เอง ผ่าน package manager นะ แถมใช้ไปใช้มาก็ค้าง ต้อง Force close เสียอย่างนั้น !! vs08 แต่โดยรวม ๆ แล้วสนุกดีนะครับ เป็นแนวทางที่น่าสนใจมาก ๆ สำหรับ Visual Studio

ปิดท้ายด้วยการสร้างระบบด้วย ASP.Net MVC บ้าง

ผลที่ออกมาคือ ชอบเลยเพราะว่าใช้งานได้ และ ดีด้วย vs09 แถมสามารถเพิ่มการสร้าง REST API ได้ง่าย ๆ vs10 ผลการทำงานเป็นดังรูป vs11

ลองสร้าง REST API หน่อยสิ

สามารถเขียน code แบบง่าย ๆ ได้ดังนี้ vs12 มาดูผลการทำงานหน่อยสิ ทำการแสดงผลข้อมูลในรูปแบบ XML หรือถ้าอยากเปลี่ยนเป็น JSON ก็ได้ง่าย ๆ vs13
เพียงเท่านี้น่าจะทำให้การเขียนโปรแกรมสนุกมากยิ่งขึ้นแล้วนะครับ มาลองใช้งานกันกับ Visual Studio for Mac Preview 1 !!!

Developer ต้องเรียนรู้และฝึกฝนอยู่อย่างสม่ำเสมอ

$
0
0

keepcoding_01

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

1. ลองแก้ไขปัญหาเดิมด้วยวิธีการใหม่ ๆ

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

2. สำหรับการเริ่มเขียนภาษาโปรแกรมใหม่ ๆ แนะนำให้เริ่มจากพื้นฐาน

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

3. เขียนเยอะแล้ว ก็ต้องอ่าน code เยอะเช่นกัน

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

สุดท้ายแล้ว Developer ที่ดี ไม่ต้องรอให้ใครมาบอกหรอกนะ ว่าต้องเรียนรู้อะไรบ้าง

เนื่องจากเป็นสิ่งที่ต้องทำด้วยจิตสำนึก หรือด้วยความเป็นมืออาชีพอยู่แล้ว การเขียนโปรแกรมก็เช่นกัน ถ้าอยากเก่งก็ต้องฝึกเขียน และเขียนต่อไปครับ Just Keep Coding ครับ ในปัจจุบันก็มี Course online เพียบเลย ตัวอย่างเช่น และที่ขาดไม่ได้เลยก็คือ Github
ปล. Developer ที่ไม่พัฒนาความสามารถในการเขียนโปรแกรมส่วนใหญ่ มักจะหยุดหรือไม่เขียนนั่นเอง หรือเขียน code แบบเดิม ๆ มาตลอด
  keepcoding_02

คำถาม :: Developer ทำการแบ่ง package ของระบบกันอย่างไร ?

$
0
0

structure

structure จากบทความเรื่อง Package by feature, not layer อธิบายถึงการแบ่ง package ต่าง ๆ ในระบบงาน ซึ่งเป็นสิ่งที่สำคัญมาก ๆ เป็นงานที่ทีมพัฒนาต้องช่วยกัน เป็นงานที่ทีมพัฒนาต้องตัดสินใจร่วมกัน ว่าต้องการให้โครงสร้างของระบบเป็นอย่างไร ? แน่นอนว่า ส่งผลต่อการพัฒนาระบบอย่างแน่นอน โครงสร้างของระบบงานก็มักสะท้อนหลาย ๆ อย่าง เช่นโครงสร้างของระบบ เช่นโครงสร้างของทีม เช่นโครงสร้างขององค์กร

ตัวอย่างเช่น ระบบอาจจะแบ่งเป็น layer หรือหน้าที่ของการทำงาน

ซึ่งประกอบไปด้วย
  • Controller
  • View
  • Model
  • DAO
  • Service
  • Interactor
แต่เมื่อระบบมีขนาดใหญ่ขึ้น มีจำนวน feature มากขึ้น มักเกิดปัญหา
  • การดูแลลำบากขึ้น เนื่องจากในแต่ละ layer มีไฟล์จำนวนมาก
  • การอ่าน code ลำบากขึ้น เพราะว่าต้องกระโดดไปกระโดดมาใน layer ต่าง ๆ
  • เรื่องของ modular ไม่ต้องพูดถึง ดังนั้นเรื่องของการ reuse ก็ไม่ต้องคิดถึงเลย ทำได้ยากมาก ๆ
  • แก้ไฟล์หนึ่งกระทบอีกหลาย ๆ ส่วน

ดังนั้นจึงมีอีกแนวคิดคือ การแยกตาม feature

โดยในแต่ละ feature จะประกอบไปด้วยทุกสิ่งอย่างที่จำเป็นทั้ง
  • Controller
  • View
  • Model
  • DAO
  • Service
  • Interactor
  • Storyboard
ส่วน module หรือส่วนการทำงานอะไรที่ต้องใช้ร่วมกัน ก็ให้ทำการแยกออกมาตัวอย่างเช่น Database และ Network รวมไปถึง Utility ที่ใช้งานร่วมกันเช่น การจัดการไฟล์ การจัดการรูปภาพ เป็นต้น ด้วยวิธีการนี้น่าจะทำให้การพัฒนาระบบดูดีขึ้น ดูแลง่ายขึ้น ลดผลกระทบต่าง ๆ จากการแก้ไข ง่ายต่อการ scale ง่ายต่อการย้าย feature ออกไปจากระบบ ง่ายต่อการอ่าน code
สุดท้าย คำถามคือ Developer ทำการแบ่ง package ของระบบกันอย่างไร ?

พื้นฐานการใช้งาน Git ที่ต้องรู้

$
0
0

basic-git

basic-git ปกติในการใช้ git ของผมจะใช้งานผ่าน command line เสมอ เนื่องจากใช้งานผ่าน GUI ไม่เป็น !! โดยคำสั่งที่ใช้บ่อย ๆ ประกอบไปด้วย
  • push
  • pull
  • status
  • add
  • commit
  • diff
  • log
ซึ่งน่าจะเพียงพอ !! แต่ขอแนะนำพื้นฐานการใช้งาน git ที่น่าจะต้องรู้ หรือถ้าไม่รู้ก็ควรจะศึกษาเพิ่มเติม เนื่องจากจะช่วยทำให้ใช้งาน git ได้ดีและมีประสิทธิภาพมากยิ่งขึ้น พื้นฐานมันเป็นเรื่องที่สำคัญมาก ๆ นะ

เริ่มด้วยอย่างแรกคือไฟล์ .gitignore

น่าจะเป็นไฟล์แรกของการสร้าง project หรือ repository ของ git เลยก็ว่าด้วย เพื่อกรองไฟล์ที่เราไม่ต้องการออกไป เช่น
  • ไฟล์ที่ถูกสร้างมาจาก IDE เช่น configuration ต่าง ๆ ซึ่งเป็นของเฉพาะเครื่อง ถ้าเอาขึ้นก็บรรลัยแน่นอน (คนในทีมยกเว้นตัวเอง)
  • ไฟล์ที่ OS สร้างขึ้นมาให้เอง เช่น .DS_Store บน MacOS เป็นต้น
โดยที่ไฟล์ .gitignore ของภาษาต่าง ๆ ลองไปดู template ได้จาก Github::Gitignore แต่ถ้าต้องการสร้างไฟล์ .gitignore ใน project ของเรา แนะนำให้ใช้งานร่วมกับไฟล์ .gitignore_global ซึ่งอยู่ใน <Home directory> ของเรานั่นเอง จากนั้นทำการเพิ่มเข้ามาในไฟล์ .gitconfig หรือไฟล์ configuration ของ git ก็ได้นะ โดยใช้คำสั่งดังนี้ [code] $git config --global core.excludesfile <Home directory>/.gitignore_global [/code] หรือเพิ่มในไฟล์ .gitconfig ได้เองดังนี้ [code] [core] excludesfile = <Home directory>/.gitignore_global [/code] บ่อยครั้งจะใช้งานไฟล์ .gitignore_global ร่วมกับ .gitignore ของแต่ละ repository

ถ้าเราต้องการตรวจสอบว่าไฟล์ต่าง ๆ ถูก ignore ออกไปหรือไม่ ?

ลองใช้งานผ่านคำสั่ง $git ls-files ซึ่งจะแสดงไฟล์ทั้งหมดที่ไม่ถูก ignore นะครับ มักใช้ร่วมกับ grep และ sed ตัวอย่างเช่นต้องการหาไฟล์นามสกุล .js หรือ JavaScript เท่านั้น จะใช้คำสั่งดังนี้ [code] $git ls-files | grep -E \.js$ [/code]

ต่อมาคือไฟล์ .gitconfig

เท่าที่พบเจอคนใช้งาน git มา มักพบว่าจะไม่รู้ไฟล์ .gitconfig ถ้าใช้งานก็ผ่านคำสั่ง $git config --global กันหมด โดยไฟล์นี้จะอยู่ที่ <Home directory>/.gitconfig เราสามารถทำการ config ค่าต่าง ๆ ให้เหมาะสมต่อการใช้งานได้ เช่น
  • User information ทั้งชื่อและ email
  • สีสันต่าง ๆ เช่นการ diff, status, grep และ alias เป็นต้น
  • พวก merge tool และ diff tool
ตัวอย่างการกำหนดสีแต่ละสถานะของไฟล์ เมื่อใช้งานผ่าน git status สามารถแบ่งสีตามสถานะดังนี้
  • แสดงสีเขียวเมื่อทำการเพิ่มไฟล์เข้าไปยัง repository ผ่านคำสั่ง git add
  • แสดงสีเหลืองเมื่อทำการแก้ไขไฟล์
  • แสดงสีแดงเมื่อทำการสร้างไฟล์ใหม่เข้ามา
[code] [color "status"] added = green bold changed = yellow bold untracked = red bold [/code] แสดงผลการใช้งานดังนี้ basic-git-02

ต่อมาคือ git alias

สำหรับการย่อคำสั่งยาว ๆ ให้สั้นลง ตัวอย่างที่ใช้บ่อย ๆ ก็เช่น git grep และ git log [code] [alias] mygrep = grep --extended-regexp --break --heading --line-number [/code] สามารถเรียกใช้งานแทนด้วย [code] $git mygrep "your pattern" [/code]

หรือว่าการใช้งาน git log เพื่อค้นหาสิ่งที่ต้องการ

ซึ่งแต่ละคำสั่งมันยาวมาก ๆ ทั้งการ grep ทั้งการใช้งาน git log ซึ่งมี option ต่าง ๆ เยอะมาก เช่นช่วงของวันที่ที่ต้องการ สามารถใช้ alias มาช่วยได้ดังนี้ [code] [alias] search = log --no-merges -i -E --pretty='%h (%ad) - [%an] %s %d' --date=format:'%b %d %Y' —grep [/code] ใช้งานแบบง่ายด้วยคำสั่ง [code] $git search "your pattern" [/code]
เป็นอย่างไรบ้างสำหรับการใช้งาน git น่าจะพอมีประโยชน์บ้างเล็กน้อยนะครับ

ว่าด้วยเรื่อง Protocol Oriented Programming (POP) ของภาษา Swift

$
0
0

pop-swift

pop-swift ในภาษา Swift นั้นพยายามแก้ไขปัญหาต่าง ๆ ที่มากับ Object Oriented Programming (OOP) โดยการนำแนวคิด Protocol Oriented Programming (POP) มาใช้งาน ซึ่งถูกแนะนำครั้งแรกในงาน WWDC 2015 แน่นอนว่ามันทำให้การเขียนโปรแกรมด้วยภาษา Swift เปลี่ยนไป แถมยังง่ายและสนุกขึ้นอีกด้วย มาดูกันนิดหน่อยว่า นำไปใช้ในการพัฒนาระบบอย่างไรบ้าง ?

สำหรับผู้เริ่มต้นแนะนำให้ศึกษาจาก

มาดูการใช้งานบ้างดีกว่า

ปกติเรามักจะมี feature พื้นฐานทั่วไป ที่ทุก ๆ หน้า หรือหน้าส่วนใหญ่จะต้องมี ตัวอย่างเช่นใน iOS app เกือบทุก ๆ หน้าจะต้องมีการ logout ออกจากระบบ ดังนั้นใน ViewController จำเป็นต้องมี function logout() ซึ่งแน่นอนว่าเราจะสร้าง BaseViewController ขึ้นมาดังนี้ [gist id="15468e328189734988c015732229ed7f" file="1.swift"] แต่ปัญหาที่เกิดขึ้นคือ ในทุก ๆ ViewController ต้องทำการ extend มาจาก class BaseController ทั้ง ๆ ที่ในบางหน้าหรือ ViewController ไม่จำเป็นต้องใช้ function logout() !! แต่ก็ต้องทำเพราะว่า มันคือ standard หรือ pattern ที่ตกลงร่วมกัน !! ดังนั้นแนวคิดนี้ ไม่น่าจะดีนะ ?

มาดูแนวคิดของ Protocol Oriented Programming (POP) กันหน่อยสิ

มันก็คือการนำ Protocol ซึ่งเป็นหนึ่งใน feature ของภาษา Swift ถ้าผมทำการสร้าง protocol ชื่อว่า Logoutable ขึ้นมาล่ะ จากนั้น ViewController ไหนที่ต้องการความสามารถการ logout ก็ทำการ conform ไปได้
ปล. แนวคิดมันเหมือนกับ interface เลยนะเออ
มาดูตัวอย่าง code กัน [gist id="15468e328189734988c015732229ed7f" file="=2.swift"] ดูเหมือนว่าจะดีนะ !! แต่ว่าทุก ๆ ViewController ที่ทำการ conform protocol Logoutable นั้น ต้องทำการ implement function logout() เองทั้งหมด ซึ่งไม่น่าจะดีแน่นอน !! ลองคิดดูสิว่า ถ้าเรามี ViewController เป็นสิบ ๆ ชีวิตน่าจะยากขึ้นนะ !!

โชคดีที่ในภาษา Swift มี Protocol Extension มาให้

ดังนั้นเราจึงสามารถเขียน extension เพิ่มเติมให้กับ Protocol ได้เลย โดยจะทำการเพิ่ม function logout() ให้กับ ทุก ๆ ViewController ที่ทำการ conform กับ protocol Logoutable เลย เมื่อนำทุกอย่างมารวมกัน สามารถเขียน code ได้ดังนี้ [gist id="15468e328189734988c015732229ed7f" file="3.swift"]
ซึ่งน่าจะทำให้การเขียน code ด้วยภาษา Swift สนุกขึ้น ด้วยแนวคิดของ POP + Extension นะครับ

สิ่งที่น่าสนใจจากบทความเรื่อง Last Line Effect

$
0
0

last-line-effect

last-line-effect จากบทความเรื่อง Last Line Effect ทำการศึกษาผลกระทบที่มักเกิดกับการ Copy-and-Paste code ซึ่งแน่นอนว่า developer ส่วนใหญ่ชอบใช้งาน แถมใช้งานกันบ่อย ๆ อีกด้วย และบ่อยครั้งพบว่าการกระทำแบบนี้ก่อให้เกิดความผิดพลาดขึ้นมา
หนึ่งในข้อผิดพลาดนั้นก็คือ code ใน block หรือบรรทัดท้าย ๆ นั่นเอง มาดูผลการศึกษากัน

ผู้ทำการศึกษาได้สรุปและจัดเก็บ bug จากระบบงานต่าง ๆ

ไว้ในรูปแบบของตนเองทำให้ง่ายต่อการศึกษา ซึ่งอยู่ที่ Detected errors database โดย pattern หนึ่งที่ได้ทำการศึกษาคือ Last Line Effect

Last Line Effect มันคืออะไร ?

ในการเขียนโปรแกรมของ developer นั้น บ่อยครั้งมักมี code คล้าย ๆ กันทำงานต่อเนื่องกัน ดังนั้นถ้า developer จะพิมพ์สิ่งที่ซ้ำ ๆ กัน มันก็น่าเบื่อสุด ๆ สิ่งที่ developer มักจะทำก็คือ ทำการ Copy-and-Paste code ที่คล้าย ๆ กันซะ จากนั้นจึงตามไปแก้ไขส่วนที่ต้องการ สิ่งที่ตามมาคือ ความผิดพลาด เนื่องจากเมื่อทำการ copy เยอะ ๆ แล้ว ทำให้ developer หลงลืมไปว่า จะต้องแก้ไขตรงไหนอย่างไรบ้าง !!

มาดูตัวอย่าง code จากการศึกษาเรื่อง Last Line Effect กันบ้าง ?

ซึ่งมักจะเกิดในช่วง ๆ บรรทัดท้ายของโปรแกรม หรือของแต่ละ method หรือในแต่ละ block [gist id="9dfda1eaea9d7fac4fe585e98a8afe6b" file="1.cpp"] คำอธิบาย เห็นบรรทัด z+= หรือไม่ ? ไม่น่าจะเป็นการเพิ่มค่าจาก other.y นะ !! หรือจากเงื่อนไขยาว ๆ ของการเปรียบเทียบ [gist id="9dfda1eaea9d7fac4fe585e98a8afe6b" file="2.cpp"] คำอธิบาย THREADS= มีความยาวเป็น 8 นะ !! หรือว่า copy มาแบบนี้ !! [gist id="9dfda1eaea9d7fac4fe585e98a8afe6b" file="3.cpp"] หรือว่าแบบนี้ ดูผ่าน ๆ หาข้อผิดพลาดยากมาก ๆ !! [gist id="9dfda1eaea9d7fac4fe585e98a8afe6b" file="4.cpp"] หรือเป็นพวกย้ำคิดย้ำทำ !! [gist id="9dfda1eaea9d7fac4fe585e98a8afe6b" file="5.cpp"]
ใครเคยทำแบบนี้บ้างยกมือขึ้น ?

วิธีการแก้ไขนั้นทำได้ไม่ยากเลยนะ

แต่ขอแนะนำให้คิดก่อนว่า การจะเป็น developer ที่ดีต้องทำอย่างไร ? โดยมากแล้วมักจะสร้างข้อผิดพลาดเล็กน้อยขึ้นมาเสมอ
แต่สิ่งที่น่ากลัวกว่าคือ ไม่รู้ว่าตนเองทำผิดพลาด !!
เนื่องด้วยสาเหตุอะไรก็ตาม หลัก ๆ มาจาก feedback loop ของการทดสอบมันนานมาก ๆ ดังนั้นสิ่งที่ควรกระทำสำหรับ developer ที่ดีคือ รู้ข้อผิดพลาดต่าง ๆ ให้รวดเร็วที่สุดเท่าที่จะเป็นไปได้ เพื่อป้องกันและแก้ไขข้อผิดพลาดเหล่านั้น ก่อนที่จะกลายเป็นข้อผิดพลาดอันใหญ่หลวง !! หนึ่งในแนวปฏิบัติคือ Test-Driven Development (TDD) ทำซะ แล้วจะช่วยทำให้คุณรู้ว่า จุดอ่อนและข้อผิดพลาดใน code อยู่ตรงไหน

ข้อดีและข้อเสียของ API Gateway

$
0
0

api-gateway-00

api-gateway-00 ในโลกของการสร้างระบบแบบ API-centric หรือแยก service ต่าง ๆ ออกมาในรูปแบบของ Microservice นั้น สิ่งที่มักจะถูกพูดถึงก็คือ API Gateway ดังนั้นเรามาดูกันว่า
  • API Gateway มันคืออะไร ?
  • API Gateway มีข้อดีและข้อเสียอย่างไรบ้าง ?
มาเริ่มกันเลย

API Gateway คืออะไร ?

เป็นจุดศูนย์รวมของการเข้าถึง API ต่าง ๆ ในระบบ ทั้งการเข้าถึงแบบ 1:1 และ 1:N ทำให้การเข้าถึง API ง่ายขึ้น ทำให้สามารถกำหนดรูปแบบการใช้งานได้ง่ายขึ้น ตัวอย่างเช่น limit การใช้งาน เป็นต้น ทำให้สามารถกำหนดเรื่อง authentication และ authorization ได้ง่ายขึ้น ทำให้สามารถวิเคราะห์การใช้งานได้ง่ายขึ้น
โดยรวมแล้วเป็นอีกหนึ่ง layer ที่เพิ่มขึ้นมาเพื่อจัดการ API ที่มีจำนวนมากมายนั่นเอง
ลองคิดดูสิว่า ถ้าระบบที่มีสถาปัตยกรรมแบบ Microservice จริง ๆ จะมีจำนวน service มากมายเพียงใด ตั้งแต่หลัก 10 ไปจนถึงหรือพัน หลักหมื่น แน่นอนว่า การเข้าถึงแต่ละ service มันน่าจะยากนะ นั่งจำ endpoint ของ service กันเยอะเลย !! ดังนั้น API Gateway น่าจะเป็นอีกหนึ่งตัวช่วยที่น่าสนใจ แต่ถ้าออกแบบไม่ดีก็บรรลัยได้ง่าย ๆ เช่นกัน !! แสดงโครงสร้างดังรูป api-gateway

มาดูข้อดีของ API Gateway กันบ้าง ?

1. แยกส่วนการใช้งาน API จากผู้ใช้งาน ผู้ใช้งานจะเห็นเพียง API จาก gateway เท่านั้น ว่าต้องส่ง request ไปที่ไหน ? มี input อย่างไร ? ได้ output อย่างไร ? โดยไม่รู้เลยว่าข้างในทำงานอย่างไร วิธีการนี้จะส่งผลดีต่อการแก้ไขปรับปรุง API ที่อยู่ด้านในระบบ โดยไม่กระทบต่อผู้ใช้งานโดยตรง รวมทั้งซ่อนการจัดการเรื่อง versioning และ service discovery ไว้อีกด้วย 2. ใช้สำหรับป้องกันการโจมตีจากผู้บุกรุก ทั้ง SQL Injection, XML exploit และ Denial-of-Service (DoS) เนื่องจากเป็น layer ที่ผู้ใช้งานจากภายนอกจะเข้าถึง API ได้ 3. ทำให้ service ภายในใช้งาน protocol ที่หลากหลายได้ ผู้ใช้งานสามารถใช้งานผ่าน HTTP/REST ได้ปกติ แต่ service ภายในสามารถใช้ protocol ที่หลายหลาย ในการติดต่อสื่อสารกันได้ เนื่องจากแต่ละ protocol ก็มีข้อดีและข้อเสียแตกต่างกันไป รวมทั้งทำให้ง่ายต่อการ integrate เข้ากับ Legacy system อีกด้วย เช่น ProtoBuf, SOAP, RPC, WebService เป็นต้น 4. ช่วยลดความซับซ้อนของ service ต่าง ๆ ลงไป ความสามารถพื้นฐานต่าง ๆ ของแต่ละ service นั้น เราสามารถนำมา implement ไว้น API Gateway ได้เลย ทำให้ผู้พัฒนาสนใจเฉพาะ service นั้น ๆ ไปเลย ไม่จำเป็นต้องไป implement ไว้ในแต่ละ service เนื่องจากเป็นการเพิ่มความซับซ้อนเข้าไปโดยใช่เหตุ เช่น
  • การ authentication
  • การ authrorization
  • กำหนด usage limit
5. ทำให้ทดสอบระบบได้ง่ายขึ้น ในทดสอบแบบ integration นั้น เราสามารถจำลองหรือ mock service ขึ้นมาได้ง่าย ๆ เนื่องจากบางครั้ง API ด้านหลังอาจจะพัฒนาไม่เสร็จหรือยังไม่พร้อม

มีข้อดีก็ต้องมีข้อเสียกันบ้างสิ ?

ปัญหาใหญ่ก็คือ Single Point of Failure (SPoF) ดังนั้นในการออกแบบต้องให้ความสำคัญอย่างมาก ลองคิดดูสิว่า ถ้า API Gateway พังไป มันส่งผลกระทบต่อทั้งระบบเลยนะ และจะ scaling ระบบกันอย่างไร ? ต่อมาเรื่องของการ configuration routing ของ service ต่าง ๆ ซึ่งมันเยอะมาก ๆ ดังนั้นควรต้องมีเครื่องมือและระบบที่สนับสนุนเรื่องเหล่านี้ด้วย มิเช่นนั้นจะกลายเป็นปัญหาใหญ่ในการจัดการ สิ่งที่สำคัญมาก ๆ คือ การ deploy ระบบงาน จำเป็นอย่างยิ่งต้องทำงานแบบอัตโนมัติ ทั้งการเพิ่ม แก้ไข และ ลบ service จำเป็นต้องใช้คนที่มีความสามารถ จำเป็นต้องใช้เครื่องมือที่เหมาะสมกับงาน Reference Websites https://dzone.com/articles/why-do-microservices-need-an-api-gateway

ทำความรู้จักกับ Annotation ต่าง ๆ ใน JUnit 5 กัน (Jupiter)

$
0
0

junit5-logo

junit5 จากบทความเรื่อง การเตรียมความพร้อมสำหรับ JUnit 5 ซึ่งในตอนนั้นเป็น alpha version แต่ตอนนี้อยู่ใน version 5.0.0 M2 แล้ว โดยสิ่งที่น่าสนใจมาก ๆ รองลงมาจาก Architecture ที่เปลี่ยนใหม่ นั่นก็คือ Annotation ต่าง ๆ ที่มีให้ใช้งานนั่นเอง เนื่องจากมีการเปลี่ยนแปลงเยอะเหมือนกัน ดังนั้นมาดูกันหน่อย
JUnit5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
คำอธิบาย
  • JUnit Platform คือ interface ระหว่าง JUnit กับ client tool อื่น ๆ เช่น IDE และ build tool อื่น ๆ เช่น Spock, Cucumber และ Fitness ซึ่งถูกเตรียมไว้ในสิ่งที่เรียกว่า TestEngine โดยเป็นหัวใจหลักของ JUnit5 กันเลย
  • JUnit Jupiter คือส่วนหลักของการเขียน test และการเขียน extension เพิ่มเติม แน่นอนว่าก็ทำงานผ่าน TestEngine ด้วยเช่นกัน
  • JUnit Vintage คือ TestEngine สำหรับทำงานกับ JUnit 3 และ 4
ปล. สำหรับการ import ใน JUnit 5 ต้องใช้ผ่าน org.junit.jupiter.api นะ

Annotation ใน JUnit 5 ประกอบไปด้วย

  • @TestFactory สำหรับการบอกว่า method นั้น ๆ เป็น dynamic test !!
  • @DisplayName สามารถทำการกำหนดชื่อของ test case ได้แล้ว ก่อนนี้ใช้จากชื่อ method
  • @Tag หรือป้ายชื่อเพื่อเอาไว้แบ่งกลุ่มของการทดสอบนั่นเอง และใช้ filter ได้อีกด้วย ใน version ก่อนหน้าคือ @Category
  • @BeforeEach โดย method นี้จะถูกเรียกใช้งานก่อนแต่ test case เสมอ ใน version ก่อนหน้าคือ @Before
  • @BeforeAll โดย method นี้จะถูกเรียกใช้งานครั้งเดียวก่อน test case แรกจะถูกเรียก ใน version ก่อนหน้าคือ @BeforeClass
  • @AfterEach โดย method นี้จะถูกเรียกใช้งานหลังจากที่แต่ละ test case ทำงานเสร็จสิ้น ใน version ก่อนหน้าคือ @After
  • @AfterAll โดย method นี้จะถูกเรียกใช้งานครั้งเดียวหลังจากที่ test case สุดท้ายใน class ทำงานเสร็จสิ้น ใน version ก่อนหน้าคือ @AfterClass
  • @Disable สำหรับปิดการทดสอบใน test case นั้น ๆ ใน version ก่อนหน้าคือ @Ignore
  • @ExtendWith มาแทน @RunWith, @Rule และ @ClassRule นะ

มาลองเปรียบเทียบการใช้งานของ Annotation กันหน่อย

ก่อนอื่นก็ต้องเตรียม library หรือ dependency กันก่อน ซึ่งผมใช้ Apache Maven จัดการ [gist id="b04cbdeec3c48f489d3f3d2c588d9e39" file="pom.xml"] เริ่มที่ @BeforeAll/@AfterAll กับ @BeforeEach/@AfterEach สิ่งที่ต่างกันคือ signature ของ method นั่นเอง ไม่ต้องเป็น static method แล้วนะ [gist id="b04cbdeec3c48f489d3f3d2c588d9e39" file="1.java"] ต่อมาก็กำหนดชื่อของ test case เองด้วย @DisplayName [gist id="b04cbdeec3c48f489d3f3d2c588d9e39" file="2.java"] อยากปิด test case ไหนก็ทำไปด้วย @Disable !! ทำไปทำไม ? [gist id="b04cbdeec3c48f489d3f3d2c588d9e39" file="3.java"] ต่อมาคือ @Tag ที่ใช้งานแทน @Category [gist id="b04cbdeec3c48f489d3f3d2c588d9e39" file="5.java"]

มาดูอีกเรื่องที่สำคัญคือ Exception Testing

สำหรับการตรวจสอบ exception ต่าง ๆ ของระบบงาน ใน JUnit5 นั้นไม่มี expected หรือ Rule อีกแล้วนะ แต่ก็มีของมาให้ใช้งานก็คือ expectThrows() กับ assertThrows() ซึ่งจากการใช้งานก็ดูแปลก ๆ ดีเหมือนกัน เนื่องจากเอา Lambda มาใช้งาน [gist id="b04cbdeec3c48f489d3f3d2c588d9e39" file="4.java"] สำหรับ source code ตัวอย่างอยู่ที่ Github::Up1:Demo JUnit 5
วันนี้ Java Developer พร้อมกับ JUnit 5 กันหรือยัง ?

สวัสดี Ethereum ด้วย Hello World Project

$
0
0

eth_00

eth_00 สองวันหนึ่งคืนในการเข้าร่วมงาน Blockchain Hackathon ได้รับความรู้และประสบการณ์มากมายเกี่ยวกับ
  • แนวคิด Blockchain ทั้งในยุค 1.0 และ 2.0
  • Blockchain ecosystem
  • Ethereum
  • การสร้าง Contract ใน Ethereum
  • การพัฒนาระบบด้วย web3.js
รวมทั้งสิ่งที่สำคัญมาก ๆ คือ การพัฒนาระบบงานผ่าน Contract ของ Ethereum เป็นแนวคิดที่สนุกมาก ๆ เทียบง่าย ๆ ก็คือ Serverless นั่นเอง ดังนั้นมาลองสร้างระบบงานง่าย ๆ ผ่าน Contract ของ Ethereum กันดีกว่า เพื่อจะได้เข้าใจกันมากขึ้น

สิ่งที่ต้องเข้าใจและต้องเตรียมก่อนลงมือประกอบไปด้วย

  • ติดตั้ง Ethereum Wallet หรือ Mist ก็ได้
  • จากนั้นก็ทำการ sync ข้อมูลมาซะ (สำหรับ private หรือ testnet)
  • ทำความรู้จักกับ Solidity เป็นภาษาสำหรับสร้าง Contract ใน Ethereum ซึ่งจะมีรูปแบบคล้าย ๆ กับ JavaScript
  • ในการเขียน contract นั้นจะทำผ่าน Browser Solidity
  • ระบบ web application จะพัฒนาด้วย library ชื่อว่า web3.js
สิ่งที่น่าสงสัยสำหรับการเริ่มต้นพัฒนาระบบงานด้วย Ethereum นั้น มี resource จำนวนที่น้อยมาก ๆ หรือไม่ก็ไม่สามารถทำตามได้เลย ดังนั้นจึงทำการสรุปขั้นตอนการศึกษาและพัฒนาแบบเบื้องต้นไว้นิดหน่อย

เมื่อทุกอย่างพร้อมก็มาเริ่มกันดีกว่า

สิ่งที่น่าสนใจมาก ๆ คือ architecture ที่เปลี่ยนไป จากเดิมคือ Client-Server แสดงดังรูป eth_01 แต่เมื่อเปลี่ยนเป็นระบบแบบ Decentralization แล้วจะเปลี่ยนไปดังรูป จะพบว่าในส่วนของ Data logic จะอยู่ในส่วนของ Blockchain ซึ่งในส่วนนี้เราจะทำผ่าน Contract ของ Ethereum eth_02

ดังนั้นสิ่งที่เราต้องทำก่อนคือ การออกแบบ Contract

ซึ่งพัฒนาด้วยภาษา Solidity นั่นเอง มาดู HelloWorld Contract เป็นดังนี้ [gist id="13e3f768b31d7c5e5e1eac9f375f736f" file="hello.sol"] ใน contract ประกอบไปด้วย 2 function
  1. sayHello() ทำการส่งค่า Hello world กลับออกมา
  2. sayHi(name) ทำการส่งชื่อเข้าไป แล้วส่งคำทักทายออกมา
ปล. ใน function strConcat นั้นเอาไว้เชื่อมต่อข้อมูล เนื่องจากในภาษา Solidity มันไม่มีนะ !! ชีวิตลำบากใช้ได้เลย การเขียนภาษา Solidity มีตัวช่วยมากมายนะ เช่น ตัวอย่างการใช้งานผ่าน Browser Solidity ซึ่งสามารถทดสอบการทำงานได้เลย แสดงดังรูป eth_03

เมื่อทุกอย่างเรียบร้อยแล้ว ก็ทำการสร้าง Contract สิ

ใช้ได้ทั้ง Mist และ Ethereum Wallet โดยไปที่ menu Contract และนำ code ที่เขียนไว้ไปใส่ จากนั้นทำการ deploy ดังรูป eth_04 ทำการกรอก password และผลที่ได้มีสิ่งที่เราต้องใช้งาน 2 อย่างคือ 1. Contract address 2. Contract Interface แสดงดังรูป eth_05 ข้อมูลของ Contract Interface ซึ่งอยู่ในรูปแบบของ JSON eth_06 รวมทั้งเราสามารถทดสอบการใช้งานได้อีกด้วยนะ แต่จำเป็นต้องมี ether หรือเงินด้วยนะ eth_07

ถึงเวลาของการเขียน code เพื่อใช้งาน Hello Contract ที่สร้างไว้

ผมเลือกเขียนด้วย web3.js + Node.js มีขั้นตอนการทำงานดังนี้
  1. ทำการ import library web3.js
  2. ทำการสร้าง contract object จาก contract address และ contract interface
  3. ทำการเรียกใช้งาน function ต่าง ๆ ที่สร้างไว้ใน contract
[gist id="13e3f768b31d7c5e5e1eac9f375f736f" file="hello.js"] ทำการ run ด้วย Node.js ดังนี้ [code] $npm install web3 $node hello.js [/code] ผลที่ได้คือ ไม่สามารถติดต่อไปยัง http://localhost:8545 !! เนื่องจากเรายังไม่ start server ขึ้นมา ดังนั้นสิ่งที่ต้องทำคือ start server ขึ้นมาด้วย geth ด้วยคำสั่งดังนี้ [code] $geth --testnet --fast --rpc --rpccorsdomain "*" --rpcapi "web3,eth,personal" --rpcaddr "0.0.0.0" [/code] คำอธิบาย
  • ใช้ network test ของ Ethereum
  • เปิดให้เรียกแบบ cross domain ได้
แสดงผลการทำงานดังรูป eth_08 เพียงเท่านี้ก็น่าจะเริ่มใช้งานได้แล้ว แต่ยังมีรายละเอียดต่าง ๆ อีกเยอะเลยครับ Source code ตัวอย่างอยู่ที่ Github::Up1::Demo with Ethereum

จากการพัฒนาระบบและลองผิดลองถูกมา 2 วัน 1 คืนพบว่า

ระบบ network ของ private หรือ test net ของ Ethereum นั้นไม่มีความเสถียรอย่างยิ่ง รวมทั้งต้องการพื้นที่จัดเก็บข้อมูลจำนวนมาก แต่สามารถแก้ไขด้วยการใช้งาน TestRPC ซึ่งเป็น Ethereum client สำหรับการทดสอบและพัฒนา ทำงานเร็วมาก ๆ หรือติดตั้ง server กลางทิ้งไว้ บางทีอาจจะทำการสร้าง private ethereum มาใช้เอง น่าจะทำให้ชีวิตดีขึ้นมา แถมยังมี Docker Image ให้ใช้งานอีกนะ ภาษา Solidity สำหรับการพัฒนา Contract ใน Ethereum นั้น ยังมีความยุ่งยากมากมาย และ ไม่ยืดหยุ่นต่อการใช้งาน แต่เป็นเพียงการเรียนรู้แบบคร่าว ๆ เท่านั้น ยังไม่ได้ลงไปในรายละเอียดมากนัก แต่ว่าก็ยังชอบในแนวคิดของ Contract สำหรับฝั่ง client ซึ่งเป็น web application โดยใช้ library ชื่อว่า web3.js นั้น พบว่า feature ต่าง ๆ ยังไม่สมบูรณ์ และขาด feature หลาย ๆ อย่างไป เช่นการรอจนกว่า block ที่สร้างใหม่นั้นจะถูก update ใน Ethreum network แล้วหรือไม่ เป็นต้น ในการสร้าง Contract, Block และ Transaction ขึ้นมานั้น เราสามารถเข้าไปตรวจสอบได้จาก Etherscan ซึ่งทำให้การพัฒนาง่ายขึ้นอีกเป็นกอง

โดยรวมแล้วเป็น 2 วัน 1 คืนที่คุ้มมาก ๆ ครับ

ได้รับความรู้เยอะมาก ๆ ได้คุยกันเยอะมาก ๆ ได้กินเยอะมาก ๆ อิ่มมาก ๆ ได้นอน 2 ชั่วโมง สุดท้ายขอขอบคุณทีมผู้จัดงานครับผม และได้เวลาลบข้อมูลออกไปจากเครื่องได้แล้ว !! Reference Websites https://blog.ethereum.org/2016/07/12/build-server-less-applications-mist/
Viewing all 2000 articles
Browse latest View live