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

ว่าง ๆ มาสร้าง Serverless function บน Cloudflare Workers กัน

$
0
0

หลังจากทาง Cloudflare ทำการเปิด opensource Wrangler CLI
เป็นชุด CLI สำหรับการสร้าง Serverless ที่พัฒนาด้วยภาษา Rust
และทำการ compile เป็น WebAssembly
จากนั้นก็ preview และ publish ขึ้น Cloudflare Workers แบบง่าย ๆ กันเลย
ดังนั้นลองมา Hello World กันหน่อย
มาเริ่มกันเลย

ปล.
เขียนทั้งภาษา Rust
เขียนทั้ง WebAssembly
สนุกแน่นอนครับ
มันออกจะงง ๆ หน่อย แต่น่าจะเป็นแนวทางในอนาคตก็ได้นะ

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

สามารถติดตั้งผ่าน Cargo ได้เลย
ดังนั้นควรเขียนภาษา Rust มานิดหน่อยเช่น Hello World
ทำการติดตั้งดังนี้

[code] $cargo install wrangler [/code]

ปล. สำหรับชาว Mac อาจจะเจอปัญหาเรื่องของ openssh
แนะนำให้ทำการติดตั้ง openssh1.1 นะครับ

[code] $brew tap arnested/openssh $brew install arnested/openssh/openssh [/code]

มาสร้าง project กันเลยด้วย Wrangler CLI

[gist id="39534653b7dd6438808456f9b36dab71" file="1.txt"]

ถ้าไม่ใส่ชื่อ project จะสร้าง directory ชื่อว่า wasm-worker ขึ้นมา
ลองเข้าไปดู จะพบว่าสร้างอะไรให้ก็ไม่รู้ เยอะมาก ๆ !!

จากนั้นทำการ build ด้วยคำสั่ง

[gist id="39534653b7dd6438808456f9b36dab71" file="2.txt"]

ผลลัพธ์ที่ได้จะอยู่ใน directory ชื่อว่า pkg นั่นเอง
ถ้าต้องการทดสอบบน localhost เองแล้ว บอกเลยว่าทำไม่ได้นะ
ต้องทำการ run บน Cloudflare Workers เท่านั้น
แต่โชคดีหน่อยว่า
ไม่ต้องมี account บน Cloudflare Workers ก็สามารถทดสอบได้ ด้วยการใช้คำสั่ง $wrangler preview ได้เลย

[gist id="39534653b7dd6438808456f9b36dab71" file="3.txt"]

จะทำการเปิด browser ให้เราทดลองใช้งานกันอีกด้วย
สบายขึ้นเยอะเลย
แต่จากที่ลองใช้งานเรื่อย ๆ พบว่า
ก็ยังเจอ bug เยอะพอสมควร
ยกตัวอย่างเช่น Resource เต็ม และ load พวก library ไม่ขึ้นนะครับ

มาลองสร้าง function ให้มันรับค่าชื่อไปหน่อยสิ

เพื่อให้ส่งค่าไปยัง function กันบ้าง
เพื่อให้รู้สึกว่าได้เขียน Rust และ WebAssembly กัน

เริ่มจากการแก้ไขไฟล์ src/lib.rs
สำหรับการสร้าง function เพื่อรับค่าชื่อ ตามที่ต้องการ

[gist id="39534653b7dd6438808456f9b36dab71" file="lib.rs"]

ต่อจากนั้นทำการแก้ไขไฟล์ worker/worker.js
สำหรับรับค่าจาก HTTP Request
ไม่งั้นมันจะดูแห้ง ๆ ไป

[gist id="39534653b7dd6438808456f9b36dab71" file="worker.js"]

เมื่อทุกอย่างเรียบร้อย
ก็ทำการ build และ preview จะได้ผลการทำงานดังนี้

จะ publish ก็ไม่มีเงิน !!
ใครสนใจลองไป Activate worker กันได้เลย


https://www.cloudflare.com/plans/

ลองไปเล่นกันดูครับ สนุกแปลก ๆ งง ๆ ดี กับตัวภาษา
แต่มันส์แน่นอนครับ

Reference Websites



สวัสดี Elastic Stack 7.0

$
0
0

และแล้ว Elastic Stack 7.0 ตัวเต็มก็ถูกปล่อยออกมา
หลังจากที่ปล่อยให้ทดลองใช้งานมาสักพัก
ซึ่งมี pull request มากกว่า 10,000 เรื่อง จาก 861 คนที่ร่วมกัน contribute

โดยสิ่งที่เปลี่ยนแปลงเยอะ ๆ และเห็นได้ชัดคือ Elasticsearch นั่นเอง
ตัวรองมาคือ Kibana ที่สามารถเปลี่ยนเป็น Dark Mode ได้ด้วย (ใช้ได้ตั้งแต่ 6.7)
รวมทั้งการปรับปรุงเรื่องการแสดงข้อมูลแผนที่ด้วย
Elastic Map Service ใน Kibana นั่นเอง

Kibana แบบ Dark mode

มาดูการเปลี่ยนแปลงและปรับปรุงของ Elasticasearch 7.0 กัน

เริ่มต้นด้วยข้อมูลพื้นฐาน
ยกตัวอย่างเช่น node name ก็เปลี่ยนเป็นชื่อเครื่องหรือ node นั้น ๆ ไปแล้ว
อีกอย่างที่ขาดไม่ได้คือไปใช้ Apache Lucene 8.0.0 แล้ว

สิ่งที่เปลี่ยนไปมากคือ การจัดการ Cluster นั่นเอง

ในเรื่องของการ scale และทนทานต่อความผิดพลาด 
เป็นความสามารถและเป้าหมายหลัก ๆ ของ Elasticsearch
ซึ่งพยายามแก้ไขและปรับปรุงให้ดีขึ้นมาตลอด
ตั้งแต่ Zen ที่ใช้ multicast จนเปลี่ยนมาให้ใช้ unicast
จนมาถึง Elasticsearch 7.0 ก็ได้เปลี่ยนมาใช้ Zen2
ซึ่งอธิบายไว้ในเอกสารว่า
เร็วกว่าเดิม ปลอดภัยกว่าเดิมและใช้ง่ายกว่าเดิม

สิ่งที่น่าสนใจมากกว่านั้นคือ 

ถ้ามีการส่ง request มายัง node หนึ่ง ๆ มาก ๆ
หรือใหญ่เกินไปที่ node นั้นจะรับไหวแล้ว
Node นั้นจะแจ้งกลับไปยังผู้เรียกทันที
เพื่อให้ผู้ใช้งานทราบและจัดการต่อไป
ยกตัวอย่างเช่น ทำการ retry หรือไปเรียก node อื่นแทน เป็นต้น
หรือนั่นคือมีการจัดการด้วย Circuit Breaker นั่นเอง

เพื่อไม่ทำให้ node นั่นตาย หรือใช้ resource เกินที่กำหนด
เนื่องจากถ้า node ใน cluster มีปัญหา เช่น Out Of Memory (OOM)
จะเกิดการทำงานที่มากมายและอาจจะทำให้ cluster ล่มก็เป็นได้
ดังนั้นการตัดปัญหาตั้งแต่แรกจึงเป้นแนวทางที่ดีกว่านั่นเอง

การปรับปรุงการค้นหาก็ทำให้การทำงานดีขึ้น

ยกตัวอย่างเช่น การดึงข้อมูลแบบ Top Hit
ซึ่งช่วยลดการค้นหาทั้งหมดใน index ต่าง ๆ ลงไป
เพราะว่าจะดึงข้อมูลในจำนวนที่ต้องการหรือน้อย ๆ
ยกตัวอย่างเช่นการค้นหาสินค้าในระบบ e-commerce
ผู้ใช้งานส่วนใหญ่มักจะดูผลการค้นหาเพียงหน้าแรก 10-20 อันดับเท่านั้น
การดึงข้อมูล product ทั้งหมดที่เจอเป็นเรื่องที่สิ้นเปลืองน่าดู
ดังนั้นใน Elasticsearch 7.0 ซึ่งใช้งาน Apache Lucene 8.0.0
จะมีความสามารถเรื่องนี้คือ Block-Max WAND 
ทำให้ดึงข้อมูลแบบ Top Hit ได้รวดเร็วมากยิ่งขึ้น

มี Interval query ที่เพิ่มเข้ามาใหม่ แต่ยังไม่เคยใช้เลย
ไว้ต้องลองไปศึกษาดูบ้างว่าคืออะไร ?

รวมถึงเรื่องของ Function Score 2.0
ช่วยจัดการเรื่องของการ custom score หรือ ranking ของผลการค้นหา
ให้เป้นไปตามที่ business ต้องการ
ใน Elasticsearch 7.0 ได้ปรับปรุงให้ใช้งานง่ายขึ้นและรวดเร็วอีกด้วย

เกือบลืมไปว่า ข้อมูลของเวลาใน Elasticsearch 7.0 นั้น
สามารถ Timestamp เก็บในหน่วย nanosecond ได้แล้ว
เพื่อตอบโจทย์ต่อการอัตราการสร้างข้อมูลที่รวดเร็วขึ้นนั่นเอง
เช่นมาจากอุปกรณ์ IoT หรือจากอุปกรณ์ network ต่าง ๆ

โดย Elasticsearch ได้เปลี่ยน library การจัดการเวลา
จาก JODA time มาใช้ Java Time ใน JDK 8 แล้ว

ลองไป Download มาใช้งานกันได้แล้วที่ Elastic Stack 7.0

ส่วนใครที่รอการ migrate อยู่ก็เตรียมได้แล้วนะครับ

สรุปเรื่อง Top 6 Microservices patterns จาก MuleSoft

$
0
0

เห็นเอกสารเรื่อง Top 6 Microservices patterns จาก MuleSoft ออกมา
เป็นการแนะนำ 6 แบบของ Microservices ที่มักถูกนำมาใช้งาน
และดูเหมือนจะเป็นรูปแบบที่เกิดขึ้นในองค์กร IT ที่เป็น enterprise เสียด้วย
จึงทำการสรุปไว้นิดหน่อย

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

กลุ่มที่หนึ่ง เรื่องของการแยกออกเป็น service เล็ก ๆ

รูปแบบที่ 1 Fine-grained SOA

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

การแยกเป็น service ย่อย ๆ ก็ทำให้เกิดปัญหาใหม่ ๆ ขึ้นมา
เช่นการติดต่อสื่อสารการระหว่าง service และการ monitoring ระบบ

ที่มาของรูปแบบนี้คือ
แต่ละ service มีขนาดใหญ่หรือหน้าที่รับผิดชอบเยอะเกินไป
ยากต่อการเปลี่ยนแปลง และเลี่ยงไม่ได้ที่จะเกิดผลกระทบ
บางครั้งเรียกระบบนี้ว่า Big bang microservices
แสดงดังรูป

รูปแบบที่ 2 Layered APIs overfine-grained SOA

จากรูปแบบที่ 1 จะแบ่งกลุ่มการทำงานในรูปแบบ Layer คือ

  • System Layer
  • Process/Domain Layer
  • Experience Layer

แต่ละ layer จะทำการ expose API ออกมา เพื่อให้ส่วนอื่น ๆ เข้าใช้งาน
รูปแบบนี้เป็นที่มาของ MuleSoft เลยก็ว่าได้
ทำให้สามารถจัดกลุ่มและจัดการ service ได้ง่ายขึ้น
แต่ก็ทำให้แต่ละ layer ต้องมีเรื่องของการทำงานร่วมกัน integration
ซึ่งจะลดเรื่องของ speed of change ลงไปอีก
แสดงดังรูป

กลุ่มที่สอง เรื่องของการจัดการ state

รูปแบบที่ 3 Message-oriented state management over layered APIs

จากในรูปแบบที่สองนั้น แต่ละ Layer จะมีการติดต่อผ่าน API ที่กำหนดไว้
ซึ่งมักจะมีปัญหาเรื่อง side-effect หรือผลกระทบที่เกิดขึ้นจากการเปลี่ยนแปลงใน layer ต่าง ๆ
เนื่องจากต้องติดต่อสื่อสารกัน
ดังนั้นวิธีการนี้จึงใช้การติดต่อสื่อสารแบบ asynchronous
โดยทุก ๆ การทำงานทั้ง event และ command ต่าง ๆ จะถูกส่งมายังตัวกลาง
ซึ่งมักจะใช้ queue เป็นตัวพื้นฐาน
จากนั้น service ต่าง ๆ ก็ต้องทำงานตาม event หรือ command นั้น ๆ
ถ้าในสายของ SOA จะเข้าใจดีในชื่อ ESB (Enterprise Service Bus)

แต่ปัญหาที่ตามมาคือ ระบบมีความซับซ้อนมากขึ้น ก็แน่ละ
ถ้าเกิดข้อขัดแย้งต่าง ๆ หรือการทำงานผิดพลาด
สามารถที่จะทำงานซ้ำใหม่หรือ rebuild/replay หรือ rollback ได้อย่างไร ?

รูปแบบที่ 4 Event-driven state management over layered APIs

ในรูปแบบนี้เริ่มต้นก็เหมือนกับรูปแบบที่ 3 แต่เพิ่มเติมคือ
การกำหนดมาตรฐานของ event ที่สร้างขึ้นมา
โดยแต่ละ event จะมีข้อมูลที่เกี่ยวข้องกับ state การทำงานนั้น
มี timestamp เพื่อระบุเวลาที่เกิดขึ้น
ทำให้แต่ละ event มีลำดับการทำงานที่ชัดเจน
ช่วยทำให้เมื่อเกิดปัญหาขึ้นมา
เราสามารถ replay หรือ rollback ได้ง่ายขึ้น

แต่แนวคิดนี้ยังทำให้เกิดความสับสนระหว่าง event กับ command
โดยที่
event คือสิ่งที่เกิดขึ้นแล้ว
ส่วน command คือคำสั่งที่ทำให้เกิดบางอย่างขึ้นมา

อีกทั้งยังมีปัญหาเรื่องของ data consistency หรือความถูกต้องของข้อมูล

รูปแบบที่ 5 Isolating state in layered APIs

เนื่องจากการติดต่อแบบ asynchronous และการใช้ messaging queue
ทำให้เกิดปัญหาเรื่อง data consistency
ดังนั้นเราแก้ไขปัญหาง่าย ๆ  ด้วยการแยกเก็บ state หรือข้อมูลตามแต่ละ layer ไปเลยสิ ไม่ต้องมา share หรือส่ง event/command ไปมา ให้เสียเวลา

แต่ต้องทำให้มั่นใจว่า ข้อมูลไม่ถูก copy ไปที่ส่วนอื่นนะ
มิเช่นนั้น เรื่องการ sync ข้อมูลจะหนักเอาการแน่ ๆ

รูปแบบที่ 6 Replicating state in layered APIs (Event sourcing)

เนื่องจากปัญหาของ data consistency ที่เกิดจากข้อมูลชุดเดียวกันอยู่หลาย ๆ ที่
จึงพยายามจะทำที่จัดเก็บความข้อมูลหรือการเปลี่ยนแปลงไว้ที่เดียว
ในส่วนแต่ละ layer/service ก็ทำการเก็บ caching data เท่าที่จะใช้งาน
เมื่อมีการเปลี่ยนแปลงก็มาจัดเก็บในรูปแบบ event ที่มีมาตรฐานไว้ตรงกลาง
โดย event จะมีคุณสมบัติตามที่กล่าวมาข้างต้น
ไม่สามารถเปลี่ยนแปลงได้
เรียงตามเวลา หรือ timestamp
ซึ่งจะเรียก event เหล่านี้ว่า event sourcing
ส่วนที่จัดเก็บเรียกว่า event store
แสดงดังรูป

ก่อนนำไปใช้งานต้องเข้าใจก่อนว่าในแต่ละ pattern เป็นอย่างไร

เหมาะกับงานประเภทไหน
ในงานที่เราพัฒนาสามารถนำหลาย ๆ pattern มาใช้งานได้เสมอ

ที่สำคัญ Microservices ไม่ได้เหมาะสมกับงานทุก ๆ อย่าง
ยกตัวอย่างเช่น 
ระบบงานมีการใช้งาน ERP ทั้งหมดแล้ว
ถ้าต้องการนำแนวคิด Microservices มาใช้
คำถามคือ คุณต้องลบ ERP ทิ้งไปเลยนะ คุณจะทำมันจริง ๆ ไหม ?
คำตอบคือ คิดเอาเองนะ นั่นมันทางที่คุณฯเลือกและต้องเผชิญต่อไป

ลองไป download มาอ่านกันได้ครับ มีเพียง 46 หน้าเท่านั้นเอง

หนังสือ Front-End Developer Handbook 2019 มาแล้ว

$
0
0


https://frontendmasters.com/books/front-end-handbook/2019/

เห็นใน email ว่าหนังสือ Front-End Developer Handbook 2019 นั้นออกมาแล้ว
เขียนโดยคุณ Cody Lindley ซึ่งเขียนมาทุกปีตั้งแต่ปี 2016
หนังสือนี้เป็นการสรุปรวมในแต่ละปี ว่ามีอะไรควรใช้งานและไม่ใช้งาน
เนื่องจาก technology ในฝั่ง frontend นั้นไปมารวดเร็วเหลือเกิน

โดยใน  Front-End Developer Handbook 2019 นั้น

มีความคาดหวังดังนี้

  • ควรเลิกใช้ Sass
  • ควรใช้งาน WebP ซึ่งเป็น format ของรูปภาพที่ browser ทุก ๆ ตัวสนับสนุนแล้ว
  • GraphQL ยังคงมีการนำไปใช้งานอย่างสูงต่อเนื่อง
  • จะมีการทำการสำรวจ CSS เพิ่มเข้ามา จากที่มีเพียบ JavaScript เท่านั้น
  • ให้จับตามมองและศึกษา Web Annimation API ไว้
  • มีความพยายามในการใช้งาน TypeScript
  • คู่แข่งของ Babel มีแล้วนั่นคือ swc-project ซึ่งพัฒนาด้วยภาษา Rust
  • สิ่งที่ยังคงพยายามต่อไป เช่น เขียน code ชุดเดียวแล้วนำไป run บนทุก ๆ platform, Prepack และ JAM stack เป็นต้น
  • ใน project ใหญ่ ๆ เช่น Bootstrap เริ่มเอา jQuery ออกไปแล้ว
  • เรื่องของ Web Component ยังคงเป็นคำถามว่ามีหรือใช้ไปทำไม ?

ลองไปอ่านรายละเอียดเพิ่มเติมดูได้
มีประโยชน์อย่างมากต่อ Front-End Developer
ขอให้สนุกกับการเขียน code ครับ

ตกใจว่า package net/http ของภาษา Go มันไม่ดีตรงไหน ?

$
0
0

ครั้งแรกที่อ่านชื่อของบทความ Don’t use Go’s default HTTP client (in production) ก็ตกใจนิดหน่อยและปลกใจว่า package net/http ของภาษา go นั้นมันมีปัญหาอะไร เพราะว่าในงานที่ขึ้น production ก็ใช้อยู่นะ และไม่ได้เกิดปัญหาอะไรด้วย
แต่พอได้อ่านบทความแล้วพบว่ามันไม่ใช่นะ 

เราต้องมาทำการ custom ค่าหรือการทำงานบางอย่างให้ถูกต้องและเหมาะสม
มิเช่นนั้น อาจจะเกิดปัญหาตามมาได้

ในบทความยกตัวอย่างการกำหนดค่าของ Timeout ของ HTTP Client
ที่ค่า default ไม่ได้กำหนดมาให้
มีทั้ง timeout ฝั่ง server และ client กันอีกด้วย เยอะไปไหน ?

ซึ่งเราสามารถกำหนดค่านี้ในฝั่ง Client ได้เลย 
ถ้ามี request หรือการทำงานที่รอข้อมูลไม่ตอบกลับไปเรื่อย ๆ
ทั้ง CPU/Memory/IO ก็จะถูกใช้จนหมด แบบนี้ไม่ดีแน่ ๆ 
ดังนั้นเราควรทำการกำหนด timeout ด้วยเสมอ
ซึ่งน่าจะเป็นสิ่งที่นักพัฒนาในทุก ๆ ภาษาทำกันอยู่แล้วนะครับ
แต่ถ้าใครใช้ framework แล้วเรื่องนี้ก็จะหายไป
เพราะว่ามักจะมีค่า default ให้เสมอ

ตังแต่ Go 1.7 ขึ้นมา จะทำการกำหนดค่า request timeout ด้วย Context กันแล้ว

[gist id="bf4a3591597f499c3479cd3384253184" file="timeout.go"]

ลองไปดู VDO เพิ่มเติมได้

สรุปจาก Infographic เรื่อง The Top 10 Big Data Challenges

$
0
0

จากกลุ่ม Data Science Thailand ทำการ share บทความ
เรื่อง The Top 10 Big Data Challenges 
ซึ่งเป็น infographic สรุปเรื่อง 10 อันดับในความท้ายของการนำ Big Data มาใช้ในองค์กร
ทำการสร้างไว้ตั้งแต่ปี 2015 เห็นว่าน่าสนใจ เลยนำมาสรุปไว้นิดหน่อย

จาก 10 อันดับพบว่า 8 เรื่องมันคือเรื่องของ culture หรือวัฒนธรรมขององค์กร
ที่เหลืออีกสองคือ เรื่องของ technical หรือ technology
มาดูกันว่าแต่ละข้อเป็นอย่างไร

  1. ในส่วนของ business ต้องทำการ share หรือแบ่งปันข้อมูลไปยังส่วนหรือแผนกอื่น ๆ ด้วย ไม่ใช่หวงข้อมูล
  2. ระบบต้องการสามารถรองรับข้อมูลที่มีขนาดมหญ่ เกิดขึ้นอย่างรวดเร็วและหลายหลายรูปแบบได้
  3. ต้องรู้ว่าจะใช้ข้อมูลอะไรบ้าง ที่ไหน จากใคร เพื่อตอบโจทย์ต่าง ๆ ที่ต้องการ เพราะว่าความต้องการต่างกันข้อมูลก็ย่อมต่างกัน
  4. ต้องสร้างความเชื่อมั่นหรือไว้เนื้อเชื่อใจระหว่าง data scientist กับ manager ในแต่ละส่วน
  5. ต้องทำการหาหรือจ้างคนที่เข้ามาช่วยดูหรือจัดการข้อมูล รวมทั้ง insight ของข้อมูล ควรเริ่มด้วยการหาจากในองค์กรก่อน
  6. ต้องได้รับการสนับสนุนจากผู้บริการระดับสูง ไม่ใช่แค่เรื่องการลงทุนเฉพาะ project Big data เพื่อหาหรือซื้อเครื่องมือ แต่ต้องลงทุนกับคนด้วยเช่นการ training เป็นต้น
  7. สุดท้ายของการนำผลการวิเคราะห์ข้อมูลไปใช้งาน คือ การอธิบายหรือ present ออกไปให้คนที่ต้องการใช้ในการตัดสินใจเข้าใจได้ง่าย ดังนั้นจำเป็นต้องมีระบบ dashboard หรือ visulization tool มาใช้งาน
  8. ต้องหาวิธีการจัดการเกี่ยวกับ Big data ในองค์กรให้ง่ายและสะดวกมากที่สุด จะได้ไม่เป็นภาระแก่ลูกหลาน
  9. ในองค์กรต้องมีความเข้าใจเกี่ยวกับการลงทุนด้าน Big Data ด้วยว่าทำไปทำไม ไม่ทำแล้วจะได้หรือเสียอะไร
  10. สิ่งที่สำคัญอีกอย่างคือ คนในองค์กรต้องเข้าใจด้วยว่าจะนำผลที่ได้จาก Big Data ไปทำอะไร ใช้อย่างไร เพราะว่าต่อให้ระบบดีเพียงใด แต่คนใช้ใช้ไม่เป็นหรือไม่เข้าใจ หนักกว่านั้นคือใช้งานแบบผิด ๆ มันก็ไร้ค่ามาก ความรู้พื้นฐานและความเข้าใจจึงสำคัญมาก ๆ

แสดงดังรูป

https://www.getelastic.com/big-data-infographic-2

ก่อนที่จะนำเครื่องมืออะไรมาใช้
ลองกลับมาดูที่คนและองค์กรก่อนว่าพร้อมหรือไม่ ?

มันดีทุกอย่างเลยนะ …แต่อยากให้หัวหน้ามาเรียน !!!

$
0
0

จากหัวข้อ Design Thinking ในงาน Beta conference ครั้งที่ 1
มีคำพูดหนึ่งที่ยังจำได้ชัดเจน
เป็น feedback ที่ผู้พูดได้รับจากการสอน Design Thinking ให้กับแต่ละองค์กรนั่นก็คือ "ทุกอย่างที่เรียนมานั้นมันดีมาก แต่อยากให้หัวหน้ามาเรียน"
ทำให้ฉุกคิดขึ้นมาว่า นี่เรากำลังทำอะไรกันอยู่

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

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

สวัสดี Google Cloud Run

$
0
0

ทาง Google Cloud เพิ่งปล่อย Google Cloud Run ใน version beta ให้ใช้งาน
โดยให้เหล่านักพัฒนาสามารถ run serverless app ที่อยู่ใน Docker container ได้เลย ซึ่ง Google Cloud Run จัดการให้เองแบบอัตโนมัติ คือ
เมื่อมี request เข้ามาจะทำการ start ให้เอง
และเมื่อไม่มีการใช้งานจะทำการ stop ไปให้อีก
ชีวิตน่าจะง่าย สะดวกมากขึ้น

อีกทั้งการจัดการทั้งหมดจะอยู่บน Knative 
นั่นหมายความว่า
สามารถนำ serverless ที่ run อยู่บน Google Cloud Run
ไป deploy บน platform อื่น ๆ ที่ใช้ Kubernetes ได้อีกด้วย เช่น Google Kubernetes Engine (GKE)
ส่วนการ scale จะทำให้แบบอัตโนมัติ (Elastic scale) ตามจำนวน request นั่นเอง

https://www.youtube.com/watch?v=gx8VTa1c8DA

มาลอง deploy ระบบงานง่าย ๆ กันดีกว่า

ทำ Hello app ซึ่งจะ Build เป็น Docker Image เพื่อ deploy กัน
ส่วนเรื่องภาษาก็เอาที่สบายใจ
ในหน้า Quick Start นั้นมีหลายภาษาเลย
ทั้ง Go, Node, Python, PHP, Ruby และอื่น ๆ

โดยใน blog นี้เลือกใช้ Go แค่ทำ Web Server ให้แสดงคำว่า Hello World พอนะ
สามารถดูเพิ่มเติ่มได้ใน Github:Up1

ขั้นตอนการพัฒนาและ deploy เป็นดังนี้

ขั้นตอนที่ 1 ทำการ build Docker Image และ run Docker container ในเครื่องเราก่อน

[code] $docker image build -t somkiat/hello_cloud_run:1.0 . $docker container run -d -p 8080:8080 somkiat/hello_cloud_run:1.0 $curl http://localhost:8080/ Hello Google Cloud Run! [/code]

ขั้นตอนที่ 2 ทำการ submit และสร้าง Docker image ไปไว้ที่ Google Container Registry

จากที่ลอง deploy ด้วย Docker image ที่อยู่ใน Docker Hub จะไม่ได้นะ !!

[code] $gcloud builds submit --tag gcr.io/[PROJECT-ID]/helloworld [/code]

ขั้นตอนที่ 3 ทำการ deploy serverless บน Google Cloud Run

จากที่ลองสามารถ deploy ได้บาง region เท่านั้น
เพราะว่ายังอยู่ในสถานะ beta นั่นเอง
จากตัวอย่างผมทำการ deploy ไปยัง region us-central-1

[code] $gcloud components install beta $gcloud components update $gcloud beta run deploy --image gcr.io/[PROJECT-ID]/helloworld --region us-central1 ✓ Deploying new service... Done. ✓ Creating Revision... ✓ Routing traffic... ✓ Setting IAM Policy... Done. Service [helloworld] revision [helloworld-00001] has been deployed and is serving traffic at https://helloworld-6tqzl55hla-uc.a.run.app [/code]

จะได้ URL สำหรับ app ที่เรา deploy มาให้ใช้งานทันที

และสามารถเข้าไปดูใน Google Cloud Console ได้เลย

Google Cloud Run ลักษณะเหมือนกับพวก Serverless หรือ Function as a Service ต่าง ๆ

ไม่ว่าจะเป็น Google Cloud Functions, AWS Lambda และ Azure Functions
แต่ต่างกันมากเรื่องไม่ผูกมัดกับ platform
กับเรื่องของเทคโนโลยี และ ภาษาโปรแกรม
อีกทั้งยังสามารถใช้งาน Docker ได้อีก ยิ่งทำให้สะดวกขึ้นไปอีก
เพราะว่า สามารถทดสอบที่ local ก่อนได้เลย ไม่ต้องมีเรื่องเยอะ

นั่นหมายความว่าคู่แข่งของ Google Cloud Run จริง ๆ
คือ Azure Container Instances และ AWS Fargate นั่นเอง

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

Reference Websites



บันทึกการเขียน Unit Test ที่ดี

$
0
0

ระหว่างนั่งเตรียมเรื่องการเขียน Automated Tests สำหรับการทดสอบระบบงาน
มีเรื่องหนึ่งที่น่าสนใจมาก ๆ คือ
ในการเขียน Unit test นั้นมีแนวทางที่ดีอะไรบ้าง
ที่จะทำให้เราเขียนได้ดีขึ้น
จึงทำการสรุปไว้ 3 เรื่องง่าย ๆ ดังนี้

เรื่องที่ 1 ในแต่ละ test case ให้ทดสอบเรื่องเดียว

ตามแนวคิดของ Single Responsibility Principle (SRP) มันสำคัญมาก ๆ
นั่นคือแต่ละ test case ควรตรวจสอบเรื่องเดียว เป้าหมายเดียว
แต่ไม่ใช่บอกว่ามีการ assert เพียงบรรทัดเดียวนะ !!

เพราะว่า ถ้ามีการทดสอบในหลาย ๆ เรื่องพร้อมกันใน test case เดียวแล้ว
ปัญหาที่ตามมาคือ ความงง ความซับซ้อน ดูแลรักษายากมาก ๆ
ดังนั้นในแต่ละ test case ต้องเฉพาะเจาะจงไปเลย
ว่าต้องการจะทดสอบอะไร
ถ้ามีหลายเรื่องก็ให้แยกเป็นเรื่องย่อย ๆ 
จากนั้นจึงแยกออกเป็น test case ไปซะ

อย่าลืมว่า คิดก่อนทำนะ
เราคิดอย่างไร ก็จะทำเช่นนั้น

เรื่องที่ 2 ตั้งชื่อ test case ให้ดี เข้าใจและอ่านได้ง่าย

ชื่อนั้นสำคัญไฉน ?
ชื่อของ test case มันเป็นสิ่งที่บอกว่า
เราต้องการจะทำอะไร
ทดสอบอะไร
คาดหวังอะไร

เป็นการบอกว่า เรานั้นเข้าใจปัญหาที่ต้องการทดสอบ
หรือเราเข้าใจปัญหาที่ต้องการแก้ไขหรือไม่นั่นเอง !!

ยกตัวอย่างของชื่อ test case ที่ไม่ดี
testcaseTBD00001
testcaseTBD00002
testcaseTBD00003 …

คำถามคือ test case เหล่านี้ทำอะไร
ทดสอบอะไร คาดหวังอะไร
เมื่อมีปัญหาเช่น ทดสอบไม่ผ่าน
เราจะรู้ได้อย่างไรว่าเกิดจากปัญหาอะไรได้บ้าง ​?

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

  • ตั้งชื่อตาม business case ไปเลย ดังนั้นก่อนพัฒนาหรือทดสอบต้องมี test case รอไว้แล้ว
  • ตั้งชื่อตามรูปแบบ ชื่อ function + action + ผลที่คาดหวัง
  • ตั้งชื่อตามรูปแบบ ชื่อระบบ + action + ผลที่คาดหวัง

อย่าลืมว่า ชื่อ test case ต้องสัมพันธ์กับสิ่งที่อยู่ใน test case ด้วยนะ
ไม่ใช่ชื่อไปทาง การทดสอบจริง ๆ ไปอีกทาง แบบนี้ก็ไม่ไหว

เรื่องที่ 3 โครงสร้างของ test case ก็สำคัญเช่นกัน

มีเป้าหมายที่ชัดเจนแล้ว มีชื่อที่ดีแล้ว
ต่อมาก็เป็นเรื่องของโครงสร้างภายใน test case ซึ่งมีหลายรูปแบบ
หนึ่งในนั้นที่ผมชอบใช้คือ AAA (Arrange, Act, Assert)

  • Arrange สำหรับการกำหนดค่าหรือสถานะเริ่มต้น เช่นการ mock/fake/stub สิ่งต่าง ๆ ที่ต้องใช้งาน
  • Act สำหรับการเรียก function หรือพฤติกรรมต่าง ๆ ที่ต้องการทดสอบ
  • Assert สำหรับการตรวจสอบผลการทำงานจริง ๆ กับสิ่งที่คาดหวัง ว่าตรงตามที่หวังหรือไม่

ผลที่ได้จากการมีโครงสร้างที่ดีคือ
ทุกคนในทีมจะมีแนวทางเดียวกัน
ทำให้คุยกันได้ง่าย
ทำให้ดูแลรักษาได้ง่ายขึ้น

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

สุดท้ายลงมือทำครับ

Make it Work => เรียนรู้ ลงมือทำให้มากที่สุด 
Make it Right => เรียนรู้ ในสิ่งที่ถูกและผิด แนะนำให้เรียนจากสิ่งที่ผิดแล้วทำการปรับปรุง Make it Fast => เรียนรู้ ปรับปรุงการเขียนและการทดสอบให้เร็ว เพื่อทำให้ได้รับ feedback ที่เร็วและดี

ทุกอย่างมันไม่ง่ายเลย ถ้าไม่ลงมือทำ
ก็จะไม่ได้เรียนรู้และปรับปรุงอะไรเลย
วันนี้เขียน test แล้วหรือยัง ?


จัดการ Web Driver ง่าย ๆ ด้วย Web Driver Manager

$
0
0

จาก release note ของ Robot Framework 4.0 alpha 1 นั้น
เห็นข้อหนึ่งว่า Web Driver Manager ทำการแก้ไขไฟล์ readme ด้วย
เป็นสิ่งที่เคยเห็นผ่าน ๆ แต่ยังไม่เคยลองใช้งาน
ดังนั้นมาดูกันหน่อย ว่ามันทำอะไร และ มีประโยชน์อะไรบ้าง ?

Web Driver Manager คืออะไร ?

ง่าย ๆ คือ ตัวจัดการพวก Web Driver ที่ Selenium
ใช้สำหรับควบคุม web browser ต่าง ๆ นั่นเอง
โดยที่จะทำการ download/deploy 
รวมทั้งทำการกำหนดค่าใน environment variable ชื่อว่า PATH ให้อีกด้วย
ส่งผลให้เราไม่ต้องจัดการเองอีกต่อไป
ลดงานไปได้เหมือนกันนะ

โดยที่จะสนับสนุน Driver ดังต่อไปนี้

ติดตั้งผ่าน pip เลย ดังนี้

[code] $pip install webdrivermanager [/code]

การใช้งานก็ไม่ยาก

ตัวอย่างเช่นต้องการใช้งาน Chrome Driver ทำดังนี้

[code] $webdrivermanager chrome [/code]

เพียงเท่านี้ก็ใช้งานได้แล้วครับ ง่ายมาก ๆ
ลองใช้งานกันดูครับ

สรุปสิ่งที่น่าสนใจจาก Technology Radar Vol. 20

$
0
0

จากงาน XConf ที่ผ่านมาเห็นมีหนังสือ Technology Radar 20 ภาษาไทยแจกด้วย
ดังนั้นลองมาทำการสรุปหน่อยว่า
ในครั้งนี้มีอะไรเปที่น่าสนใจบ้าง 
โดยแบ่งเป็น 4 หัวข้อดังนี้

  1. Techniques
  2. Tools
  3. Platforms
  4. Languages and Frameworks

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

รูปแบบของ Technology Radar 20 นั้นประกอบไปด้วย 4 เรื่องคือ

  1. การจัดการข้อมูลที่เกิดขึ้นอย่างรวดเร็วและมีจำนวนสูงมาก ๆ ดังนั้นต้องวางแผนในการจัดการข้อมูลให้ดีและเหมาะสม
  2. เรื่องของ Terraform ซึ่งมีการเติบโตและได้รับการยอมรับหรือนำมาใช้งานสูงมาก ๆ ตาม Docker และ Kubernetes รวมทั้งมีเครื่องมือที่เกี่ยวข้องให้ใช้มากมาย
  3. ภาษา Kotlin ได้รับความนิยมสูง รวมทั้ง library และเครื่องมือที่ครบครัน
  4. อย่านำ Business logic เข้าไปอยู่ใน XXX as a code 

มาดูในกลุ่มของ Technique กันหน่อย
ว่าแนะนำอะไรมาให้ใช้งานบ้าง

เรื่องที่ 1 คือตัวชี้วัด 4 เรื่องจาก State of DevOps 

โดยเน้นการนำข้อมูลและสถิติมาใช้ในการจัดตัดสินใจขององค์กร ประกอบไปด้วย

  1. Lead time
  2. Deployment frequency
  3. Mean Time to Restore (MTTR)
  4. Change fail percentage

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

เรื่องที่ 2 คือการจัด format ของ code แบบอัตโนมัติ

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

ดังนั้นจะดีกว่าไหมถ้ามีเครื่องมือมาช่วยจัดการ
ถึงแม้จะไม่เห็นด้วยทั้งหมด
ก็สามารถ custom ได้นะ
แต่น่าจะมีประโยชน์มากขึ้น ลดการถกเถียงลงไป
ยกตัวอย่างเช่น

  • Prettier สำหรับ JavaScript
  • Black สำหรับ Python
  • หรือจะ build-in มาใช้ตัวภาษาเลยเช่น Go และ Elixir เป็นต้น

การจัด format ก็ให้ทำแบบอัตโนมัติไปเลย
ยกตัวอย่างเช่น การใส่ไว้ใน git hook ตอนที่กำลัง commit (pre-commit) เป็นต้น

เรื่องที่ 3 คือ Secret as a Service

การเก็บข้อมูลที่เป็นความลับต่าง ๆ
ทั้งข้อมูลของผู้ใช้งาน, infrastructure และ เครื่องมือต่าง ๆ
ยกตัวอย่างเช่น password, credit card, key เข้าระบบ เป็นต้น
จำเป็นต้องมีที่จัดเก็บที่ปลอดภัย
รวมทั้งการเข้าถึง service ก็จำเป็นต้องมี key ในการเข้าถึง
ดังนั้นเรื่องของ key management ก็สำคัญ
ถ้าหลุดไป งานเข้าแน่นอน
อีกเรื่องของ communication ระหว่าง service หรือ ระบบงาน
จำเป็นต้องมีการเชื่อมต่อที่ปลอดภัย และ ข้อมูลก็ต้องเข้ารหัสเช่นกัน

การกำหนดค่าและเข้าถึงข้อมูลที่เป็นความลับมีหลายรูปแบบ
แน่นอนว่า
เราจะไม่ทำการจัดการข้อมูลเหล่านี้ไว้ใน source code management อยู่แล้ว
เพราะว่ามันไม่ปลอดภัยเลย
ดังนั้นจึงแนะนำให้แยกส่วนของการจัดการข้อมูลที่เป็นความลับออกไป
อาจจะใช้เครื่องมือเช่น get-secrets และ tailsman เป็นต้น
เพื่อหลีกเลี่ยงการจัดเก็บใน source control management

แนะนำให้ใช้ Secrets as a Service สามารถใช้งานผ่าน HTTPS
มี endpoint ที่ปลอดภัย เพราะว่ามีระบบ access control ที่ดีและน่าเชื่อถือ
ยกตัวอย่างเช่น Vault และ AWS Key Management Service (KMS)

เรื่องที่ 4 Micro Frontend

ปกติเรามักจะคุยกันแต่เรื่องของ Microservices
ซึ่งจะเน้นไปที่ส่วนของ backend เท่านั้น
แต่เมื่อมาดูในส่วนของ frontend จะพบว่า
ยังคงมีรูปแบบเป็น Monolith frontend
ทำให้ส่วนของ frontend นั้นมีขนาดที่ใหญ่มาก ๆ
แน่นอนว่า ยากต่อการพัฒนาและดูแลรักษา
อาการเหมือนกับฝั่ง backend เลย

ดังนั้นจึงพยายามแก้ไขปัญหาเหล่านี้ลงไป
ดังนั้นเรื่องของ Micro frontend จึงเหมาะสมต่อการนำมาปรับใช้งานอย่างมาก
โดยในส่วนนี้จะพูดถึง Web component standard มากขึ้น

เรื่องที่ 5 Polyglot programming

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

ส่วนเทคนิคที่น่าจะลองนำมาใช้งานเพื่อดูผล
จะเน้นไปที่ security โลกของ DevOps, Container มาก ๆ  เช่น

  • การ scan เรื่อง security ของ Container
  • การ scan เรื่อง security ของ Infrastructure as a Code
  • การจัดการ Service mesh

สามารถทำการ Download มาอ่านเพิ่มเติมได้

ว่าด้วยเรื่องการจัดการ Error ถ้ามันเยอะก็ลดสิ

$
0
0

จากการมาเรียน Workshop Practical Go
ในงาน GopherCon 2019 ที่ประเทศสิงคโปร์ มีหลายเรื่องที่น่าสนใจ ประกอบไปด้วย

  • Idiomatic code
  • Package และ project structure
  • API design
  • Error handling
  • Testing นิดหน่อย

ส่วนเรื่อง concurrency นั้นไม่ได้สอนเพราะว่า เวลาหมดก่อน
เรื่องที่ผมให้ความสนใจเรื่องแรกคือ Error handling
เนื่องจากใน Go 2 นั้น มีการพูดถึงปัญหาและแนวทางการปรับปรุงเรื่องนี้ให้ดีและง่ายขึ้น

สิ่งที่น่าสนใจของการจัดการ Error ที่ดีนั้น

  • ต้องไม่ทำให้ logic หรือการทำงานของ code มันยุ่งยากหรือวุ่นวาย เพราะว่าทำให้เข้าใจได้ยาก
  • Software ที่ดีและน่าเชื่อถือ ไม่จำเป็นต้องมาจัดการ unchecked หรือ runtime exception เอง

ปล.
นี่คือการด่าภาษา Java เลยนะ  ที่มี try/catch block
รวมถึงต้องจัดการ runtime exception เองอีก !!

แต่สิ่งที่น่าสนใจกว่าคือ

จะดีกว่าไหม ?
ถ้าเราไม่จำเป็นต้องจัดการ error หรือทำการลด code
ที่ต้องทำการตรวจสอบ error ลง
เพราะว่าส่วนของการจัดการหรือตรวจสอบ error นั้น
ส่งผลต่อขั้นตอนการทำงานใน function นั้น ๆ
แน่นอนว่าทำให้ซับซ้อนและเข้าใจยากขึ้น !!

มาดูตัวอย่างการนับจำนวนบรรทัดของข้อมูลกัน

[gist id="e12091956520f45f6e2b2aafe584273b" file="counting.go"]

คำอธิบาย
จาก code ที่เขียนขึ้นมานั้น
จะต้องทำการวน loop เพื่ออ่านข้อมูลของแต่ละบรรทัด
ด้วย function ReadString() จาก bufio.Reader
อ่านไปจนกว่าจะจบไฟล์นั้น ๆ
โดยในแต่ละรอบต้องทำการตรวจสอบ error ด้วยเสมอ
คำถามคือ สิ่งที่เขียนมานั้น มันใช่สิ่งที่เราต้องการจริง ๆ หรือไม่ ?

จะดีกว่าไหม ถ้าเปลี่ยนวิธีคิดและวิธีเขียนกัน

เป้าหมายเพื่อลดการจัดการ error ลงมา หนึ่งในนั้นคือ
การใช้ bufio.Scaner แทน 
โดยที่จะเป็น abstraction layer หรือ helper ที่ครอบ bufio.Reader ไว้
ช่วยจัดการ error ต่าง ๆ ให้
ดังนั้นในมุมมองของคนใช้งานอย่างเรา ๆ ท่าน ๆ 
ไม่จำเป็นต้องมาจัดการ error ต่าง ๆ เองหรือลดการตรวจสอบลงไป
ดังตัวอย่าง

[gist id="e12091956520f45f6e2b2aafe584273b" file="counting2.go"]

คำอธิบาย
จาก code นั้น scanner จะมี function Scan() ให้ใช้งาน
ทำการ return ค่า true ถ้าอ่านเจอข้อมูลในบรรทัดและไม่มี error เกิดขึ้น
แต่ถ้ามี error ขึ้นมา จะ return ค่า false
ที่สำคัญจะทำการบันทึก error ที่เกิดขึ้นให้
สามารถเรียกใช้ function Err() จาก scanner อีกด้วย
ทำให้ code ดูอ่านง่าย เข้าใจง่าย
ที่สำคัญคือ มี code เท่าที่เราต้องการอีกด้วย

เป็นอีกแนวทางหนึ่งที่น่าสนใจ
ที่ต้องศึกษา ฝึก ลงมือทำและปรับปรุงต่อไป

หนังสือน่าอ่าน A Philosophy of Software Design

$
0
0

จากที่ไปเรียนมาพบว่าในเอกสาร
มีอ้างอิงถึงหนังสือชื่อว่า A Philosophy of Software Design
จึงลองตามไปดูว่าในหนังสือมีอะไรบ้าง
ก็พบว่าเป็นหนังสือที่น่าสนใจ
เขียนโดยคุณ John Ousterhout เป็นอาจารย์สอนเรื่องของ Software Design

โดยหนังสือเล่มนี้เป็นการสรุปแนวคิดต่าง ๆ ของการออกแบบ software

นำข้อผิดพลาดที่เกิดขึ้นจากการวิจัยและสอน รวมทั้งงานจริง ๆ 
หัวใจหลักของการออกแบบ software คือ
การแยกส่วนการทำงานต่าง ๆ ที่มันมีความซับซ้อนออกจากกัน (decomposition)
ออกมาเป็น module เช่น class และ method ซึ่งทำงานเป็นอิสระต่อกัน

เนื้อหาในหนังสือประกอบไปด้วย

  1. Introduction
  2. The nature of complexity
  3. Working code isn't enough
  4. Modules should be deep
  5. Information hiding (and Leakage)
  6. General-purpose modules are deeper
  7. Different layers, different abstractions
  8. Pull complexity downwards
  9. Better together or better apart? 10 Define errors out of existence
  10. Design it twice
  11. Why write comments? The four excuses
  12. Comments should describe things that aren't obvious from the code
  13. Choosing names
  14. Write comments first
  15. Modifying existing code
  16. Consistency
  17. Code should be obvious
  18. Software trends
  19. Designing for performance

จาก course Practical Go ที่ไปเรียนมา
จะพูดถึงเรื่องที่ 9 คือ Better together or better apart? 10 Define errors out of existence

มีกลุ่มใน Google Group สำหรับพูดคุยหนังสือเล่มนี้กับผู้เขียนด้วย

สามารถดู VDO เรื่องนี้ได้อีก

https://www.youtube.com/watch?v=bmSAYlu0NcY

ถ้าสังเกตให้ดีจะเป็นหนังสือที่มีเนื้อหาคล้าย ๆ กับหนังสือพวก

  • Clean code
  • Code simplicity
  • The Pragmatic Programmers

เป็นหนังสือในกลุ่มสำหรับนักพัฒนาที่เพิ่มเริ่มต้นจนถึงระดับกลาง
ส่วนใครที่เป็นคนมีประสบการณ์สามารถนำมาศึกษาเพื่อ reflect ตัวเองได้ดีอีกเล่ม
ว่าแล้วไปหาหนังสือเล่มจริงมาอ่านกันดีกว่า

สรุปเรื่องของ Principle 3 ข้อของภาษา Go

$
0
0

จาก course Practical Go นั้นในช่วงเริ่มต้น
ทำการอธิบายเรื่องของ Principle guideline ของภาษา Go
ซึ่งประกอบไปด้วย 3 เรื่องคือ

  1. Clarify
  2. Simplicity
  3. Productivity

เรื่องนี้เคยเรียนและได้ยินจาก course Ultimate Go ที่เรียนเมื่อ 2 ปีก่อน
ทั้ง 3 เรื่องนี้มีความสำคัญมาก ๆ
เหมือนเป็นเข็มทิศนำทางของการพัฒนา software เลย
มาดูในรายละเอียดกัน

เริ่มด้วยสิ่งที่น่าสนใจอีกแล้วคือ

คำว่า Software programming กับ Software engineering
มีความแตกต่างกันอย่างไร ?

Software programming คือการพัฒนาระบบงานให้เสร็จไปตามหน้าที่
จากนั้นเดี๋ยวก็มีคนมารับไปทำหรือดูแลต่อไป

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

คำถามคือ เรากำลังทำอะไร ?

กลับมาที่เรื่องของ Principle 3 ข้อ

  1. Clarify
  2. Simplicity
  3. Productivity

โดยจะไม่มีเรื่องของ performance และ concurrency เลย
เนื่องจากมันคือความสามารถภาษา
รวมทั้งความสำคัญของ 3 เรื่องข้างต้นจะมีความสำคัญกว่า
มาดูรายละเอียดของแต่ละเรื่องกัน

เรื่องที่ 1 Clarify หรือ ชัดเจน เข้าใจได้ง่าย

เนื่องจากในการเขียน code นั้น
เรามักจะใช้เวลาในการอ่านมาก และอ่านบ่อยมาก ๆ
ดังนั้นถ้า code ที่เขียนมานั้นมันชัดเจน เข้าใจได้ง่าย
ตามที่เราต้องการจริง ๆ น่าจะดีไม่ใช่น้อยนะ

มีคำพูดที่น่าสนใจคือ
เราเขียน code เพื่อให้คนอ่าน ไม่ใช่เพียงให้ machine เข้าใจและทำงานตามเท่านั้น


การเขียน code มันก็คือ communication skill 
หรือเป็นความสามารถในการสื่อสารสิ่งที่คิดออกไป
เพื่อให้เราและคนอื่น ๆ เข้าใจ
ยิ่งถ้ามีความสามารถด้านนี้มาก ๆ
สิ่งที่ออกมาก็จะชัดเจนและเข้าใจได้ง่าย

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

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

เรื่องที่ 2 Simplicity หรือความเรียบง่าย

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

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

บ่อยครั้งเรามักจะเจอเหตุการณ์
ไปอ่าน code ของระบบแล้วไม่เข้าใจเลยว่าทำอะไร ?
แต่ต้องทำการแก้ไขตามความต้องการ
ผลคือกลัว หรือ ไม่กล้าทำ
เพราะว่า ไม่รู้ว่ามันทำงานอย่างไร
แก้ไขไปแล้วจะกระทบตรงไหนบ้าง
หนักกว่านั้น เมื่อไม่เข้าใจ
ก็ไม่รู็จะไปแก้ไขตรงไหนอีก
นี่แหละเขาเรียกว่าระบบมีความซับซ้อน

ปัญหาเหล่านี้มันเป็นสิ่งที่ทำลายระบบงานของเราลงไปเรื่อย ๆ
ดังจะเห็นได้ในหลาย ๆ ระบบงานที่เราดูแลกันอยู่ !!
ดังนั้นเรื่องของ Simplicity จึงเป็นเป้าหมายหลักของการออกแบบภาษา Go

เรื่องที่ 3 Productivity

จาก 2 ข้อแรกนั้นเป็นแนวปฏิบัติพื้นฐานเลยของการออกแบบและพัฒนาระบบงาน
และมันส่งผลต่อ productivity ของการทำงาน

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

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

เป้าหมายของภาษา Go เรื่อง productivity
จะพยายามลดสิ่งที่ไม่จำเป็นออกไป
อะไรที่ตรวจสอบให้ได้จะทำให้เลย
ทำให้นักพัฒนาสนใจไปที่การพัฒนาไปเลย
ทั้งเรื่องของการ debug
ทั้งเรื่องของการจัด format ของ code
ทั้งเรื่องการตรวจสอบสิ่งที่ไม่ได้ใช้
ทั้งเรื่องการ build และ deploy ที่ไม่ต้องเยอะ

โดยรวมแล้วเป้าหมายหลัก ๆ ของ productivity ของภาษา Go
คือเรื่องของการ scale
ทั้ง scale ของทีม
ทั้ง scale ของระบบ
ทั้ง scale ของ code

Principle 3 ข้อของการออกแบบและพัฒนาระบบด้วยภาษา Go เป็นเรื่องที่นักพัฒนาจำเป็นต้องเข้าใจด้วย เพราะว่า เพียงแค่เขียนให้ทำงานได้คงยังไม่พอ

มาดูแนวโน้มของ Architecture และการออกแบบ Software จากทาง InfoQ กัน

$
0
0

เพิ่งไปเรียน course Domain-Driven Design (DDD) มา
มีเรื่องหนึ่งที่น่าสนใจจาก course คือ 
Architecture and Design InfoQ Trends Report ประจำเดือนมากราคม 2019
ซึ่งแบ่งกลุ่มตาม Diffusion of innovations แสดงดังรูป

แบ่งออกเป็น 4 กลุ่มคือ

  1. Innovators คือกลุ่มชอบลองของใหม่ ๆ ที่ยังไม่มีใครใช้ จะไม่กลัวกับปัญหาที่จะต้องเจอ
  2. Early Adopters คือกลุ่มที่เปิดรับสิ่งใหม่ ๆ ได้เร็ว มองเห็นประโยชน์จากเทคโนโลยีต่าง ๆ
  3. Early Majority คือกลุ่มที่เข้ามายังกระแสหลักกลุ่มแรก มีตัวอย่างที่ประสบความสำเร็จให้เห็นแล้ว 
  4. Late Majority คือกลุ่มที่เข้ามายังกระแสหลักทีหลังเพื่อไม่ให้ตกยุค

มาดูกันว่าแต่ละกลุ่มมีอะไรบ้าง

เริ่มจากกลุ่มที่ 4 Late Majority

ประกอบไปด้วย

  • Microservices
  • Domain-Driven Design (DDD)
  • Behaviour-Driven Design (BDD)
  • Test-Driven Design (TDD)
  • REST

หมายความว่าในกลุ่มนี้เป็นกระแสหลักไปแล้ว
ใครไม่รู้จักน่าจะเริ่มมีปัญหา หรือ คุยกับคนอื่น ๆ ไม่รู้เรื่อง

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

กลุ่มที่ 3 Early Majority

ในกลุ่มนี้ประกอบไปด้วย

  • Event-Driven Architecture และ Event Sourcing
  • Eventual Consistency

ซึ่งไม่น่าแปลกใจมากนัก
เพราะว่ามีความเกี่ยวข้องกับกลุ่มที่ 4 อย่างมาก
จะเน้นไปที่โลกของ distributed มากขึ้น

กลุ่มที่ 2 Early Adopters

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

  • GraphQL
  • Reactive Programming
  • Functional Programming
  • CQRS
  • Serverless
  • Evolutionary Architecture
  • Architect as Technical Leader
  • Correctly designing distributed system

กลุ่มที่ 1 Innovators

เป็นกลุ่มที่ลองของใหม่ ๆ เช่น

  • Blockchain
  • Service Mesh
  • HTTP 3

ซึ่งแตกต่างจากแนวโน้มในปี 2018 ดังรูป

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


[Part 1] สรุปจากการไปเรียน Domain-Driven Design by Roofimon

$
0
0

พอดีช่วงบ่ายวันศุกร์เห็น course Domain-Driven Design by Roofimon เด้งขึ้นมา
ลองไปกดดู ก็มีบัตรว่างด้วย
ดังนั้นจึงซื้อตั๋วไปเรียนด้วย
เป้าหมายหลัก ๆ เพื่อทำให้รู้และเข้าใจเกี่ยวกับ DDD (Domain-Driven Design)
ว่าคืออะไร เป็นอะไร
มาเริ่มกันเลย

เป้าหมายของ course นี้ประกอบไปด้วย

  • ที่ไปที่มาของแนวคิด DDD
  • Principles ต่าง ๆ
  • วิธีการในการทำ Modeling หรือ Model-Driven Design ซึ่งมีหลายรูปแบบ
  • วิธีการทำงานร่วมกันหรือ collaboration
  • อธิบายถึงแนวคิด CQRS(Command Query Responsible Segregation) และ Event sourcing

จะเน้นไปที่แนวคิด การออกแบบ การทำงานร่วมกัน
ส่วนการ implementation หรือพวก technical จะไม่เน้น

เข้าใจที่ไปที่มาของ DDD จากรูปแบบการออกแบบ software กัน

เริ่มต้นด้วยแนวทางการออกแบบเดิม ๆ
หรือการออกแบบในการทำงานแบบ Waterfall นั้น
พยายามให้ทีมออกพยายามทำการออกแบบ
ในขณะที่มีความรู้ใน domain หรือเรื่องนั้น ๆ น้อยมาก
(ยกเว้นว่ามีความรู้ด้านนั้น ๆ มานานและมากแล้ว)
ทำให้การออกแบบออกมาในรูปแบบหนึ่งซึ่งก็สามารถทำงานได้ดี !!

แต่เมื่อเรามีความรู้มากขึ้น
ระบบงานใหญ่ขึ้น หรือมีความซับซ้อนมากขึ้น
พบว่าสิ่งที่ออกแบบและทำมานั้น
มันเริ่มไม่เหมาะสม
สัญญาณที่บอกว่า ไม่เหมาะสม ก็เช่น 
พัฒนาได้ช้า  เกิด side-effect เยอะ และ deploy มีพิธีกรรมเยอะ  !!

ยกตัวอย่างสิ่งที่เห็นได้ชัดเจนก็เช่น

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

  • เรานำข้อมูล master, transactional และ analytical มาจัดเก็บไว้ที่เดียวกัน
  • สนใจเรื่องของ consistency หรือความถูกต้องของข้อมูลมากจนเกินไป (Over consistency)

คำถามคือ ปัญหานี้แก้ไขด้วยวิธีการอะไร ?

คำตอบคือ 
ก็มีการใช้งาน Store procedure ไงละ
สำหรับจัดการ process การทำงานที่ซับซ้อน

ส่วนถ้าต้องเขียน SQL การดึงข้อมูลเยอะ ๆ ก็ยัดเข้าไปใน View เลย

ส่วนถ้ามีข้อมูลเกิดขึ้นที่หนึ่ง แล้วต้องไปเพิ่มข้อมูลอีกที่หรืออีก table ก็ใช้ Trigger ไงละ  เป็นไงละ reactive ไหมละ

ซึ่งทั้งหมดนี้ทำงานอยู่ใน Database Server นั่นเอง !!
แน่นอนว่า มันเร็วมาก ๆ แต่เมื่อเวลาผ่านไป ระบบใหญ่ขึ้น Business logic เยอะขึ้น
พบว่า Database Server หรือ RDBMS (Relational Database Management System) ใหญ่
และซับซ้อนมาก (Overuse RDBMS)
คุ้นกันไหม ? กับระบบงานที่หลาย ๆ คนยังต้องดูแลกันอยู่ไหมนะ

คำถามคือ ปัญหานี้แก้ไขด้วยวิธีการอะไร ?

คำตอบคือ 
จากเดิมที่ business logic อยู่ใน Database Server ซึ่งมีปัญหา
ดังนั้นแยกออกมาดีกว่า
เอามาใส่ใน Presentation หรือ Web หรือ Business tier
ตาม Architecture แบบ N-Tier
หรืออาจจะออกแบบตามแนวคิดของ SOA (Service-Oriented Architecture)
หรือไปจนถึง Microservices

แต่ผลสุดท้ายแล้วยังเกิดปัญหาเดิม ๆ คือ
Database Server ยังไมีขนาดใหญ่
จำนวน table มากมาย
ถ้า Database Server พังไป ส่งผลกระทบให้ระบบหลัก ๆ พังหมด

สุดท้ายระบบงานก็มักเกิดปัญหา หรือ วิกฤติของการพัฒนา software (Software Crisis)

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

จากปัญหาที่เกิดขึ้น จึงมีแนวคิดต่าง ๆ ในการแก้ไขขึ้นมา

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

  • Extreme Programming (XP) เกิดจากการมองว่าปัญหาเกิดจากนักพัฒนา จึงแก้ไขที่วิธีการของนักพัฒนา ทั้ง TDD, CI, Review code และ Collective Ownership
  • Scrum เกิดจากมุมมองด้านของ Project management สำหรับการปรับปรุงขั้นตอนการทำงานขององค์กรณ์ให้เรียบง่ายมากขึ้น ด้วยการมีเพียงแค่ 3 roles เท่านั้น
  • Kanban เกิดจากมุมมองของการทำงานร่วมกัน

แต่แนวคิดและวิธีการต่าง ๆ เหล่านี้
ไม่ได้บอกหรืออธิบายการออกแบบ Architecture ของ software เลย
มีเพียงการบอกว่า Architecture ที่ดีมันจะออกมาแบบ Iterative and Incremental หรือค่อยเป็นค่อยไปตามความต้องการ หรืออาจจะเรียกว่า Emergent Design
ผลที่ได้ออกมาคือ เหมือนเดิม
ได้ระบบออกมาลักษณะเดิม แต่จัดการได้ดีขึ้น
เช่น ส่วน UI มีการทดสอบที่ดี
ส่วนของ business มีการทดสอบที่ดี
แต่ส่วนของ Database ยังไม่ขนาดใหญ่

เพราะอะไรจึงเป็นเช่นนี้ ? (Missing Pieces)

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

Image result for missing piece

เราจึงต้องการแนวทางและวิธีการในการออกแบบ Software Achitecture
ที่มีประสิทธิภาพ ไม่ over engineering เกินไป ดังที่เคยเกิดขึ้น
บ่อยครั้งมักได้ยินว่า ออกแบบอะไรมา ไม่ตรงความต้องการเลย
แต่ต้องทำตาม ทำไมนะ ?
นั่นคือ วิธีการที่ทำมานั้นไม่มีประสิทธิภาพ

หนึ่งในวิธีการที่น่าจะมีประสิทธภาพคือ DDD (Domain-Driven Design)

แต่วิธีการเดียวไม่น่าจะเพียงพอ
ดังนั้นจึงจำเป็นต้องนำเอาวิธีการต่าง ๆ มาประยุกต์ใช้งานร่วมกัน
ยกตัวอย่างเช่น

  • Architecture นำแนวคิด DDD มาใช้
  • Process การทำงาน นำแนวคิด Scrum มาใช้
  • Coding นำแนวคิด XP มาใช้
  • การทำงานร่วมกัน (Collaboration) นำแนวคิด Kanban มาใช้

ต่อจากนี้เรามาดูกันว่าแนวคิด DDD มันเป็นอย่างไรบ้าง ?

เก็บตกเรื่องการออกแบบ package สำหรับภาษา Go

$
0
0

จาก course Pratical Go ที่ไปเรียนมานั้น
มีเรื่อง Package design หรือการออกแบบหรือวาง package
ในระบบที่พัฒนาด้วยภาษา Go ว่า
มีแนวคิดและอย่างไร
ออกแบบอย่างไร
รวมทั้งหน้าที่ความรับผิดชอบ มาดูกันว่ามีอะไรบ้าง

หน่วยที่เล็กมาก ๆ ของ software น่าจะเป็นสิ่งที่เรียกว่า Unit

ซึ่งมันมีขนาดเล็ก เป็นอิสระและไม่สามารถแยกออกมาได้อีก
แต่ในการทำงานจริง ๆ นั้น
คำว่า Unit มันอาจจะมีความซับซ้อนมากมายอยู่ข้างใน
ดังนั้นบ่อยครั้งเราไม่สามารถไปดูว่า
การทำงานภายในหรือ implementation เป็นอย่างไร
เนื่องจากมีหลายสิ่งอย่าง รวมทั้งมีการเปลี่ยนแปลงอย่างสม่ำเสมอ
แต่เราสามารถดูพฤติกรรมการทำงานจากภายนอกได้ (behaviour)
ดังนั้นแนวคิดการออกแบบ package ของภาษา Go ก็เช่นกัน
นั่นคือ ให้ออกแบบ package ตามพฤติกรรมของการทำงานนั่นเอง

โดยในภาษา Go นั้นจะมองว่า

สิ่งที่เล็กสุดหรือ Unit นั้นคือ package ไม่ใช่ function/method หรือ class นะ
ดังนั้นแต่ละ package จะให้ความสนใจเพียงว่า
แต่ละ package ทำงานอะไรบ้าง มีอะไรให้ใช้บ้าง (Public APIs)
นั่นคือสนใจที่ What ไม่ใช่ How นะ
มาดูแนวคิดในการออกแบบ Package กัน

แนวคิดที่ 1 การตั้งชื่อ package ที่ดี

เริ่มด้วยเรื่องที่ยากมาก ๆ เลย
ถ้าตั้งชื่อผิดนี่เหมือนการเริ่มเดินที่ผิดพลาดมาก ๆ
ต้องตั้งชื่อที่บอกว่า package นี้
ทำอะไรได้บ้าง
มีเป้าหมายอะไรบ้าง
ไม่ได้บอกรายละเอียดข้างในนะ ข้อนี้ยากจริง ๆ

แนวคิดที่ 2 ชื่อที่ดีมันต้อง unique

นั่นคือชื่อที่พูดกออกมาแล้วรู้ทันทีว่าคืออะไร ทำงานอะไร
แต่ก็ต้องระวังชื่อ package ที่มันกว้างเกินไป
เช่น shared, client, worker เป็นต้น
ซึ่งทำให้งงว่า มันคืออะไร และทำอะไรกันแน่
หรืออาจจะมีชื่อไปทับซ้อนกับ package อื่น แบบนี้ก็ไม่ไหว
แต่ถ้าเกิดขึ้นมาก็ความแก้ไขด้วยการย้ายไปรวมกันเป็นต้น

แนวคิดที่ 3 หลีกเลี่ยงการใช้ชื่อพวก base, commom และ util

ใครบ้างที่เคยตั้งชื่อแบบนี้ ?
ยกมือขึ้น
น่าจะผ่านมือมาแล้วกันทุกคนหรือเปล่านะ !!

เป็นชื่อ package ที่แย่มาก ๆ
เพราะว่าไม่ได้ระบุแบบชัดเจนว่ามันทำอะไร
ผลที่ตามมาคือ มี code จำนวนมากอยู่ใน package เหล่านี้
และยากต่อการอธิบายอีก
ลำบากนะ
หนักไปกว่านั้น
อาจจะก่อให้เกิดการเรียกใช้งานเป็น cyclic อีกด้วย ใครเคยบ้าง ?

ดังนั้นสิ่งเหล่านี้คือ การออกแบบที่แย่และผิดพลาดมาก ๆ

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

ในภาษา Go นั้นจะแยกพวก helper หรือ util function
ไปไว้ใน package นั้น ๆ เลย
แต่ถ้ามันเยอะก็จะสร้าง package helper มาเช่น
ตัวช่วยในการจัดการ string ก็คือ package strings เป็นต้น

อีกตัวอย่างที่น่าสนใจคือ
การรวมการทำงานต่าง ๆ ไว้ใน package เดียวกัน
แต่ให้แยกเป็นไฟล์ใน package นั้น
ยกตัวอย่างเช่น package net/http จะไม่มี package ย่อย เช่น client และ server
แต่ใน package net/http จะมีไฟล์ client.go และ server.go แทน
ซึ่งแต่ละไฟล์ก็มีหน้าที่การทำงานที่แตกต่างกันไป

แนวคิดที่ 4 ในแต่ละ function ควร return ให้เร็วที่สุด

ลดความซับซ้อนของ code ลง ให้ทำการ return ให้เร็วที่สุด
เช่นทำการตรวจสอบ error ก่อน
ถ้าไม่มีก็ทำงานตาม success flow ต่อไป
ทำให้ code ไม่รกรุงรัก หรือ มีทั้งการตรวจสอบและทำงานจริง ๆ อยู่ปนกัน
ดังนั้นควรแยกการทำงานเป็นส่วน ๆ ให้ชัดเจน

เพราะว่า code ที่เราเขียนขึ้นมานั้น เป้าหมายหลัก ๆ คือ
ความชัดเจน เข้าใจง่ายและเพิ่ม productivity
ดังนั้น code มันควรเข้าใจได้ง่าย ไม่รกรุงรังนั่นเอง
หนึ่งในแนวคิดที่อ้างอิงถึงคือ Line of side in code ของคุณ Mat Ryer

แนวคิดที่ 5 ควรใช้ประโยชน์จาก Zero value

โดยคุณ Dave Cheney ได้เขียนอธิบายไว้ใน blog ชื่อว่า 
What is the zero value, and why is it useful?

แนวคิดที่ 6  หลีกเลี่ยงการจัดการ state ใน package level

หัวใจหลักของการออกแบบ software ที่ดูแลจัดการได้ง่าย
คือการออกแบบ loose coupling
หรือทำให้แต่ละส่วนไม่ผูกมัดกันมากหรือให้น้อยสุด ๆ
ในภาษา Go ก็คือ ถ้าเกิดการเปลี่ยนแปลงใน package หนึ่ง ๆ แล้ว
ต้องไม่กระทบกับส่วนการทำงานที่อื่นหรือ package อื่น ๆ

สามารถทำได้ 2 วิธีการคึอ

  • ใช้ interface ในการอธิบายพฤติกรรมการทำงานของ package
  • ลดหรือหลีกเลี่ยงการใช้ Global state หรือ package level ลง

ต่อไปจะมาดูเรื่อง project structure กัน

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

Flutter สามารถ run บน Web browser ได้แล้ว

$
0
0



https://developers.googleblog.com/2019/05/Flutter-io19.html

จากงาน Google IO 2019 นั้นทางฝั่งของ project Flutter ก็ออก feature มาขายด้วย
นั่นก็คือ

มันทำให้เราสามารถพัฒนาระบบด้วย Flutter ซึ่งเขียนด้วยภาษา Dart นั้น
ไป run บน platform ต่าง ๆ ได้เลย
ทั้ง Mobile (Android และ iOS), web browser, embedded device และ desktop มันคือ Multi-platform นั่นเอง 
เขียน code ชุดเดียวได้ครบเลย (ไม่ทุกเรื่องนะ)

แต่ตัวที่ผมสนใจคือ Flutter for Web 

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

มันคือความพยายามที่จะทำการ implement ส่วนการ render

ด้วย web technology ทั้ง HTML, CSS และ JavaScript
นั่นหมายความว่า เราสามารถเขียน code ด้วยภาษา Dart และ library/dependency เหมือนเดิม
แต่ flutter จะทำการ compile ไปตามเป้าหมายที่ต้องการ
ที่สำคัญไม่ต้องทำการติดตั้ง plugin ใด ๆ บน web browser เพื่อใช้งานอีกด้วย

โดย project นี้อยู่ในช่วง Technical Preview เท่านั้นเอง

นั่นคือเป็นการลองทำขึ้นมา เพื่อ proof-of-concept
ด้วยการ fork code ของ Flutter มาพัฒนาต่อยอด
อยู่ที่ GitHub:: Flutter Web

มีโครงสร้างดังรูป

เนื่องจากเป็นเพียงการเริ่มต้นเท่านั้น
ดังนั้นพวก library ต่าง ๆ ไม่ได้ถูกเพิ่มเข้ามาใน Flutter เลย
เรื่อง performance ไม่ต้องพูดถึง
รวมทั้งเรื่อง workflow การทำงานต่าง ๆ จะอยู่บน Chrome เท่านั้น

มาลองเล่นกันหน่อย

ทำการ clone หรือ download มาจาก GitHub:: Flutter Web
จากนั้นลอง build ดูได้เลยดังนี้

ทำการติดตั้ง web dev package ก่อนเลย

[code] $flutter packages pub global activate webdev [/code]

ทำการ build ให้ครบ

[code] $git clone https://github.com/flutter/flutter_web.git $cd flutter_web $cd examples/hello_world/ $flutter packages upgrade $pub get [/code]

ถ้าผ่านแล้วก็ทำการ run web server ด้วยคำสั่ง

[code] $webdev serve [INFO] Serving `web` on http://localhost:8080 [INFO] Running build completed, took 13.6s [INFO] Caching finalized dependency graph completed, took 131ms [INFO] Succeeded after 13.7s with 548 outputs (3169 actions) [/code]

ลองเปิด http://localhost:8080  ที่ Web Browser  
จะแสดงผลดังนี้


ปล. ไม่สนับสนุน IE นะเออ
ลองดูครับ ถ้าเอาไปรวมกับ Flutter แล้วน่าจะสนใจมากขึ้น

เรื่อง Project structure ของระบบที่พัฒนาด้วยภาษา Go

$
0
0

จาก course Practical Go นั้นหนึ่งในเรื่องที่น่าสนใจอีกแล้ว
คือ Project structure นั่นเอง
เนื่องจากเป็นเรื่องที่มีการพูดคุยใน community เยอะมาก ๆ
ที่สำคัญมีหลากหลายแนวทางมาก ๆ อยู่ที่ว่าใครจะมองและวางออกมา
มาดูว่า มีคำแนะนำอะไรดี ๆ กันบ้าง

ปล. สิ่งสำคัญมาก ๆ ที่ได้เข้าใจมากขึ้นคือ  ความเข้าใจของคนในทีมนั่นเอง

หลังจากที่อธิบายเรื่องของการออกแบบ package ไปแล้ว
แต่ระบบงานของเราจะมี package จำนวนมากทำงานร่วมกัน ซึ่ง code มักจะอยู่ใน repository เดียวกัน

ปล. ในอนาคต community ของ Go นั้น
นักพัฒนาอาจจะพูดคำว่า module หรือ project ก็ได้
ซึ่งมีความหมายเดียวกัน จากการมาของ Go module นั่นเอง

สิ่งหนึ่งที่ยังจำได้คือ

การออกแบบ package นั้นจะต้องมีชื่และหน้าที่รับผิดชอบที่ชัดเจน
มาถึง project ก็เช่นกัน ควรมีหน้าที่ชัดเจน ควรมีเป้าหมายชัดเจน
ยกตัวอย่างเช่น project ที่สร้างเป็น library
ก็ต้องระบุให้ชัดเจนว่า library นั้นทำอะไร เช่น json parser, logging เป็นต้น

แน่นอนว่า ต้องระวังเรื่องการทำงานหลาย ๆ เรื่องใน library เดียวกัน
อาจจะทำให้เกิด common library ขึ้นมาอีกก็เป็นได้ !!
ก่อให้เกิดปัญหามากมาย ทั้งการผูกมัดที่มากเกินไป
ทั้งผลกระทบจากการแก้ไขอีกต่างหาก

ต่อมาคือเรื่องของจำนวน package

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

อีกอย่างหนึ่งในภาษา Go
จะมี visibility เพียง public และ private เท่านั้น
ต่างจากภาษาอื่น ๆ เช่น Java มีทั้ง public, protected, default และ private
ดังนั้นถ้ามี package จำนวนมาก ๆ
อาจจะก่อให้เกิดปัญหาในการจัดการก็เป็นไปได้

คำถามที่น่าสนใจคือ แล้ว project เราควรมีโครงสร้างอย่างไรบ้าง ?

จากใน course แนะนำไว้ดังนี้ ในแต่ละ package ใน project นั้น
ให้เริ่มจากไฟล์เดียวที่ชื่อเหมือนกับ package
เช่น http package จะมีไฟล์ชื่อว่า http.go
ถ้า package มีการทำงานมากขึ้น
ให้ทำการสร้างไฟล์ตามหน้าที่ความรับผิดชอบ เช่น

  • message.go สำหรับโครงสร้างข้อมูลของ request และ response
  • client.go สำหรับการทำงานฝั่ง client
  • server.go สำหรับการทำงานฝั่ง server

สิ่งที่เพิ่งรู้คือ

การ compile ของภาษา Go นั้น จะทำการ compile แบบ parallel กัน
ไปตามแต่ละ package นั่นหมายความว่า
ถ้าเราทำงาน refactor ใน package เดียวกันแล้ว
ผลที่ได้คือ ไม่ได้ช่วยให้ compile เร็วขึ้นนะ

และอีกอย่างคือ package net/http นั้น ไม่ได้เป็น sub-package ของ net package
มันคนละ package กันนะ
เป็นเรื่องที่ต่างจากภาษาอื่น ๆ เช่น java และ c# 

มีคำแนะนำในการใช้งาน package ใน project ไว้ดังนี้

  • cmd สำหรับเก็บ package main
  • internal สำหรับลด scope ของ public API ใน package หนึ่ง ๆ ให้ใช้ได้จาก base package เท่านั้น ไม่สามารถใช้ได้จาก package อื่น ๆ ซึ่งตรงนี้ทำให้จัดการ scope ของ package ได้ดียิ่งขึ้น

อีกสิ่งหนึ่งที่แนะนำอย่างแรงคือ package main ให้เล็กที่สุด

ใน package นี้คือ จุดเริ่มต้นของการทำงาน ทำงานเพียงครั้งเดียว
ดังนั้นมี code เท่าที่จำเป็นก็พอ เช่น

  • การ parsing parameter ต่าง ๆ
  • การ initial ข้อมูลจากไฟล์
  • การ initial logger
  • การสร้าง connection ไปยัง database

จากคำแนะนำต่าง ๆ ก็พบว่ามี project ตัวอย่างที่น่าสนใจตัวหนึ่งคือ

Starter code for writing web service in Go
น่าจะใช้เป็นตัวอย่างและแนวทางในการออกแบบได้เลย


GitHub เปิด Package registry ให้ใช้แล้ว [beta version]

$
0
0

https://techcrunch.com/2019/05/10/github-gets-a-package-registry/

เห็นทาง GitHub เปิดให้ลองใช้งาน Package registry ใน beta version
เป็น package management service เหมือนกับพวก
npm, maven, grade, RubyGems นั่นเอง
ทำให้นักพัฒนาสามารถ publish package ต่าง ๆ
ที่อยู่ใน GitHub ผ่าน Web hook ได้แบบง่าย ๆ
ที่สำคัญคือ compatible กับ package management เจ้าอื่น ๆ ด้วย
มาลองใช้งานกันดู

เริ่มต้นด้วยไปที่ Package registry 

เพื่อทำการสมัครใช้บริการนี้

จากที่ดูใน web นั้นจะสนับสนุน

  • npm
  • Docker
  • Apache Maven
  • NuGet
  • RubyGems

จากข่าวที่ประกาศออกมา จะเพิ่มตัวอื่น ๆ เข้ามาเรื่อย ๆ

https://techcrunch.com/2019/05/10/github-gets-a-package-registry/

ทำการขอเข้าใช้งาน แน่นอนว่า ก็รอ Waiting list กันไป !!

แต่ขณะที่รอก็ไปอ่านเอกสารเพิ่มเติมก่อนได้

https://help.github.com/en/articles/about-github-package-registry

Service นี้มีความน่าสนใจมาก ๆ
ที่เดียวครบทุกอย่างเลย (One Stop Service)

Viewing all 1997 articles
Browse latest View live