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

ผลที่น่าสนใจจากแบบสำรวจเรื่องของ DevSecOps

$
0
0

อ่านเอกสารเกี่ยวกับการสำรวจเรื่อง DevSecOps Community Survey
มีหลาย ๆ เรื่องที่น่าสนใจ เลยสรุปไว้ดูนิดหน่อย
น่าจะมีประโยชน์สำหรับบริษัทที่เริ่มนำมาประยุกต์ใช้งาน
เพื่อแก้ไขปัญหาและปรับปรุงการพัฒนาไปจนถึงส่งมอบระบบงานให้ดีขึ้น
มาเริ่มกันเลย

เป็นผลการสำรวจจากจำนวน 2,076 คน
พบว่านำแนวคิดและแนวปฏิบัติของ DevOps มาใช้งานจริงจัง 25%
กำลังนำมาใช้งานเพื่อปรับปรุงบางอย่าง 49%
ที่เหลือยังไม่ได้นำมาใช้งานจริงจัง
โดยรวมการนำมาใช้งานสูงขึ้นมาแบบก้าวกระโดดมาก ๆ คือ 338%

เรื่องของ Security นั้นได้ถูกนำเข้าไปเป็นขั้นตอนหนึ่งในระบบ Automation ของทุก ๆ ขั้นตอนการพัฒนา

ตั้งแต่การออกแบบ พัฒนา ทดสอบ ไปถึงกาาร deploy บน production server เรื่องของ Automation จึงขาดไม่ได้เลย

แนวโน้มต่าง ๆ ก็วิ่งไปสู่โลกของ containerization ทั้งหมด
ทั้งเรื่องของ image registry ที่ใช้ภายใน
ทั้งเรื่องของ container security
ทั้งเรื่องของ Infrastructure as a Code
นี่มันเครื่องมือล้วน ๆ  !!

การลงทุนในเรื่องของ Security Tools สูงขึ้นมาก ๆ ประกอบไปด้วย

  • Application firewall
  • Container และ application security
  • Open source governance 
  • Static application analysis
  • Dynamic application analysis

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

อีกอย่างคือ มากกว่า 62% ของบริษัทยังไม่ควบคุม !!
หรือจัดการการใช้งาน open source หรือ 3-party component
ที่ใช้ใน application เลย ซึ่งนี่ถือว่า น่ากลัวมาก ๆ

แต่เรื่องที่ขัดแย้งมาก ๆ คือ 100:10:1
100 คือจำนวนคนในทีมพัฒนา
10 คือจำนวนคนในทีม operation
1 คือจำนวนคนในทีม security

คำถามแรกคือ มีการอบรมเรื่องของ Application Security หรือไม่ ?
35% ของคำตอบทั้งบริษัทที่ขั้นตอนการพัฒนาแบบ waterfall และ Agile ตอบว่า ไม่มี !! ส่วนอื่น ๆ ก็มีทั้ง E-learning และ การอบรมภายใน

ดูเหมือนว่า เรื่องความรู้ต่าง ๆ ทาง security น่าจะยังขาดอยู่สูงมาก ๆ
ทั้ง Application, Network และ Infrastructure
แต่เครื่องมือนั้นมาเต็มที่เลย มันดูแปลก ๆ ดีนะ !!

ส่วนใหญ่เห็นว่า
ต้องเตรียมพร้อมรับมือกับการโจมตี
แต่ความรู้ในการสร้างและดูแลกลับน้อย
จุดนี้คือเรื่องใหญ่เลย จะพึ่งเครื่องมืออย่างเดียวไม่เพียงพอ
คนก็ต้องมีความรู้ด้วยเช่นกัน


NPM :: แก้ไขปัญหา Unexpected end of JSON input while parsing near

$
0
0

ปัญหาที่เจอ
เมื่อ run . npm install ใน project ที่กำลังพัฒนา
แล้วเจอปัญหาแบบนี้ Unexpected end of JSON input while parsing near

การแก้ไขนั้นมีเพียบเลยจึงสรุปไว้หน่อย
ซึ่งเป็นปัยหามาจาก cached ของ npm เอง

  1. ลบไฟล์ package-lock.json และ run npm cache clear --force
  2. ทำการลบ npm cached ตรง ๆ ที่ ~/.npm บน Linux/Mac หรือ %AppData%/npm-cache บน Windows

[Part 4] สรุป 50 เรื่องสำหรับผู้เริ่มต้นพัฒนาระบบด้วยภาษา Go

$
0
0

ใน Part  4 นี้จะเป็นเรื่องที่ลึกไปอีกขั้น แต่ยังเป็นสำหรับมือใหม่อยู่ !!
ประกอบไปด้วย

  • การใช้งาน channel
  • การใช้งาน struct
  • การใช้งาน net/http package
  • การใช้งาน encoding/json package

มาเริ่มกันเลย

เรื่องที่ 31 การส่งข้อมูลไปยัง channel ที่ปิดไปแล้ว ทำให้เกิด panic

ตัวอย่าง code ที่ทำการส่งข้อมูลไปยัง channel ที่ปิดไปแล้ว จะเกิด panic ขึ้นมา
ทำให้ program หยุดการทำงานทันที (ถ้าจัดการ panic ไม่ดี)

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="31.go"]

การแก้ไขปัญหานี้มีหลายวิธีการ ขึ้นอยู่กับระบบหรือความต้องการไป
เพื่อทำให้มั่นใจว่า จะไม่ส่งข้อมูลไปยัง channel ที่ปิดแล้ว
ยกตัวอย่างเช่น
ทำการสร้าง channel ใหม่ขึ้นมา เพื่อใช้สำหรับการยกเลิกการทำงาน
หรือ บอกว่าทำการปิด channel แล้ว
จากนั้นจะทำการส่งสัญญาณไปบอกให้ worker ต่าง ๆ รู้นั่นเอง
จากตัวอย่าง code ข้างล่าง จะสร้าง channel ชื่อว่า done ขึ้นมา

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="312.go"]

เรื่องที่ 32 การใช้งาน channel ที่เป็น nil ก่อให้เกิด deadlock ขึ้นมา

ในการใช้งาน channel นั้น ถ้านักพัฒนาเพียงประกาศ channel ที่เป็น nil ขึ้นมาแล้ว
จะก่อให้เกิดปัญหาขึ้นมา นั่นคือ channel จะโดน block ไว้
ดังนั้นงานอื่น ๆ จะไม่สามารถทำงานได้ 
มันคือ deadlock ดี ๆ นี่เอง ซึ่งต้องระวังให้มาก ๆ

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="32.go"]

เรื่องที่ 33 Methods with Value Receivers Can't Change the Original Value

Method receiver นั้นจะเหมือนกับ argument ของ function นั่นคือ
ถ้าทำการประกาศแบบปกติ จะเป็นการ pass by value (เป็นค่าของข้อมูล ไม่ใช่ตำแหน่ง) ทำให้เมื่อทำการแก้ไขข้อมูลแล้ว จะไม่กระทบกับข้อมูลต้นทางหรือ original
ดัง code ตัวอย่าง

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="33.go"]

ดังนั้นถ้าต้องการให้การแก้ไขข้อมูลใน method มีผลต่อต้นทางด้วย
การส่งค่าหรือ value เป็นตำแหน่งแทนด้วย pointer ดังนี้

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="332.go"]

เรื่องที่ 34 Closing HTTP Connections

ว่าด้วยเรื่องของการปิด HTTP connection 
โดยปกติเมื่อทำการ start HTTP server แล้ว
Connection หรือช่องทางการติดต่อจะถูกสร้างและเปิดขึ้นมา
จะเปิดค้างไว้ หรือ ปิดไปเมื่อใช้งานเสร็จ ก็ขึ้นอยู่กับงานของเรา
จากเอกสารของ HTTP 1.1 นั้นสามารถกำหนดค่าผ่าน keep-alive ใน HTTP Header

จาก package net/http ในภาษา Go นั้น
จะทำการปิด connection เมื่อ HTTP server บอกให้ปิดเท่านั้น (จะปิดตอนไหนละ ?)
ซึ่งอาจจะส่งผลทำให้เกิดปัญหาคือ 
เปิด socket/file descriptor มากเกินที่มีให้

ดังนั้นการแก้ไขมีหลายแบบ ขึ้นอยู่กับความต้องการของระบบงาน
ทั้งเพิ่มจำนวน socket ที่เปิดได้
ทั้งเพิ่มจำนวน file descriptor
ทั้งการปิด connection เมื่อใช้งานเสร็จแล้ว 
โดยการเพื่อค่า Connection = Close ใน HTTP Header  หรือกำหนด property Close ใน request เป็น true ดังนี้

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="34.go"]

หรือถ้าไม่ต้องการให้ใช้ HTTP connection ร่วมกัน
ก็สามารถปิดได้ ด้วยการ custom HTTP transportation กันไปเลย
กำหนดค่า DisableKeepAlives = true ไป ดังนี้

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="342.go"]

แต่ถ้ามีการส่ง request มายัง HTTP server เดียวกันจำนวนมากแล้ว
ควรต้องให้มีการใช้ HTTP connection ร่วมกัน หรือ เปิด connection ทิ้งไว้
เพราะว่าการสร้าง connection ถือว่าต้องใช้ resource เยอะ
แต่ถ้าจำนวน request ไม่เยอะ ก็ให้เปิดและปิดไป น่าจะเหมาะสมกว่า
ดังนั้น วิธีการมันขึ้นอยู่กับงานกันมากกว่า

เรื่องที่ 35 Closing HTTP Response Body

เมื่อผ่านเรื่องของ การปิด HTTP Connection มาแล้ว
ก็มาถึงการปิด HTTP Reponse ที่ได้รับกลับมา
จากการส่ง request ไปยัง server ปลายทางกันบ้าง

ปัญหาที่มักจะเกิดขึ้นสำหรับนักพัฒนา Go คือ
ถ้าไม่สามารถอ่านข้อมูลจาก body ใน response แล้ว
ต้องการที่จะปิดมันซะ ส่วนใหญ่จะทำการปิดใน defer ตามตำรา
ดังนี้ ซึ่งจะทำได้ดีถ้าได้รับ response แบบปกติหรือสำเร็จกลับมา
แต่ถ้าเกิดมีปัญหาขึ้นมา สิ่งที่ต้องเจอคือ panic นั่นเอง
เพราะว่า reponse จะมีค่าเป็น nil

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="35.go"]

การแก้ไขปัญหาก็ไม่ยากคือ ตรวจสอบก่อนทำการปิดว่า response มีค่าเป็น nil หรือไม่ ? ถ้าไม่ nil ก็ close ได้ ดังนี้

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="352.go"]

เรื่องที่ 36 JSON Encoder Adds a Newline Character

เมื่อทำการแปลงข้อมูลจาก object ต่าง ๆ มาอยู่ในรูปแบบ JSON 
ด้วย JSON Encoder จาก encoding/json package แล้ว
จะพบว่าสิ่งที่ได้เพิ่มขึ้นมาคือ newline chareacter (\n)
ทำให้ในการทดสอบอาจจะผิดพลาดขึ้นมาได้

เนื่องจาก JSON Encoder จาก encoding/json package นั้น
ออกแบบมาสำหรับ streaming  การเพิ่ม newline character ขึ้นมา
เพื่อใช้แยก JSON object แต่ละตัวออกจากกันนั่นเอง

เรื่องเล็ก ๆ แบบนี้นักพัฒนาอาจจะหลงลืมไป
ทั้ง ๆ ที่ในเอกสารหรือใน code ก็เขียนไว้อย่างชัดเจน
ไปดู code ของ JSON Encoder ดูนะ

[gist id="ea56fa327f9acbad9e479e49cf428c53" file="36.go"]

อย่าวัดผลการทำงานที่ชั่วโมงการทำงานใน office เพียงอย่างเดียว

$
0
0

ปกติคนทำงานมักจะเข้างาน 9 โมงเช้า เลิกงาน 6 โมงเย็น
รวม ๆ แล้วใน 1 วันจะทำงานประมาณ 8 ชั่วโมง
แต่ถ้าใครทำงานหลังจาก 6 โมงเย็นไปอีก ยิ่งดี (ไม่มี OT นะ)
บางองค์กรชอบคนเหล่านี้มาก ๆ
เพราะว่า มาทำงานก็ตรงเวลา กลับก็ช้า แสดงว่าขยันทำงานมาก ๆ !!!

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

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

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

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

สิ่งต่าง ๆ เหล่านี้มันจะเกิดขึ้นได้
ถ้าแต่ละคนเคารพซึ่งกันและกัน
มีการพูดคุยและสื่อสารที่ดี
นี่คือสิ่งที่องค์กรต้องการหรือไม่ ?

ปล. แต่งานบางอย่างก็ต้องการความตรงต่อเวลาเช่นกัน

ว่าด้วยเรื่องแนวคิด CQRS (Command Query Responsibility Segregation)

$
0
0

หลัง ๆ มาในโลกการพัฒนา Software มักได้ยินคำแปลก ๆ ออกมาเยอะมาก
(ตามจริงอาจจะไม่แปลก แต่เราไม่เคยรู้มากกว่า )
หนึ่งในนั้นคือแนวคิด CQRS (Command Query Responsibility Segregation)
โดยแนวคิดนี้มันจะพ่วงมาจากเรื่องของ DDD (Domain-Driven Design) และ Microservices
หนักกว่านั้นโยงไปถึง Event sourcing อะไรพวกนั้นอีก
ทำให้งงเข้าไปใหญ่
ดังนั้นเพื่อความไม่สับสนจึงลองไปศึกษาหน่อยว่า
จริง ๆ แล้วแนวคิดนี้มันมีที่มาที่ไปอย่างไร ?

เรื่องแรก ถ้าเราไปค้นหาใน Google น่าจะเจอ link เหล่านี้

เยอะไปไหน !!!

ต่อมาก็ลงไปหาที่มาของแนวคิดนี้จาก CQRS Info
ก็ได้ paper ของแนวคิดมาคือ

ก็ทำให้รู้และเข้าใจที่มาของแนวคิด CQRS ว่าเป็นดังนี้

จุดเริ่มต้นของแนวคิด CQRS ?

เริ่มจาก design pattern ซึ่งหน้าที่การทำงานของ class ต่าง ๆ มักจะประกอบไปด้วย

  • Query คือการดึงข้อมูล
  • Command คือการเปลี่ยนแปลงทั้งการเพิ่ม ลบและแก้ไข

จากหนังสือ Object-Oriented Software Construction เขียนไว้ว่า

Every method should either be a command that performs an action,
or a query that returns data to the caller,
but not both.

In other words,
Asking a question should not change the answer.

พูดง่าย ๆ มันคือเราควรแยกการทำงานทั้งคู่ออกจากกัน 
หรือเรียกว่า Command Query Separation
คิดโดย Bertrand Meyer ซึ่งอธิบายไว้ว่า

  • Query ทำการ return ข้อมูลกลับมา โดยไม่ทำการเปลี่ยนแปลงข้อมูลใด ๆ หรือไม่มี side-effect นั่นเอง หรือเรียกว่า pure function ก็ได้
  • Command ทำการเปลี่ยนแปลงข้อมูล แต่ไม่ return ข้อมูลกลับมา

ซึ่งการนำแนวคิดนี้ไปประยุกต์ใช้มันมีหลายระดับหรือขอบเขตมาก ๆ
ทั้งระดับ class/method, service, database และ system เป็นต้น
เป็นเรื่องของการแบ่งหน้าที่รับผิดชอบกัน (Single Responsibility Principle)

ถ้ามองในขอบเขตของ class ในโลกของ Object-Oriented แล้ว

เราสามารถทำได้ดังนี้
ยกตัวอย่างเช่น Customer Service มีความสามารถดังนี้

  • ดึงข้อมูล customer ทั้งหมด
  • ดูข้อมูลของ customer แต่ละคน
  • ทำการสร้าง customer ใหม่
  • ทำการแก้ไข customer ที่มีอยู่
  • ทำการลบ customer ออกจากระบบ

โดยถ้าใช้แนวคิด Command Query Separation มาใช้เพื่อแยกการทำงานสามารถแบ่งได้ดังนี้

กลุ่มที่ 1 Customer Read Service

  • ดึงข้อมูล customer ทั้งหมด
  • ดูข้อมูลของ customer แต่ละคน

กลุ่มที่ 2 Customer Write Service

  • ทำการสร้าง customer ใหม่
  • ทำการแก้ไข customer ที่มีอยู่
  • ทำการลบ customer ออกจากระบบ

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

เมื่อย้อนกลับมาดูแล้ว พบว่า เรามักใช้ data model ชุดเดียวกันเสมอ สำหรับทุก ๆ เรื่อง ทำไมนะ ?

มาถึงแนวคิด CQRS กันบ้าง

แน่นอนว่ามาจากแนวคิด Command Query Separation นั่นเอง
จาก VDO บอกว่า
ถ้าค้นหาคำว่า CQRS ใน google เมื่อ 10 ปีที่แล้ว
จะบอกว่าสะกดผิด และแนะนำว่าเป็นคำว่า Cars  !!

โดยที่แนวคิด CQRS นั้นไม่ใช่แนวคิดใหม่อะไร
แต่กลับได้รับความนิยมหรือพูดถึงมาก ๆ 
เมื่อมีการพูดถึง DDD, event sourcing มากขึ้น
นั่นคือมีการจัดเก็บ event ไว้ใน event store
รวมทั้ง event ต่าง ๆ เป็น immutable หรือไม่สามารถแก้ไขได้
และผลลัพธ์จะถูกสร้างมาจากการรวม event เข้าด้วยกันตามลำดับเวลาที่ event เกิดขึ้น
ฟังมาถึงตรงนี้มันคุ้น ๆ เหมือน Git เลยนะ

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

เนื่องจากแนวคิดนี้มีข้อดีแต่ก็มีข้อเสียเช่นกัน
ยกตัวอย่างเช่น เพิ่มความซับซ้อนของระบบงานให้มากยิ่งขึ้น
ดังนั้นการจะเลือกใช้อะไรสักอย่างก็ต้องรู้ทั้งข้อดีและข้อเสีย
เพื่อจะได้เตรียมการรับมือไว้

อีกเรื่องคือ บ่อยครั้งเรามักจะสร้างระบบ Event sourcing ขึ้นมา
สำหรับการใช้งานทั้ง application นั่นคือระบบ Monolithic ของ event นั่นเอง
ซึ่งกลายเป็นภาระให้ลูกหลานต่อไปอีกแล้ว
ดังนั้นต้องระวังให้มาก

ที่สำคัญเรื่องของ Event sourcing และ CQRS นั้นยิ่งถูกพูดและใช้งานมาก ๆใน
ระบบ Cloud, Actor model และ Microservices

เมื่อพูดถึงเรื่องของ Event แล้ว ก็พ่วงไปถึงเรื่องของ Event Storming

เป็น workshop หนึ่งที่ช่วยให้เราเข้าใจ domain ของระบงานมากขึ้น
ว่ามี event และ command อะไรเกิดขึ้นบ้าง
และแต่ละ event ก่อนให้เกิดอะไรขึ้นมา ต้องการอะไรหรือกระทบอะไรบ้าง

ถ้าไม่รู้ ก็แค่ทำให้รู้ จะถูกหรือไม่ก็ลองลงมือทำในกรอบสั้น ๆ แล้วสรุปและปรับปรุงต่อไป
ขอให้สนุกกับการ coding ครับ


ลองใช้งาน Git History กัน

$
0
0

เห็นใน timeline มีการ share การใช้งาน Git History
แสดง git commit ของแต่ละ file แบบสวย ๆ แจ่ม ๆ
ก็เลยลองไปใช้ดูหน่อย ว่าเป็นอย่างไรบ้าง ?

เริ่มต้นไปดูที่ web ก่อนคือ Git History
หรือสามารถเข้าไปดู source code ได้ที่ GitHub:: Git History
การใช้งานก็ไม่ยาก  แน่นอนว่ามีหลายวิธี ดังนี้

วิธีที่ 1 ไม่ต้องทำอะไร เพียงเปลี่ยน url ของ github 

ยกตัวอย่างเช่น ต้องการดู History ของไฟล์ 
https://github.com/vuejs/vuepress/blob/master/scripts/bootstrap.js
ให้ทำการเปลี่ยนเป็น 
https://github.githistory.xyz/vuejs/vuepress/blob/master/scripts/bootstrap.js
ก็จะเห็น History แบบนี้แล้ว

วิธีที่ 2 สำหรับคนขี้เกียจ ก็ให้ลง extension/plugin ใน Browser เลย

มีให้ทั้ง Google Chrome และ Firefox
ซึ่ง extension ไม่ได้ทำอะไรมาก เพียงเพิ่มปุ่มชื่อว่า Open in Git History เข้ามา เมื่อกดปุ่มแล้วจะไปยัง url ตามวิธีที่ 1 นั่นเอง

วิธีที่ 3 ใช้งานผ่าน command line

ทำการติดตั้งด้วยคำสั่ง

$npm install -g git-file-history $git-file-history path/to/file.extention Running at http://localhost:3000

จะทำการ start server ขึ้นมาด้วย port 3000
และทำการแสดงผลการทำงานลักษณะเดิมดังนี้

ลองใช้งานกันดูนะครับ
ขอให้สนุกกับการ coding ครับ

ลองไปนั่งดู React Hooks นิดหน่อย เราต้องเปลี่ยนเลยไหม ?

$
0
0

จาก tweet ของ Dan Abramov ผู้สร้าง React นั่นเอง
เกี่ยวกับแนวคิดการออกแบบ component เป็น Presentational และ Container component 
หรือเรื่องของ Stateful และ Stateless component
ได้บอกว่า แนวคิดนี้น่าจะไม่เหมาะสมแล้วกับ React ใหม่ที่มี React Hooks ออกมา
นั่นหมายความว่าเราสามารถแยก logic การทำงานออกไปยัง React Hooks เลย

เลยเกิดคำถามว่า ต้องใช้ Hook กันเลยไหม ?
หรือต้อง migrate มา Hook เลยไหม ?

ก็เลยไปลองอ่าน Blog ของ React พบบทความ React 16.8 : The one with Hooks

แน่นอนว่าอธิบายได้ชัดเจนมาก ๆ ทั้ง React Hooks คืออะไร

  • Hooks สามารถใช้งาน state และ feature ต่าง ๆ ของ React ได้โดยไม่ต้องสร้าง class ขึ้นมา
  • สามารถสร้าง Hooks ขึ้นมาเองเพื่อ share/reuse stateful logic ระหว่าง component
  • ดังนั้นไม่ต้องมาแยก Stateful และ Stateless component อีกแล้ว 

ในเอกสารบอกว่า ยังไม่ต้องเรียนรู้ Hooks ตอนนี้ก็ได้
เพราะว่ายังไม่มีแผนเอา class ต่าง ๆ
ออกจาก React ดังนั้นสบายใจกันได้

แถมยังไม่แนะนำให้ Rewrite ระบบงานเดิมด้วย Hooks อีกด้วย
แต่แนะนำให้ใช้กับ component ใหม่ ๆ ดีกว่า

คำถามที่น่าสนใจคือ จะเริ่มใช้ Hooks ตั้งแต่ตอนนี้เลยไหม ?

ตอบเลยว่าใช่ ได้เลย
แต่ใช้กับ React 16.8 ขึ้นไปเท่านั้น
แน่นอนว่า Hooks เข้าสู่ stable version แล้ว
สามารถใช้งาน Hooks กับสิ่งต่าง ๆ เหล่านี้ได้เลย

  • React DOM
  • React DOM Server
  • React Test Renderer
  • React Shallow Renderer

ปล. ตอนนี้ Hooks ยังไม่ครอบคลุมครบทุกกรณี แต่ก็ใกล้แล้วต้องรอกันหน่อย
หรือดูเพิ่มเติมได้ใน Hooks FAQ

มาเริ่มเรียนรู้ Hook ใน React 16.8 กัน 

[code] $yarn add react@^16.8.0 react-dom@^16.8.0 [/code]

ขอให้สนุกกับการ coding กันครับ

ทำการแจ้งเตือนไปยังผู้ใช้งานในระบบอย่างไรดี ?

$
0
0

พอดีต้องแจ้งเตือนนักศึกษาที่สอนว่า
พรุ่งนี้เป็นวันหยุด เขาหยุดเรียนกัน (ตามจริงก็เตรียมไปสอน)
ก็เลยเกิดคำถามว่า
จะส่งการแจ้งเตือนนี้ไปยังนักศึกษาอย่างไรดี ?
ทั้งแบบ manual และแบบสร้างเป็นระบบงานขึ้นมา !!

ปกตินักศึกษาจะมี Github รวมและแยกเป็นกลุ่มอยู่แล้ว

ดังนั้นการแจ้งเตือนก็ง่าย ๆ คือ manual ไงล่ะ
ไปเปิด issue ที่ repository กลาง หรือในแต่ละกลุ่ม
ก็จะได้รับการแจ้งเตือนแบบง่าย ๆ แล้ว
แต่ว่าต้องเข้าไปสร้าง issue เองนะ
ซึ่งคิดว่าเป็นวิธีการที่ไม่ค่อยโดนใจ หรือ มีประสิทธิภาพเท่าไร !!
ดังนั้นเขียน code เพื่อสร้างระบบการสร้าง issue ใน Github กันดีกว่า

จะเขียน code ก็ดูยากไปหน่อย !!

เมื่อกี้ยังบอกว่าจะเขียน code เลยไปลองดู มี cli ง่าย ๆ ให้ใช้งานคือ ghi 
การใช้งานก็ไม่ยาก แค่เพียง download มาติดตั้งและ authentication ซะ
จากนั้นก็สร้าง issue เลย ง่ายสุด ๆ

[code] $ghi config —auth $ghi open -m แจ้งหยุดเรียน -- / [/code]

แต่ว่ามีหลายกลุ่ม เราจะส่งแบบไหนดี ?

  1. ส่งแบบเรียงลำดับ (Sequencial)
  2. ส่งแบบเป็นลำดับแต่ทำงานไม่ต้องเป็นลำดับก่อนหลัง
  3. ส่งแบบพร้อม ๆ กัน ไม่สนใจผล
  4. ส่งแบบพร้อม ๆ กัน แต่ต้องหยุดทำงานเมื่อส่งครบ
  5. ส่งแบบพร้อม ๆ กัน พร้อมขอดูสถานะการส่งด้วย จะได้รู้ว่า การส่งไหนไม่สำเร็จหรือสำเร็จ

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


ว่าด้วยเรื่องของ Technical Excellence

$
0
0

วันนี้มีโอกาสมาแบ่งปันเรื่องของ Technical Excellence
ซึ่งเป็นเรื่องหนึ่งที่สำคัญมาก ๆ ของการพัฒนา software
จึงทำการสรุปไว้อีกนิดหน่อย ว่ามีอะไร เป็นอย่างไรบ้าง ?

เริ่มต้นจากเรื่องสำคัญของ Technical Excellence

ผมชอบคำพูดจาก Jim Highsmith ที่ว่า

In Agile project, 

Technical Excellence is measured by 
both capacity to deliver customer value today
and create an adaptable product for tomorrow.

คำถาม คือ เราใส่ใจเรื่องนี้ในระบบงานเราหรือไม่ ?
ทั้งในแง่ของคน ทีม รวมไปถึงวินัยและ skill
ทั้งในแง่ของ Architecture
ทั้งในแง่ของ code

จาก Agile Principle ข้อที่ 9 คือ

Continuous attention to Technical Excellence 
and good design enhance agility.

คำถาม คือ เราใส่ใจหรือไม่ ?
ถ้าตอบว่า ใส่ใจแต่ไม่ทำ นั่นคือ ไม่ใส่ใจ !!

จาก Less.Works พูดถึง Technical Excellence ว่า

Organizational Agility is constrained by Technical Agility

ดังนั้นคำว่า Agility หรือ True Flexibility จะเกิดขึ้นได้
เมื่อเราสามารถเปลี่ยนแปลง product หรือระบบงานได้ง่าย เร็ว และยึดหยุ่น

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

หนึ่งในวิธีการแก้ไขคือ
การนำแนวปฏิบัติที่ดีในการพัฒนา software มาใช้งาน
หรือเอาเข้ามาแก้ไขปัญหาที่เราพบเจออยู่
เพื่อเพิ่มเรื่องของคุณภาพ
รวมไปถึงการเปลี่ยนแปลงที่ง่ายและรวดเร็วขึ้น
ดังนั้นในทีมส่งมอบ software/product จำเป็นต้องเรียนรู้ ลงทุนด้านนี้อย่างสม่ำเสมอ

แต่ก่อนอื่นนั้น ไม่ว่าจะนำ framework หรือ process อะไรมาใช้ในการพัฒนา software

ควรต้องแนะนำ ทำความเข้าใจเกี่ยวกับแนวปฏิบัติต่าง ๆ ของการพัฒนา software ด้วย
โดยเฉพาะเหล่าแนวทางตาม Agile ยิ่งต้องรู้และเข้าใจ (What and Why)
ส่วนทำอย่างไร (How) มันคืออีกเรื่อง
มิเช่นนั้น ระบบงานที่ได้ก็จะเลอะเทอะอีกแล้วครับท่าน !!!

คำถามคือแล้ว Technical Excellence หรือพวกแนวปฏิบัติในการพัฒนา software ที่ดีมีอะไรบ้าง ?

จาก Less.Works นั้นได้สรุปไว้ได้ดี ซึ่งส่วนใหญ่จะมาจาก Extreme Programming 
ซึ่งผมแนะนำให้ลองไปศึกษาดูก่อนว่ามีอะไรบ้าง 
มันคืออะไร มีประโยชน์อย่างไรบ้าง แสดงดังรูป



https://less.works/less/technical-excellence/index.html

น่าจะเป็นอีกหนึ่งวิธีการทำให้ระบบงานที่เราดูแล Agility มากยิ่งขึ้น

รวมทั้งลดปัญหาหรือพวก Technical Debt เช่น

  • Ignorance เกิดจากไม่เข้าใจการทำงานทั้งหมดของระบบ
  • Complex requirement ทำให้เกิดการพัฒนาระบบที่ซับซ้อนเกินเหตุ แทนที่การสร้างระบบเพื่อลดความซับว้อนกลับเพิ่มซะอย่างงั้น
  • Over engineering ทำให้พัฒนาระบบหรือเขียน code มากจนเกินความจำเป็น มันเปลือง
  • Undone work มีงานที่ควรทำแต่ไม่ทำเพียบ เช่น เราว่าจะเขียน Automated test นะ แต่มันทำให้เราช้า ดังนั้นเอาไว้ก่อน
  • Good code but wrong place อันนี้ทำให้เกิด code ที่ไม่จำเป็น มันดีนะ แต่ผิดที่ผิดทาง
  • Quick and dirty ทำเร็ว ๆ ให้รีบเสร็จ แล้วเดี๋ยวค่อยกลับมาแก้ไข ส่วนใหญ่ก็ไม่กลับมาแก้ไข (Later is never)

สุดท้ายแล้วมันดีนะ แต่ ... มีการสนทนาหนึ่งที่น่าสนใจคือ

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

Business หรือ Product Owner จะได้ยินว่าอะไร ?
คำตอบคือ เราสามารถทำ feature นี้ได้ใน 2 วันหรอ !!

สิ่งที่ทำต่อจากนี้คืออะไร
เราทำให้มันผ่านไปวัน ๆ 
หรือจะทำให้มันดี เพื่ออนาคต

ลองหรือยังกับ Elasticsearch 7.0.0 beta 1

$
0
0

https://www.elastic.co/v7

ทาง Elastic ได้ปล่อย Elastic Stack 7.0.0 beta 1 ออกมาให้ลองทดสอบใช้กันดูแล้ว
ใน stack ก็ประกอบไปด้วยตัวหลัก ๆ คือ

  • Elasticsearch
  • Logstash/Beat
  • Kibana

มาดูกันว่าแต่ละตัวมีอะไรน่าสนใจบ้าง โดยเฉพาะกับ Elasticsearch

เริ่มจาก Elasticsearch 7

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

และการกำหนดจำนวนผลการค้นหาที่นำมาคำนวณค่า score
หรือความเหมือนสูงสุดไว้ที่ 10,000 document ซึ่งเป็นค่า default
แน่นอนว่าเปลี่ยนได้ ส่งผลให้การค้นหาเร็วขึ้น
แต่วิธีการนี้ไม่ได้ใช้กับการ aggregate นะ

มีเรื่องที่ผมใช้งานบ่อย ๆ คือ Function Score
สำหรับการจัดการ score ranking ของเอกสารต่าง ๆ
ซึ่งตอนนี้เป็น Function Score 2.0 แล้วหรือ Script Score Query

กับอีกอย่างที่รอมานานคือ 
ตอนนี้สามารถวิเคราะห์ข้อมูลในหน่วยเวลา nanosecond แล้ว
เพราะว่าที่ผ่านมามีหน่วยเล็กที่สุดคือ milisecond นั่นเอง
ทำให้เห็นว่า มี use case ที่ต้องการวิเคราะห์ข้อมูล
ในหน่วยเวลาที่เร็วและละเอียดขึ้นอย่างมาก
การสร้างข้อมูลมันเร็วจริง ๆ

เรื่องอื่น ๆ ที่น่าสนใจ เช่น

  • สนับสนุน JDK 11
  • ปรับปรุงการจัดการข้อมูลในและระหว่าง Cluster เช่น soft-delete index และการ discovery host เป็นต้น 
  • ใครใช้ Elasticsearch 5.0 ไม่สามารถ reindex มา 7 ได้ตรง ๆ ต้อง reindex เป็น 6 ก่อนนะ
  • เรื่อง breaking change นี่ต้องอ่านให้ดี ๆ

ส่วนอีกสองตัวคือ Kibana และ Logstash ก็มีเปลี่ยนแปลงเช่นกัน

Kibana ก็ทำการเปลี่ยน UI และ Navigation ต่าง ๆ
รวมทั้งมี Dark Theme ให้แล้วด้วย
รวมทั้ง feature อื่น ๆ ที่ใน community ขอเพิ่ม
ทั้ง auto-suggestion และ Map ที่ดีขึ้น

ส่วนพวก Beat และ Logstash ก็เพิ่มการ integrate ไปยังระบบอื่น ๆ ได้มากขึ้น
ทั้ง CouchDB, NATS และ MariaDB เป็นต้น

อีกอย่างหนึ่งที่น่าสนใจคือ Elastic Common Schema (ECS) 
สำหรับการกำหนด schema ของข้อมูลที่จะนำเข้า Elasticsearch
ควบคุม schema ของข้อมูลจากระบบต่างให้ได้มาตรฐาน
ทำให้สามารถนำข้อมูลไปวิเคราะห์ได้ง่ายขึ้น

ลองไปใช้งานกันดูครับ
ว่าระบบปัจจุบันของเราต้องเปลี่ยนและแก้ไขอะไรบ้าง


สรุปเนื้อหาที่น่าสนใจจากหนังสือ Building Microservices

$
0
0

หลังจากที่อ่านหนังสือ Building Microservices ไปหลายรอบ
เลยทำการสรุปภาพรวมของหนังสือไว้นิดหน่อย
มีทั้งเรื่องความรู้พื้นฐาน ข้อดี ข้อเสีย สิ่งที่ต้องจัดการ รับมือ
รวมไปถึง use case และประสบการณ์ต่าง ๆ ที่น่าสนใจ
มาเริ่มกันเลย

Microservices คืออะไร ?

ในหนังสือให้คำจำกัดความไว้ว่า
มีขนาดเล็ก Autonomous service นั่นคือ
ทำงานจบภายใน service เดียว
ที่สำคัญมักจะทำงานร่วมกันอีกด้วย

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

เมื่อมีขนาดเล็กแล้ว ทำให้เรา focus กับมันได้ง่ายขึ้น
ทั้งจำนวน code ที่น้อยลง
การจัดการต่อการเปลี่ยนแปลงต่าง ๆ ง่ายขึ้น
แต่คำว่าเล็กนั้น มีคำถามว่า เล็กอย่างไร ?
เท่าไรถึงบอกว่าเล็ก ?
เล็กแล้วมีประโยชน์หรือโทษอะไรบ้าง ?

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

คำว่า Autonomous นั้นรวมทั้งทีมและ service
นั่นคือระบบงานทำงานจบในตัวเอง เป็นสิ่งที่ดีที่สุด
เพื่อลดการผูกมัดกับ service อื่น ๆ (Loose coupling)
ส่งผลให้ง่ายต่อการพัฒนา deploy และ scaling ต่อไป

ประโยชน์หลัก ๆ ของ Microservices ประกอบไปด้วย

  • เลือกเครื่องมือให้เหมาะกับงาน ทั้งภาษาโปรแกรมและที่จัดเก็บข้อมูล เป็นต้น
  • ทำให้ระบบมีความน่าเชื่อถือมากขึ้น เพราะว่าถ้าเกิดปัญหาจะใช้ไม่ได้เพียงบางส่วน ไม่ใช่ล่มทั้งระบบเช่นเดิม
  • สามารถ scale ระบบได้ง่าย และ scale เฉพาะในส่วนงานที่ต้องการได้ ไม่จำเป็นต้อง scale ทั้งระบบ
  • ทำให้การพัฒนาและส่งมอบงานได้รวดเร็วขึ้น
  • ทำให้องค์กรต้องมีการปรับเปลี่ยนโครงสร้าง จากเดิมมีทีมขนาดใหญ่ ก็ให้แบ่งเป็นทีมเล็ก ๆ ตามแต่ละ service
  • ทำให้เกิดการ reuse ที่ง่ายตามมา
  • สามารถเปลี่ยนแปลงการทำงานของแต่ละส่วนได้ง่าย เช่นการเปลี่ยนเทคโนโลยีเป็นต้น

มุมมองและเป้าหมายของ Architect และ Engineer ที่เปลี่ยนไป

จากเดิมจะให้ความสำคัญไปที่
การทำงานร่วมกันของ service หรือ boudary ต่าง ๆ
โดยไม่สนใจการทำงานภายในของแต่ละ service มักจะมีแผนภาพที่สวยงาม
ตามด้วยเอกสารจำนวนมาก ซึ่งดู ๆ แล้วเป็นแผนการที่ดี perfect และแจ่มแมว
แล้วให้ทีมพัฒนาไปทำตาม โดยไม่ได้ใส่ใจว่าจะทำได้หรือไม่

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

ดังนั้นในการพัฒนา software น่าจะย้อนกลับมาดูว่า
สิ่งที่เราทำกันอยู่ไม่น่าจะถูกต้อง
เพราะว่าปัจจุบันการเปลี่ยนแปลงมันรวดเร็วมาก ๆ
ทั้ง แนวคิด เทคนิคและเครื่องมือ
แนวคิดของการออกแบบระบบ จำเป็นต้องเปลี่ยนเช่นกัน
จากการสร้างสิ่งที่ดีสุด ๆ หรือ perfect system/architecture
ไปเป็นการออกแบบและสร้างสิ่งที่ช่วยเหลือให้สร้างระบบได้ง่าย ตรงตามความต้องการ
ที่สำคัญพร้อมที่จะเปลี่ยนแปลง ตามความต้องการและเทคโนโลยีที่เปลี่ยนไป

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

มีกรอบช่วยตัดสินใจ ประกอบไปด้วย Strategic goal, Principle และ Practice

  • Strategic goal คือเป้าหมายที่องค์กรจะไป และผลที่อยากเห็นเช่นทำให้ลูกค้ามีความสุข ซึ่งต้องมีเทคนิคและเทคโนโลยีสนับสนุนด้วย
  • Principle คือกฎระเบียบต่าง ๆ ที่จะทำให้เราไปถึงเป้าหมายที่ตั้งไว้ เช่นเป้าหมายเพื่อทำให้ส่งมอบ feature ใหม่ ๆให้เร็วขึ้น ดังนั้น priciple ที่ดีควรให้ delivery team ดูแลจัดการการส่งมอบแบบเบ็ดเสร็จ ทำให้ไม่ต้องไปเสียเวลากับการทำงานกับส่วนอื่น ๆ 
  • Practice คือวิธีการลงมือทำตามแนวคิดของ priciple เพื่อให้ถึงเป้าหมายที่ตั้งไว้ ยกตัวอย่าง coding guideline, รูปแบบการจัดเก็บ log ต่าง ๆ และ HTTP/REST สำหรับการ integrate ของระบบต่าง ๆ

เรื่องที่สำคัญมาก ๆ คือ การออกแบบ service

เริ่มด้วย service ที่ดีประกอไปด้วย

  • Loose coupling เมื่อแก้ไขที่ service หนึ่งแล้ว ต้องไม่ไปแก้ไขใน service อื่น ๆ
  • High cohesion ต้องให้การทำงานที่ทำงานร่วมกันเกี่ยวข้อกันให้อยู่ด้วยกัน ไม่จำเป็นต้องแยกออกจากกัน เพื่อหลีกเลี่ยงผลกระทบจากการแก้ไขรวมไปถึงเรื่องของการ deploy และ scaling

ปล.  เมื่อไปอ่านความหมายของคำว่า service แล้ว

คือ Standalone, loose-coupling และมีการทำงานที่มีประโยชน์ต่อผู้ใช้งาน


เรื่องหนึ่งที่พูดถึงกันอย่างมากคือ Boudary Context
ที่หยิบยืมมาจาก Domain-Driven Design (DDD)
เนื่องจากใน business domain หนึ่ง ๆ นั้น
มักจะประกอบไปด้วย กลุ่มงานที่แตกต่างกันจำนวนมาก
ดังนั้นจำเป็นต้องแบ่งกลุ่มการทำงานให้ชัดเจน
ด้วยสิ่งที่เรียกว่า Boudary Context

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

แสดงตัวอย่างดังรูป

ในการแยก service นั้น
ให้เริ่มจากหน้าที่รับผิดชอบของแต่ละ context ก่อน
เพื่อให้แยกตามหน้าที่การทำงานทาง busienss
จากนั้นจึงมาคิดถึงเรื่องของ data ว่าจะแยกหรือ share กันต่อไป

ในหนังสือยังมีคำเตือนด้วยว่า
การแยกระบบงานออกจากกันเป็น service ย่อย ๆ หรือ Microservices นั้น 
จะมีค่าใช้จ่ายตามมาเสมอ ดังนั้นแนะนำให้เริ่มจาก service เดียวดี ๆ
แบ่งกลุ่มให้ชัดเจน เมื่อถึงเวลาที่เหมาะสม ค่อยทำการแยกออกมา

ต่อมาว่าด้วยเรื่องของการ Integration กับส่วนงานต่าง ๆ

ในหนังสือจะเน้นไปเรื่องของการทำงานกับ database/data store
ซึ่งมักจะเป็นการ shared database ในหลาย ๆ service
ส่งผลให้เกิดผลดังนี้

  • เมื่อทำการแก้ไข schema แล้วจะกระทบกับ service อื่น ๆ ที่ใช้งาน
  • ทุก ๆ service ที่ใช้งาน shared database เดียวกัน ทำให้เกิดการผูกมัดอย่างมาก เปลี่ยนได้ยาก

ทำให้เราต้องคิดมากขึ้นว่า จะแก้ไขปัญหานี้อย่างไร
ซึ่งแนะนำให้ทำการแยก database ออกไปตามส่วนการทำงานก่อน
จากนั้นทำการแยก service ออกมา

เมื่อแยกเป็น service ย่อย ๆ ออกมา ปัญหาการ integration จึงเกิดขึ้นมา
คำถามคือในแต่ละ service จะติดต่อสื่อสารกันอย่างไร
คำถามคือในแต่ละ service จะทำงานร่วมกันอย่างไร
การติดต่อสื่อสารอาจจะมีการทำงานแบบ synchonous หรือ asynchonous ขึ้นอยู่กับงาน

ยังไม่พอ ถ้าการทำงานมีความซับซ้อนขึ้น
นั่นคือต้องเรียกใช้งาน service จำนวนมาก
คำถามที่ตามมาคือ จะจัดการอย่างไร
ในหนังสือจะมี 2 แบบที่แนะนำคือ

  • Orchestration pattern
  • Choreography pattern

แบบแรกคือ Orchestration pattern

นั่นคือมีตัวกลางในการจัดการการทำงานทั้งหมด แสดงดังรูป

แบบที่สองคือ Choreography pattern

ตรงข้ามกับแบบแรกคือ
ไม่มีตัวควบคุม แต่ว่าเป็นการส่งต่อการทำงานไปเรื่อย ๆ
ซึ่งมักจะทำงานร่วมกับ Event-based architecture
นั่นคือเมื่อทำงานในขั้นตอนที่ 1 เสร็จแล้ว
จะทำการสร้าง event ขึ้นมา
ถ้า service ไหนที่สนใจ event นี้ก็จะทำการ subscribe ไว้
เพื่อนำ event ที่เกิดขึ้นไปทำงานต่อไป
ทำให้แต่ละ service ไม่ผูกมัดกัน แต่ความซับซ้อนจะสูงขึ้น แสดงดังรูป

อีกเรื่องที่น่าสนใจคือ การ integrate กับ User Interface

เนื่องจาก user interface นั่นคือ
ฝั่งที่ทำการรวบรวมหรือเรียกใช้งานหลาย service
ทำให้การทำงานจริง ๆ อาจจะเกิดปัญหาเรื่องการติดต่อสื่อสารไปยัง service ต่าง ๆ
ดังนั้นจึงแนะนำให้สร้าง composition service ขึ้นมา
เพื่อทำงานตามความต้องการของ user interface ไปเลย

ยกตัวอย่างเช่น user interface มีทั้ง Mobile, Web และ Admin
ก็ให้มี composition service ของแต่ละ user interface 
เรามักจะเรียก service เหล่านี้ว่า Backend for Frontend (BFF) แสดงดังรูป

รวมไปถึงการจัดการ version ของ service ก็สำคัญมาก ๆ
เพื่อสร้างความน่าเชื่อถือให้กับ service

เรื่องที่ผมชอบมาก ๆ คือ Split the monolith

หรือการแยก service จากระบบเดิม แน่นอนว่า ต้องมีเหตุผลในการแยกดังนี้

  • เหตุผลในการเปลี่ยนแปลง เมื่อแยก service ออกมาแล้วการเปลี่ยนแปลงต้องเป็นเฉพาะ service นั้น ๆ เท่านั้น ไม่ไปทำให้ service อื่นเปลี่ยนด้วย ถ้าแยกออกมาแล้ว ยังต้องเปลี่ยนเพราะว่า service อื่นเปลี่ยน แบบนี้เราจะแยกออกมาทำไมกัน
  • โครงสร้างของทีม การแยกทีมออกมาดูแต่ละ service ก็ทำให้จำนวน code น้อยลง การดูแลง่ายขึ้น ยิ่งถ้าทำงานต่างที่กัน น่าจะทำให้ตอบรับโจทย์หรือปัญหามากขึ้น
  • เทคโนโลยีที่เลือกใช้งานที่เหมาะสมกับงาน บางครั้งการแยก service ออกมา เพราะว่าเทคโนโลยีที่เหมาะสมกับงานทั้ง algorithm, เครื่องมือ, ภาษาโปรแกรม, database ทำให้ง่ายต่อการสร้างและ deploy

เมื่อทำการแยกออกมาเป็น service ย่อย ๆ แล้ว

Database ที่ใช้งานมักจะไม่ shared กัน
หรือเก็บข้อมูลแยกในแต่ละ service
ทำให้เกิดปัญหาที่ตามมา
ทั้งเรื่องการจัดการความถูกต้องของข้อมูล 
ซึ่งแต่ก่อนจะมีการจัดการด้วย transaction 
แต่พอมาเป็นหลาย ๆ service ไม่มี ทำให้ต้องรับมือกับปัญหานี้
ยังไม่พอนะ
ถ้ามีการใช้งานข้อมูลจากหลาย ๆ service จะจัดการอย่างไร
ยกตัวอย่างเช่นระบบ reporting

มาถึงเรื่องของการ deploy service ต่าง ๆ

เป็นอีกเรื่องที่น่าสนใจ ว่าจะใช้แนวทางใดบ้าง
ทั้งแบบเครื่องจริง ๆ VM หรือ container
เพื่อให้ตอบโจทย์ที่ต้องการ
ซึ่งตรงนี้ต้องมาวางแผนและศึกษากัน
เพื่อการส่งมอบงานที่รวดเร็ว และ น่าเชื่อถือ
แน่นอนว่า เรื่องของการทำงานแบบอัตโนมัติ เป็นเรื่องที่สำคัญขึ้นมาทันที

รูปแบบการ deploy service ต่าง ๆ ก็เช่นกัน
มีทั้ง Blue/green deployment และ Canary release เป็นต้น
ยิ่งกว่านั้น
ถ้ามีปัญหาเกิดขึ้นหลังจากการ deploy จะทำอย่างไร
ใช้เวลาในการแก้ไขนานหรือไม่ ?
ถ้าช้ากว่าเดิม หรือ ยากกว่าเดิม น่าจะเดินผิดทางอย่างแน่นอน

การทดสอบเป็นสิ่งที่ขาดไม่ได้เลย

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

  • Unit test
  • Integration test
  • Component test
  • Consumer Contract test
  • End-to-End test

เรื่องของ integration test ใน level ต่าง ๆ เป็นความท้าทายสุด ๆ
ในโลกของ microservices
คำถามที่น่าสนใจมาก ๆ คือ
เมื่อมี service จำนวนมาก ๆ แล้ว การทดสอบจะทำกันอย่างไร
ได้วางแผนเพื่อรับมือกันหรือไม่ ?

เรื่องสุดท้ายคือ Monitoring หรือ Observability

ก่อนที่จะเริ่มแยก service นั้น
เราควรมีระบบ Monitoring ที่ดี
ทั้งเรื่องของ centralize logging, dashboard, alert, metric
และ tracing ของระบบ
มันคือ infrastructure พื้นฐานของระบบที่ต้องมีก่อน
มิเช่นนั้น ปัญหาที่ตามมาจะหายากและแก้ไขยากแน่นอน แสดงปัญหาดังรูป

เรื่องของการ monitoring ระบบนั้นมีหลายรูปแบบ
แต่ก่อนอื่นเราต้องตอบคำถามเหล่านี้ให้ได้

  • มีอะไรบ้างที่ต้องการรู้ทันทีเมื่อเกิดขึ้น
  • มีอะไรบ้างที่ต้องการรู้ในภายหลัง
  • มีข้อมูลอะไรบ้างที่เราต้องใช้งาน

เป็นหนังสืออีกเล่มที่น่าสนใจครับ

UI ของ Spring Initializr เปลี่ยนแล้วนะ !!

$
0
0

https://start.spring.io/

ค่ำนี้เข้าไปที่หน้า web ของ Spring Initializr
ซึ่งเป็นหน้าสำหรับช่วยสร้าง Spring Boot Project
พบว่าเปลี่ยนไปอย่างน่าตกใจ เลยนำข่าวมาบอก
ที่สำคัญใช้ง่ายขึ้นกว่าเดิม

สิ่งที่เปลี่ยนแล้วชอบประกอบไปด้วย

  • UI ที่เปลี่ยนไป ดูไม่อึดอัดเหมือนเดิม
  • มีให้เลือกว่าจะ packaging เป็นอะไรคือ JAR หรือ WAR file
  • มีให้เลือก version ของ JDK คือ 8 หรือ 11
  • เมื่อเลือก dependency แล้วแสดงรายละเอียดสั้น ๆ ด้วย แต่ link ของรายชื่อ dependency เยอะ ๆ หายไป !!

ลองใช้กันดูนะ

VDO งาน RoboCon 2019 ออกมาแล้ว

$
0
0

งาน RoboCon 2019 คืองาน conference สำหรับ Robot Framework community 
มี session ที่น่าสนใจเยอะใช้ได้ รวมทั้งกับ Lightning talk สั้น ๆ
โดยตอนนี้ทำการ upload VDO ต่าง ๆ ขึ้น Youtube แล้ว 
ลองไปเสพกันได้เลยครับ

ว่าง ๆ มานั่งแงะดู App พฤติมาตร นิดหน่อย

$
0
0

ช่วงวันว่าง ๆ ลองนั่งแงะ App พฤติมาตร กันดูเล่น ๆ
แน่นอนว่า ก็ไปนำ APK ของ App มาลอง decompile ดู
ว่าพัฒนากันอย่างไรบ้าง
เผื่อจะได้เป็นแนวทางในการพัฒนา App กันต่อไป
มาเริ่มกันเลย


ปล. มานั่งแงะดู App แบบนี้มันผิดหรือเปล่าครับ ?

ถ้าผิดก็บอกกันได้ แค่อยากลองดูว่า App เป็นยังไง
เพื่อใช้ในการพัฒนาต่อไป
ไม่มีจุดประสงค์ร้ายนะครับ

เริ่มที่การขอ permission ได้มากมายก่ายกอง

น่าจะขอหมดทุกอย่างนั่นแหละ เป็น App ที่ให้ download ผ่าน web ของ กสทช เลย
ไม่ผ่าน Play Store นะ 
การใช้งานต้องไปลงทะเบียนผ่านหน้า web ก่อน

[gist id="6f6cfed69df8b0757cf21170a0f51e2d" file="AndroidManifest.xml"]

ต่อไปดูภาษาและ Library ที่นำมาใช้งานบ้าง

น่าจะพัฒนาด้วยภาษา Kotlin นะ  เห็นมี package ของ Kotlin ด้วย
ส่วน library ที่ใช้ประกอบไปด้วย

  • OkHttp3 สำหรับการเรียกพวก API ต่าง ๆ
  • Firebase สำหรับพวก analytic ต่าง ๆ ของ App
  • Joda Time สำหรับจัดการเรื่องของ datetime
  • AChartEngine สำหรับการแสดงกราฟต่าง ๆ
  • Glide สำหรับจัดการแสดงรูปภาพต่าง ๆ
  • Jackson สำหรับจัดการข้อมูล JSON น่าจะใช้ Gson แทนนะ
  • จัดการข้อมูลบน SQLite ด้วย Room

มีจำนวน Activity ไม่เกิน 30 activity 
มีพวก background service เพียบเลย !!

มาดู code การพัฒนาบ้าง

เมื่อลองทำการเปิด APK ใน APK Analyzer ก็เห็นประมาณนี้

ลองเอาไป decompile ก็ได้ code คร่าว ๆ มาดูบ้าง (ไม่รู้ code จริง ๆ เป็นอย่างไรนะ)

โดย code ที่ได้ออกมาจะเป็นภาษา Java นะ (ต้นฉบับน่าจะเป็นภาษา Kotlin มากกว่า)
มาดูภาพคร่าว ๆ ของสิ่งที่ decompile ออกมา

  • ชื่อ package เป็น Pascal case เช่น BackGroundUse, GroupPhone, Setting, OtherClass และ TabView
  • แต่ชื่อ package ก็ตั้งชื่อขัดแย้งกันเองเช่น Appdata และ Speedtest

มาดูการทำงานในส่วนต่าง ๆ ของ code บ้าง

เริ่มจากส่วนของพวก background service ซึ่งมีเยอะ
ลองเข้าไปดูใน package BackGroundUse เจอเพียบเลย
จะทำการเห็บข้อมูลการใช้ app ของเรา 
เนื่องจากได้ทำการของ permission ในการเข้าถึงแล้วจากข้างบน

เริ่มต้นจะมีข้อมูลของ social app ดังนี้

[gist id="6f6cfed69df8b0757cf21170a0f51e2d" file="1.txt"]

จากนั้นก็มีการ update การใช้งาน App บนมือถือของคนใช้งานไปเรื่อย ๆ

[gist id="6f6cfed69df8b0757cf21170a0f51e2d" file="2.txt"]

โดยข้อมูลการใช้งานจะมีการดูได้ 5 แบบ คือ Daily, Weelky, Monthly และ Yearly

[gist id="6f6cfed69df8b0757cf21170a0f51e2d" file="3.txt"]

จะทำการเก็บข้อมูลเยอะนะ ซึ่งเบื้องต้นจะเก็บไว้บนเครื่องคือใน SQLite ก่อน ดังนี้

  • ข้อมูลการโทร
  • Traffic network ที่ใช้งาน 
  • มีการทดสอบความเร็วของ Network ที่ใช้งานด้วย (Download และ Upload)
  • การส่ง SMS และ MMS
  • App ที่ใช้งานรวมไปถึงเวลาการใช้งาน
  • Location หรือตำแหน่งของผู้ใช้งาน

ลองไปดู code ในส่วนการเชื่อมต่อไปยัง RESTful API ฝั่งหลังบ้านจาก App

ใน class ApiRequest จะทำการ hardcode token ของการ access ไปยัง API
ไว้ใน code ไม่แน่ใจว่าทำไมต้อง hardcode ไว้ด้วย
ซึ่งลองเอาไปแปลงใน web JWT ก็เจอว่าส่งอะไรไปบ้าง

ทำให้ใครก็ตามที่อยากไปดึงข้อมูลจาก API เหล่านี้ทำได้ง่าย ๆ เลย
ทั้งการ GET และ POST ข้อมูล !!

ตัวอย่างเช่น API ที่ชื่อว่า /api/mobile_apps.json
ก็ได้ค่าข้อมูลเพียบเลย 
เท่าที่ดูคือข้อมูลการใช้ App ต่าง ๆ ของผู้ติดตั้ง App นี้นั่นเอง
จากที่ลองไปดึงมานั้นพบว่าทีจำนวน 69 app นะครับ
ยกตัวอย่างเช่น

กลุ่ม Social ประกอบไปด้วย

  • Facebook
  • Twitter
  • BeeTalk
  • Badoo
  • Pantip
  • Dek-D
  • Kapook!
  • Mthai

กลุ่ม ความบันเทิง

  • Shopee, Lazada (มายังไงหว่า มัน shopping นะ)
  • Tiktok
  • Youtube
  • 4shared
  • Viu
  • JOOK
  • Netflix
  • 7-Eleven
  • Line TV
  • Bugaboo TV
  • Mello Thailand

กลุ่มเกมส์

  • Garena
  • Voodoo Paper 2
  • Garena Free Fire
  • Color Bump 3D
  • Kungfu world
  • Candy Crush
  • Hay Day

กลุ่ม Utility

  • TrueMoney Wallet
  • Krungthai NEXT
  • K Plus
  • SCB Easy
  • Google Chrome
  • Accu Weather
  • Kerry Express
  • LINE
  • JobDB search

สุดท้ายลองไปเปิด code ส่วนอื่น ๆ ดู 

ก็เจอ Arrow Function นิดหน่อย Code จริง ๆ คงไม่เป็นแบบนี้หรอกนะ

หวังว่าจะมีประโยชน์บ้างนะครับ
สำหรับนักพัฒนา Android App

สรุปการย้ายจาก dep มายัง Go module กัน

$
0
0

บันทึกการย้ายตัวจัดการ library/dependency ของระบบงาน
ที่พัฒนาด้วยถาษา Go จาก dep มายัง Go module ไว้นิดหน่อย 
การย้ายนั้นไม่ยากเท่าไร
มีขั้นตอนดังนี้

  • go mod init จะทำการ import library ต่าง ๆ จากไฟล์ Gopkg.lock มาให้แบบอัตโนมัติ
  • go mod tidy   ทำการลบ library/dependency ต่าง ๆ ที่ไม่ได้ใช้งานออกไป
  • rm -rf vendor  ทำการลบ folder vendor ทิ้งไป เพราะว่าไม่ต้องใช้งานแล้ว
  • go build  ทำการ run build เพื่อทำให้มั่นใจว่าทุกอย่างยังปกติสุข
  • ลบไฟล์ config ของ dep ทิ้งไป เช่น .lock และ toml เป็นต้น

มาดูรายละเอียดกันนิดหน่อย เพราะว่า ทำจริง ๆ มันไม่ง่ายตามขั้นตอน

เริ่มด้วยการย้าย code จาก $GOPATH/src ไปที่ใหม่ก่อน
ยกตัวอย่างเช่นไปที่ /work เป็นต้น

ใน /work นั้นจะมี code ของ project เรา
รวมทั้ง directory /vendor ด้วย
รวมไปถึงไฟล์ Gopkg.lock และ Gopkg.toml
จากนั้นจึงทำการ run คำสั่ง

[code] $go mod init example go: creating new go.mod: module . go: copying requirements from Gopkg.lock [/code]

จะทำการสร้างไฟล์ go.mod ขึ้นมา
โดยจะทำการ import library/dependency ต่าง ๆ
มาจากไฟล์ Gopkg.lock ให้ด้วย

จากนั้นทำการลบสิ่งที่ไม่ได้ใช้ตามขั้นตอน
ทำการ build ด้วยคำสั่ง

[code] $go build example go: downloading github.com/gorilla/mux v1.7.0 go: extracting github.com/gorilla/mux v1.7.0 [/code]

เพียงเท่านี้ก็ย้ายได้แล้วนะ
ขอให้สนุกกกับการ coding ครับ


ไม่มากก็น้อยไป สำหรับการพัฒนา

$
0
0

นั่งอ่านหนังสือ Real World Software Development ไปนิดหน่อย
พบรูปแบบของ code ที่น่าสนใจ นั่นก็คือ ไม่มากก็น้อยไป
จึงทำการสรุปไว้

เริ่มด้วย God Interface

นั่นคือใน interface หนึ่ง ๆ มี method จำนวนมาก
คำถามที่น่าสนใจคือ interface นี้จำเป็นต้องมี method เยอะแบบนี้ไหม ?
บ่อยครั้งจะเป็นแนวทางที่ขัดแย้งกับแนวคิด Interface Segregation Principle (ISP) 

[gist id="1687dc7b7c3bd5486b05e9e13fac1915" file="1.java"]

ดังนั้นน่าจะต้องแยกออกเป็นกลุ่ม ๆ  ตามกลุ่มงานเดียวกัน
ยกตัวอย่างเช่นการอ่านและการแก้ไขข้อมูลเป็นต้น
แต่บ่อยครั้งจะพบว่า ก็แยกกันเกินไป
อาจจะทำให้เกิด Low Cohesion อีก
หาความพอดีได้ไหมเนี่ย
ยกตัวอย่างเช่น

[gist id="1687dc7b7c3bd5486b05e9e13fac1915" file="2.java"]

ต่อมาก็เรื่องของ God Class

เรื่อง class ที่ทำมันไปหมดทุกอย่าง
ขัดแย้งกับแนวคิด Single Responsibility Principle (SRP) อย่างมาก
ทำให้ code ที่เขียนออกมา มันขัดแย้งกับ code ที่ดีอย่างมาก
ผลที่ตามมาคือ เข้าใจยาก ดูแลรักษายาก

เรื่องของการโยน Exception ออกมาก็น่าสนใจ

ทำไมโยน exception ออกมาตัวเดียวแบบนี้
แบบนี้ก็มักง่ายไปหน่อย หรือ น้อยไปหน่อยไหม ?
จะทำการจัดการ exception แบบนี้ต่อไปอย่างไรดี ?

[gist id="1687dc7b7c3bd5486b05e9e13fac1915" file="3.java"]

หรือลองจัดการด้วยการ Notification pattern ก็ดูดีขึ้นนะ

[gist id="1687dc7b7c3bd5486b05e9e13fac1915" file="4.java"]

อีกเรื่องที่น่าสนใจคือ การเขียน Test หรือ Automation Test

แนะนำให้เขียน
เพื่อเพิ่มความเชื่อมั่นที่มีต่อระบบ
เพื่อลดปัญหาหรือหาปัญหาจากการเปลี่ยนแปลงต่าง ๆ
เพื่อให้เข้าใจระบบมากยิ่งขึ้น

พบว่าปัญหาที่เจอคือ ไม่เขียน Test หรือเขียนแล้วไม่ช่วย
แต่กลับทำร้ายให้แย่กว่าเดิม เพราะว่า เขียนเพียงให้มี แต่ไม่ได้ทำให้มันดี

ในหนังสือเล่มนี้มีอีกหลายเรื่องที่น่าสนใจ
ไว้เอามาสรุปไว้อีกรอบ ไปอ่านต่อก่อน

มาดู Switch Expressions (Preview) ใน JDK 12 กัน

$
0
0

เห็นว่า JDK 12 เพิ่งปล่อยออกมาตามสัญญาคือ ทุก ๆ 6 เดือน
เลยลองดูหน่อยว่า มี feature อะไรที่น่าสนใจสำหรับนักพัฒนากันบ้าง ?
พอไปดูก็ไม่รู้เรื่องสิครับ อะไรก็ไม่รู้

  • 189:    Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)
  • 230:    Microbenchmark Suite
  • 325:    Switch Expressions (Preview)
  • 334:    JVM Constants API
  • 340:    One AArch64 Port, Not Two
  • 341:    Default CDS Archives
  • 344:    Abortable Mixed Collections for G1
  • 346:    Promptly Return Unused Committed Memory from G1

แต่ตัวที่พอจะรู้เรื่องหน่อยคือ Switch Expressions (Preview)

ดังนั้นมาดูกันหน่อยว่ามันคืออะไร
พอเข้าไปดูก็พบว่า มันคือ Swich-case ตามชื่อนั่นเอง
แต่มันทำให้ชีวิตนักพัฒนาง่ายขึ้นมา
ด้วยการนำ Pattern Matching มาใช้งานใน Switch statement นั่นเอง 
แต่เป็น feature ที่อยู่ในการ preview นะ
นั่นหมายความว่าอาจจะเอาออก แก้ไขได้ต่อไปในอนาคต
มาดูตัวอย่าง code กันหน่อย

[gist id="10b0e665fb51585b6257e3b829b38ff4" file="DemoSwitch.java"]

คำอธิบาย
เห็นครั้งแรกก็ดูดีเลยนะ pattern matching กันมาเลย
นี่มัน scala นิ
Break ก็ไม่ต้องมี
-> คุ้น ๆ มาอีกแล้ว
ที่สำคัญ สั้น กระชับ อ่านง่ายขึ้นไหม

การ compile และ run ทำอย่างไร ?

เนื่องจากยังเป็น preview เท่านั้น
ในการ compile และ run จึงต้องใส่ option ดังนี้

[code] $javac --enable-preview --release 12 DemoSwitch.java $java --enable-preview  DemoSwitch [/code]

เพียงเท่านี้ก็ใช้ได้แล้วครับ
ว่าง ๆ ลองไป download มาเล่นและศึกษากันครับ

สวยดีนะ Vicious cycle of technical debt

$
0
0

https://www.devopsgroup.com/2015/07/31/devops-and-automating-the-repayment-of-technical-debt/

อ่านเจอบทความเรื่อง Vicious cycle of technical debt
หรือแปลเป็นภาษาไทยง่าย ๆ ว่า วงจรอุบาทว์ของหนี้เชิงเทคนิค
มันน่าสนใจดีนะ

วงจรที่มันจะวนไปเรื่อย ๆ โดยเริ่มจาก

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

ใครอยู่ในวังวนหรือวงจรอุบาทว์นี้บ้างนะ ?
เราจะออกไปจากวังวนนี้อย่างไรนะ ?

หนึ่งในแนวทางที่อ่านเจอมาคือ อะไรที่มันซ้ำ ๆ ก็ให้มันทำงานแบบอัตโนมัติซะ

ยกตัวอย่างเช่น
ชอบผิดซ้ำ ๆ ที่เดิมก็เขียนชุดการทดสอบซะ
ครั้งต่อไปไม่น่าจะผิดที่เดิม เพราะว่ามีชุดการทดสอบคอยช่วยแล้ว
ชอบ deploy ผิดบ่อย ๆ ก็ลองทำระบบ deploy ให้สั้น ๆ เร็ว ๆ สิ ขั้นตอนเยอะไปไหน
ชอบเขียน code ซ้ำ ๆ ก็ reuse​ ซะ
ชอบ review code ก็แยกส่วนที่ซ้ำออกมา แล้วใช้เครื่องมือช่วยซะ
เหลือไว้ที่ต้องใช้คนก็พอ

ผลที่ได้คือ จะลดข้อผิดพลาดและปัญหาลงไป
จะได้มีเวลามากขึ้น
จะได้มีเงินมากขึ้น
มีเวลาแก้ไขหรือชดใช้หนี้มากขึ้น
ส่งผลให้ business ดีขึ้น

.


สรุปความรู้ที่ได้ในการเปลี่ยนจากภาษา Python มายัง Go

$
0
0

นั่งอ่านบทความเรื่องการย้ายระบบงานด้วยภาษา Go จาก Golang :: Success Story 
มีหลาย ๆ เรื่องราวที่น่าสนใจ แต่มีเรื่องหนึ่งที่เขาเล่ามาได้ดีมาก ๆ
คือการย้ายจากภาษา Python มาใช้ภาษา Go
ที่ชอบคือ ลำดับขั้นตอนการศึกษา พร้อมแหล่งที่มา
ทำให้เข้าใจได้ง่าย จึงทำการสรุปไว้นิดหน่อย

สิ่งแรกที่บทความอธิบายคือ

ภาษา Python นั้นดีมาก ๆ พัฒนาได้ทั้ง
Web, เขียน script ง่าย ๆ, Machine Learning และ Data visualization
แต่ภาษา Go นั้นก็โตขึ้นมาถึงจุดที่น่าสนใจ
รวมทั้งเรื่องของ performance ที่ดี
ดังนั้นจึงเป็นอีกหนึ่งภาษาที่น่าสนใจ
มีความรู้หลาย ๆ ภาษา น่าจะดีกว่าภาษาเดียว
เพื่อช่วยให้ตัดสินใจได้ว่า งานอะไรเหมาะกับภาษาหรือเครื่องมืออะไร

ในบทความจะเน้นที่การเดินทางเพื่อศึกษาและใช้งานภาษา Go
ซึ่งเป็นหัวใจของบทความเลย

ขั้นตอนที่ 1 เริ่มจากการศึกษาความรู้พื้นฐานของภาษา  นั่นก็คือ Go Tour 
ตอนนี้มีแปลเป็นภาษาไทยแล้วด้วย

ขั้นตอนที่ 2 ศึกษาเพิ่มเติมจากมุมมองของ Python
คือ e-book ที่ชื่อว่า Go for Python programmers
ทำให้เห็นว่าภาษา Python กับ Go ต่างกันอย่างไรบ้าง  ทั้งเรื่องของ

  • Project structure/layout ซึ่งอ่านเพิ่มเติมได้จาก How to write Go code ? 
  • เจอ Static type language เข้าไป อาจจะทำให้คนที่มาจาก Dynamic type language อย่าง Python และ Ruby สับสนหรือขัดใจได้ หรืออาจจะชอบก็ได้
  • เรื่องของ concurency ที่มีมากับภาษา Go เลย ทั้ง goroutine และ channel ตรงนี้หลาย ๆ คนชอบ โดยแนะนำให้ศึกษาเพิ่มเติมจาก Golang routine and Channel และ Behavior of channel
  • การทำงานกับ JSON data ทำการศึกษาเพิ่มเติมได้จาก Go by Example และ Go and JSON
  • เรื่องของ Clean code ซึ่งภาษา Go นั้นได้เตรียมไว้ให้ตั้งแต่ compiler และ เครื่องมือต่าง ๆ เช่น gofmt สำหรับการจัด format ของ code จะได้ไม่ต้องมานั่งเถียงกันเป็นต้น ซึ่งแนะนำให้อ่าน Effective Go ก่อนเลย

ขั้นตอนที่ 3 หา Library และ Framework ที่เหมาะสมกับงาน
เนื่องจากภาษา Python จะมี library และ framework ที่ได้รับความนิยม
เช่น Flask, Jinja2, Request และ Kazoo
แต่สำหรับภาษา Go มันยังไม่ชัดเจนเลย ว่าอะไรทำอะไรบ้าง ?
โดยเจ้าของบทความก็ได้เปรียบเทียบกับภาษา Python ไว้ดังนี้

  • Python requests เทียบได้กับ net/http package
  • Flask + Jinja2 เทียบได้กับ Gin
  • CLI creation เทียบได้กับ Cobra สำหรับสร้าง CLI application ซึ่งมีหลาย ๆ  project ที่ใช้งานเช่น Kubernetes และ OpenShift เป็นต้น
  • Viper และ Config สำหรับ configuration management

สามารถดูเพิ่มเติมได้จาก Awesome Go

สุดท้ายมี resources ต่าง ๆ เพิ่มเติมให้ศึกษาอีก

มาเดินตามรอยของ Go Module กัน

$
0
0

จากบทความ Using Go Modules จาก website หลักของภาษา Go
ทำการอธิบายการใช้งาน Go Module
ซึ่งใน Go version 1.13 เป็นต้นไปจะเป็นค่า default สำหรับการพัฒนา
ดังนั้นควรทำการซึกษาและใช้งานกันได้แล้ว
ประกอบไปด้วย

  • การสร้าง module ใหม่
  • การเพิ่ม dependency เข้ามาใหม่
  • การ upgrade dependency ต่าง ๆ
  • การเพิ่ม dependency เข้ามายัง major version
  • การ upgrade dependency เข้ามายัง major version
  • การลบ dependency ที่ไม่ได้ใช้ออกไป

โดยจะทำการสรุปไว้ 3 เรื่องพอคือ

  • การสร้าง module ใหม่
  • การเพิ่ม dependency เข้ามาใหม่
  • การลบ dependency ที่ไม่ได้ใช้ออกไป

Module นั้นคือกลุ่มของ Go package ที่ถูกจัดเก็บในรูปแบบของ tree

ซึ่งถูกกำหนดอยู่ในไฟล์ชื่อว่า go.mod โดยที่ไฟล์ go.mod
จะอยู่ที่ root ของ module นั่นเอง ในไฟล์นี้จะใช้จัดเก็บ

  • Path ของ module
  • Dependency ต่าง ๆ ที่ต้องการใช้งาน รวมไปถึงตัวอื่น ๆ ที่ต้องการใช้งาน
  • Dependency แต่ละตัวที่ใช้งานต้องกำหนด version แบบ Semantic versioning ด้วย

มาลองทำตามบทความกัน ได้ความรู้ดีมากเลย
เหมาะมาก ๆ สำหรับคนเริ่มต้นศึกษาและใช้งานใหม่ ๆ

1. การสร้าง module ใหม่

ให้ทำการสร้าง directory ว่าง ๆ นอก $GOPATH/src นะ
จากนั้นทำการสร้างไฟล์ hello.go  มีเพียง function เดียวคือ Hello()
และส่งค่า Hello, world. กลับมา ดังนี้

[gist id="4cf4a55a5af940e9283513b8edd70d28" file="hello.go"]

ต่อมาเขียนชุดการทดสอบ
เห็นไหมว่า แม้แต่บทความสำหรับผู้เริ่มต้นก็เขียนชุดการทดสอบแล้วนะ
ดังนั้นใครไม่เขียนนี่จัดว่าบาปเลยนะ !!

[gist id="4cf4a55a5af940e9283513b8edd70d28" file="hello_test.go"]

ทำการ run ชุดการทดสอบง่าย ๆ

[code] $go test PASS ok 0.020s [/code]

ทำการแสดงผลของการ run ชุดการทดสอบ
ของระบบงานที่อยู่นอก $GOPATH และไม่อยู่ใน module ใด ๆ เลย

ดังนั้นได้เวลามาสร้าง Module แรกกันแล้ว
ชื่อ module คือ example.com/hello ด้วยการใช้คำสั่งดังนี้

[code] $go mod init example.com/hello go: creating new go.mod: module example.com/hello $go test PASS ok example.com/hello 0.020s [/code]

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

จากนั้นลองไปเปิดไฟล์ go.mod ดูจะเห็นดังนี้

[code] module example.com/hello go 1.12 [/code]

ต้องจำไว้ว่าไฟล์ go.mod จะอยู่ที่ root directory ของ Module นั้น ๆ เท่านั้น
ถ้าต้องการสร้าง package ย่อย ๆ ก็ให้สร้าง subdirectory ลงไปเรื่อย ๆ
แล้ว Go จะวิ่งไปหาให้เองแบบอัตโนมัติ

ยกตัวอย่างเช่นสร้าง directory ย่อยชื่อว่า world
นั่นคือชื่อ package จากนั้นถ้าต้องการเรียกใช้ ให้ทำการ import example.com/hello/word

[gist id="4cf4a55a5af940e9283513b8edd70d28" file="hello_test2.go"]

ทำการ run ชุดการทดสอบด้วยคำสั่ง

[code] $go test ./.. PASS ok example.com/hello ok example.com/hello/world [/code]

ดู code เพิ่มเติมได้จาก Github::Up1

2. การเพิ่ม dependency เข้ามาใหม่

ในการเพิ่ม depedency นี่เองที่ช่วยทำให้นักพัฒนาง่ายและสะดวกขึ้น
มันเปลี่ยนวิธีการคิดของนักพัฒนาไปเลย
นั่นคือ เพียงแค่ทำการ import dependency ใน code ไป
แล้ว Go module จะทำการ download และ update dependency ที่ต้องใช้งานให้เอง
ทั้ง direct และ indirect dependency
โดยที่จะไป download version ล่าสุดที่เป็นไปตาม Semantic versioning นั่นเอง
แน่นอนว่า ต้องไปแก้ไขไฟล์ go.mod ให้เองอีกด้วย
มาลองดูกัน

[gist id="4cf4a55a5af940e9283513b8edd70d28" file="hello2.go"]

จากนั้นทำการทดสอบได้ดังนี้

[code] $go test go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c go: extracting golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c PASS ok example.com/hello 0.007s [/code]

แต่ถ้า run ซ้ำอีกครั้ง จะไม่ donwload อีกแล้ว
เพราะว่า ทำการเก็บ caching ไว้ให้แล้ว

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

[code] $go mod download -json [/code]

เมื่อเปิดดูไฟล์ go.mod จะมีการเพิ่ม dependency ที่ใส่ใน code เข้ามา

[code] module example.com/hello go 1.12 require rsc.io/quote v1.5.2 [/code]

ยังไม่พอนะ ยังสร้างไฟล์ go.sum เข้ามา

สำหรับเก็บ checksum ของสิ่งที่ download มาไว้
เพื่อทำให้แน่ใจว่า ต่อไปจะทำการ download dependency ตัวเดิม
ไม่ผิดตัวนั่นเอง

[code] golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= [/code]

ถ้าอยากรู้ว่า Module ของเรามี dependency อะไรบ้าง ?
ให้ใช้คำสั่ง

[code] $go list -m all example.com/hello golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c rsc.io/quote v1.5.2 rsc.io/sampler v1.3.0 [/code]

3. การลบ dependency ที่ไม่ได้ใช้ออกไป

ง่ายมาก ๆ คือ run คำสั่ง $go mod tidy ก็จบแล้ว

ลองใช้งานกันครับ

ซึ่ง Go module มีมาตั้งแต่ Go version 1.11 แล้วนะ
โดยในบทความสรุป workflow การใช้งาน ไว้ดังนี้

  • go mod init สำหรับการสร้าง module
  • go build และ go test  สำหรับการ build และ ทดสอบ โดยจะอ่านค่าจากไฟล์ go.mod
  • go list -m all ดู dependency ต่าง ๆ ที่ใช้งานใน module 
  • go get สำหรับเปลี่ยน version ของ dependency
  • go mod tidy สำหรับลบ dependency ที่ไม่ได้ใช้ออกไปจาก module
Viewing all 1997 articles
Browse latest View live