<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: PRODIGY9</title>
    <description>The latest articles on DEV Community by PRODIGY9 (@prodigy9).</description>
    <link>https://dev.to/prodigy9</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F3839%2F4a648ff8-ab48-420c-ad42-7fc1c09ea91d.png</url>
      <title>DEV Community: PRODIGY9</title>
      <link>https://dev.to/prodigy9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prodigy9"/>
    <language>en</language>
    <item>
      <title>จะทำยังไงดีน้าาาา.. อยากแก้คำผิดใน commit message ที่ผ่านๆ มา</title>
      <dc:creator>Gatuk S. Chattanon</dc:creator>
      <pubDate>Sat, 02 Oct 2021 09:20:20 +0000</pubDate>
      <link>https://dev.to/prodigy9/commit-message-5b2m</link>
      <guid>https://dev.to/prodigy9/commit-message-5b2m</guid>
      <description>&lt;p&gt;เคยไหม... ในวันที่เราต้องแก้โค้ดอะไรสักอย่างหนึ่งในวันที่เร่งรีบ แล้วเผลอ commit message อย่างรัว จนทำให้พิมพ์อะไรผิดไปสักอย่างหนึ่ง&lt;/p&gt;

&lt;p&gt;เคยไหม... ในวันที่เรามีไฟสุดๆ ตื่นเช้ามาเขียนโค้ด แล้ว commit code อย่างรัว ยังกับตัวเองเป็น hacker ยังไงยังงั้น แต่กลับมาเจอว่า แย่แล้ว! เราเขียน commit message หลายอันผิดไป!&lt;/p&gt;

&lt;p&gt;หลายคนอาจจะเคย และหลายคนอาจจะไม่เคย แต่ถ้าหากเคยเป็น เราก็มี choice แค่ไม่กี่อย่าง นั่นก็คือ ทิ้งมันไว้ตรงนั้นแหละ 🥲 กับอีกอย่างคือ ขอกลับไปแก้หน่อยน่าา 🤔&lt;/p&gt;

&lt;p&gt;ถ้าหากเราเลือก choice "ขอกลับไปแก้หน่อยน่าา" นั่นแปลว่า blog นี้จะเป็นประโยชน์กับทุกคนที่ผ่านมาอ่านแน่ๆ 555 (เราเชื่อว่าแบบนั้น 😌)&lt;/p&gt;

&lt;p&gt;ดังนั้น เราจะพาทุกคนไปทำความรู้จักกับ git interactive rebase mode สำหรับการแก้ไข commit message หลายๆ อันในอดีต&lt;/p&gt;

&lt;p&gt;เราขอสมมติเหตุการณ์ กันเลยดีกว่า สมมติว่าเราสร้าง branch ใหม่ขึ้นมาชื่อว่า branch &lt;code&gt;feature/user_login&lt;/code&gt; ไว้สำหรับการ login ของ user เข้าสู่ระบบ ซึ่งแน่นอนว่า การ login นั้น จะมี task หลายๆ task เกิดขึ้นมา โดยเราจะขอ commit 1 ครั้งเมื่อ task 1 task เสร็จเรียบร้อย และใช้งานได้ โดย commit message ที่เกิดขึ้น จะมี 4 อัน ดังนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commit ff6c9f5ac37d77bbe084a7f8cc0d5a34c96d89e4 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; feature/login_user&lt;span class="o"&gt;)&lt;/span&gt;
Author: Gatuk Chattanon &amp;lt;gatukgl@gmail.com&amp;gt;
Date:   Sat Oct 2 15:35:33 2021 +0700

    Login user to system when user is valid

commit b9c3458ff62d400f54005927c832cee063a3d682
Author: Gatuk Chattanon &amp;lt;gatukgl@gmail.com&amp;gt;
Date:   Sat Oct 2 15:35:16 2021 +0700

    Validate psw

commit c6cda7e462eba06b65fac5d5e176f10a06652eed
Author: Gatuk Chattanon &amp;lt;gatukgl@gmail.com&amp;gt;
Date:   Sat Oct 2 15:34:53 2021 +0700

    Validate email

commit d519a517e3c8b2967ffae6155f906ccea95af7fb
Author: Gatuk Chattanon &amp;lt;gatukgl@gmail.com&amp;gt;
Date:   Sat Oct 2 15:34:07 2021 +0700

    crate login form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จะเห็นได้ว่า ด้วยความรีบหรืออะไรก็ตาม ทำให้เราพิมพ์ commit message ผิดๆ ถูกๆ เห็นแล้วขัดใจเพื่อนร่วมทีมแน่ๆ review โค้ดกันที หรือกลับมาอ่าน commit อีกทีทีหลัง น่าจะปวดใจมากๆ เพราะฉะนั้นเรามาลองแก้ไขให้ถูกกัน โดยใช้ git interactive rebase นั่นเองจ้า!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~&amp;lt;number_of_commits&amp;gt; 
// หรือ
&lt;span class="nv"&gt;$ &lt;/span&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; @~&amp;lt;number_of_commits&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ซึ่ง &lt;code&gt;number_of_commits&lt;/code&gt; ด้านบนนั้น หมายถึง จำนวน commit message ที่เราต้องการจะย้อนไปเริ่มแก้ไข โดยใน branch &lt;code&gt;feature/login_user&lt;/code&gt; นั้น เราได้สร้าง commit message ขึ้นมาทั้งหมด 4 อัน และอยากจะย้อนกลับไปแก้ไข ตั้งแต่ commit เริ่มต้นเลย ซึ่งก็ย้อนไป 4 อันนั่นเอง เพราะฉะนั้นเราจะต้องใช้ command ด้านล่างนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; @~4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หลังจากนั้น ก็ต้องใช้ทักษะ ความเชี่ยวชาญชำนาญด้าน vim เล็กน้อย ถึงปานกลาง 5555 เพราะว่าเมื่อเข้าสู่ interactive mode น้อง terminal ก็จะเปิด vim editor ขึ้นมาให้เรานั่นเองเป็นอัตโนมัติ ซึ่งก็จะมี commit message ต่างๆ เหล่านี้ขึ้นมา (อันนี้ใครที่ไม่ค่อยถนัดใช้ vim เรามีวิธีการเปลี่ยนให้ terminal ไปเปิด editor ตัวอื่นได้เช่นกันค่ะ &lt;a href="https://stackoverflow.com/a/3539630" rel="noopener noreferrer"&gt;อ่านวิธีได้ที่นี่&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pick d519a51 crate login form
pick c6cda7e Validate email
pick b9c3458 Validate psw
pick ff6c9f5 Login user to system when user is valid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ส่วนด่วนล่าง commit ที่เราเลือกมา 4 อันนั้น เป็นคำอธิบายการใช้ command ต่างๆ ซึ่งที่เราจะเลือกหยิบมาใช้ใน blog นี้นั้น ก็คือ &lt;code&gt;reword&lt;/code&gt; นั่นเองค่ะ ซึ่งเป็นการ edit commit message &lt;/p&gt;

&lt;p&gt;โดยดูจาก commit message แล้วเนี่ย... มี commit ที่เราอยากจะแก้อยู่ 2 อัน นั่นก็คือ &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;d519a51 crate login form&lt;/code&gt; อยากจะแก้ให้เป็น &lt;code&gt;Create login form&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b9c3458 Validate psw&lt;/code&gt; อยากจะแก้ให้เป็น &lt;code&gt;Validate password&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ทำได้โดยการนำ &lt;code&gt;reword&lt;/code&gt; ไปไว้ด้านหน้า commit message ที่เราอยากจะแก้ไข แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;reword d519a51 crate login form
pick c6cda7e Validate email
reword b9c3458 Validate psw
pick ff6c9f5 Login user to system when user is valid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หลังจากนั้นให้ save &amp;amp; quit ออกจาก vim editor หลังจากนั้นเราจะเห็นว่า terminal ของเราได้เปิด vim editor หน้าใหม่ขึ้นมาให้เราโดยอัตโนมัติ ให้เราแก้ commit message นั่นเองจ้า ทีนี้ ก็แก้ไขแล้วก็กด save &amp;amp; quit ออกมาทีละ message จนครบทุก commit ที่เราเลือก เพียงเท่านี้ ก็ได้ commit message ใหม่ ไฉไลกว่าเดิม&lt;/p&gt;

&lt;p&gt;หากใครยัง งงๆ อยู่ นั้นเราจะขออัดเป็น gif สั้นๆ ให้ดูกันละกันนะคะ ^^ (ขออภัย รูปเล็กไปนิดนึง)&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia0.giphy.com%2Fmedia%2FRt9gQmSNtwRo9CZgdj%2Fgiphy.gif%3Fcid%3D790b7611af1c924f6af0ff9a9f6810140a20f1dc93b8c769%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia0.giphy.com%2Fmedia%2FRt9gQmSNtwRo9CZgdj%2Fgiphy.gif%3Fcid%3D790b7611af1c924f6af0ff9a9f6810140a20f1dc93b8c769%26rid%3Dgiphy.gif%26ct%3Dg" alt="git interactive rebase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เราขอบอกก่อนว่า ถ้าเกิดใครที่รู้ตัวทัน อยากจะแก้ไขแค่เฉพาะ 1 commit ก่อนหน้าเพียงแค่อันเดียว ไม่จำเป็นต้องใช้ interactive rebase mode ก็ได้ค่ะ เพราะว่าเราสามารถกลับสู่สามัญ แล้วไปใช้ &lt;code&gt;amend&lt;/code&gt; ได้ ตัวอย่างเช่นด้านล่างนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;--amend&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'new commit message'&lt;/span&gt;

// หรือ

&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;--amend&lt;/span&gt;  // อันนี้จะไปเปิด vim editor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History" rel="noopener noreferrer"&gt;https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>rebase</category>
      <category>amend</category>
      <category>commit</category>
    </item>
    <item>
      <title>มารู้จักกับ Clean Architecture กันดีกว่า!</title>
      <dc:creator>Gatuk S. Chattanon</dc:creator>
      <pubDate>Sun, 15 Aug 2021 10:21:35 +0000</pubDate>
      <link>https://dev.to/prodigy9/clean-architecture-1o9p</link>
      <guid>https://dev.to/prodigy9/clean-architecture-1o9p</guid>
      <description>&lt;p&gt;⭐️ วันนี้เราจะพาทุกคนมารู้จักกับ Clean Architecture นั้น ที่เป็น 1 article ของ Robert C. Martin หรือว่า Uncle Bob กันค่ะ!&lt;/p&gt;

&lt;h3&gt;
  
  
  Clean Architecture คืออะไรกันนะ?
&lt;/h3&gt;

&lt;p&gt;อย่างที่บอกไปข้างบนก่อนหน้าที่เราจะมารู้จัก Clean architecture มากขึ้นใน section นี้.. Clean Architectuกre ถูกเขียนขึ้นในบทความหนึ่งของ Robert C. Martin ซึ่งเป็นผู้ที่เรียกได้ว่าเป็นผู้ที่มีอิทธิพลในเรื่องของการเขียนโค้ดที่ดี หรือที่เค้าเรียกว่าเขียนโค้ดให้ clean นั่นเอง บทความนี้ชื่อว่า "The Clean Architecture" ถูก publish มาตั้งแต่ปี  2012 (เกือบจะ 10 ปีแล้ว)&lt;br&gt;
.&lt;br&gt;
จุดประสงค์ของการใช้ Clean Architecture จะช่วยให้เราสามารถแยก layer ของโค้ด โดยในแต่ละ layer ก็จะทำงานของตัวเองอย่างชัดเจนไปเลย หรือที่เราเรียกว่า  separation of concern นั่นเอง&lt;/p&gt;

&lt;h3&gt;
  
  
  ทำไมเราถึงมาใช้ Clean Architecture ล่ะ?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7l3ny4mcarfe54f1mug.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7l3ny4mcarfe54f1mug.jpg" alt="Photo by Jeremiah Lawrence on Unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;อย่างแรก คือ &lt;strong&gt;"Independent of Frameworks"&lt;/strong&gt; หมายความว่า โค้ดที่เราเขียนจะไม่ผูกติดอยู่กับ framework ไปทุกส่วนของโค้ด ในวันไหนที่เราอยากจะเปลี่ยนไปใช้ framework อื่นๆ จะได้ปรับเปลี่ยนได้อย่างง่ายขึ้น&lt;br&gt;
.&lt;br&gt;
อย่างที่สอง ได้แก่ &lt;strong&gt;"Testable"&lt;/strong&gt; หมายถึง เราจะสามารถ test code ของเราง่ายขึ้น ตัวอย่างเพื่อให้เห็นภาพมากขึ้น คือ การแยกส่วนของ business logic ออกจากส่วนอื่นๆ เช่น UI หรือ database เวลาที่เราเขียน test ส่วนของ business logic ก็จะง่ายขึ้น เพราะไม่ต้องสนใจเรื่อง UI ว่าจะต้อง render อย่างไร หรือว่าจะต้องไปต่อกับ database ตัวไหน เป็นต้น&lt;br&gt;
.&lt;br&gt;
อย่างที่สาม คือ &lt;strong&gt;"Independent of UI"&lt;/strong&gt; เมื่อเราแยกส่วนของ UI ออกจาก business logic แล้ว สิ่งที่ง่ายขึ้นก็คือ เราสามารถเปลี่ยนแปลง UI ได้โดยไม่ต้องกังวลว่า business logic จะพังทลายไปด้วยหรือเปล่า&lt;br&gt;
.&lt;br&gt;
อย่างที่สี่ คือ &lt;strong&gt;"Independent of Database"&lt;/strong&gt; เป็นการแยกส่วนที่ติดต่อกับ database ออกมา สมมติเหตุการณ์สักหน่อย ก็คงจะนึกถึง case ของ เวลาเราสร้าง project ขึ้นมาใหม่ เราใช้ database sqlite แต่นานวันเข้า sqlite ไม่ตอบโจทย์ของการใช้งานของ user จริงๆ บน production เราจะต้องเปลี่ยน database ไปใช้ Oracle แทน เราก็สามารถทำได้ง่าย เพราะเราได้แยก layer ไว้อยู่ที่ layer เดียวแล้ว&lt;br&gt;
.&lt;br&gt;
อย่างสุดท้าย คือ &lt;strong&gt;"Independent of any external agency"&lt;/strong&gt; หมายถึง business logic ต่างๆ จะไม่รู้ว่าเกิดอะไรขึ้นภายในโค้ดที่ business logic สนใจเลยยย&lt;br&gt;
.&lt;br&gt;
โดยเหตุผลเหล่านี้ ก็ถูกเขียนอยู่ในบทความ The Clean Architecture ด้วยเช่นกัน ใครอยากอ่าน version ต้นฉบับ ก็สามารถเข้าไปตามอ่านกันได้ &lt;a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html" rel="noopener noreferrer"&gt;ที่นี่&lt;/a&gt; เลยจ้า&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dependency Rule ของ Clean Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xceggxkl51o6kbnrwr0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xceggxkl51o6kbnrwr0.jpg" alt="The Clean Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากภาพข้างบน เราจะเห็นได้ว่า แต่ละวงกลมจะสื่อถึง layer ต่างๆ เวลาที่เราทำ software ใดๆ ก็ตาม โดยวงกลมที่อยู่ด้านนอกๆ จะสื่อถึง layer ที่สูงๆ ซึ่งโดยทั่วไปก็จะเป็นส่วนที่ติดต่อกับคนที่ใช้งาน ส่วนวงกลมที่อยู่ด้านในๆ ก็จะเป็นส่วนที่ low level มากๆ อย่างเช่น ส่วนที่ติดต่อกับ database เป็นต้น&lt;br&gt;
.&lt;br&gt;
เรามาทำความรู้จักมากขึ้นกับวงกลมแต่ละ layer ให้มากขึ้นกันดีกว่า 🎉&lt;/p&gt;

&lt;h4&gt;
  
  
  Entities
&lt;/h4&gt;

&lt;p&gt;ส่วนนี้เป็นส่วนที่ติดต่อกับ Enterprise Business Rules ซึ่งโค้ดที่เกิดขึ้นใน layer นี้ อาจจะเป็น model ที่เก็บ data structure ของข้อมูลในองค์กรของเราก็ได้ โดยส่วนนี้จะมีการเปลี่ยนแปลง และกระทบน้อยที่สุด เนื่องจากเป็นชั้นด้านในที่สุดเลย เช่น ถ้าหากเราเปลี่ยนแปลง UI จาก design แบบหนึ่ง ไปเป็นอีกแบบหนึ่ง ก็จะมีโอกาสน้อยมากที่ structure ของ data ของเราจะเปลี่ยนแปลงไปตาม&lt;/p&gt;

&lt;h4&gt;
  
  
  Use Cases
&lt;/h4&gt;

&lt;p&gt;ส่วนนี้จะเป็นส่วนที่มี Application Business Rules อยู่ ซึ่งโค้ดใน use case เหล่านี้ก็จะเป็นส่วนที่ควบคุมว่าจะมี data อะไรที่จะนำออกจาก.. หรือนำเข้าไป entities บ้าง โดยที่จะทำให้ได้ผลลัพธ์อย่างที่โปรแกรมของเราต้องการ&lt;/p&gt;

&lt;h4&gt;
  
  
  Interface Adapters
&lt;/h4&gt;

&lt;p&gt;ส่วนนี้จะประกอบไปด้วยส่วนที่เอาไว้ใช้ convert data จาก format ใดๆ ก็ตาม ให้เป็น format ที่ application ของเราเข้าใจและใช้ได้ง่าย เช่นการแปลงจาก json format ให้เป็น object ที่เราต้องการ เราจะเรียกสิ่งที่ทำหน้าที่เหล่านี้ว่า Adapter ซึ่ง Adapter ถ้าแปลเป็นไทยก็คือ "ตัวแปลง" นั่นเอง&lt;/p&gt;

&lt;h4&gt;
  
  
  Frameworks and Drivers
&lt;/h4&gt;

&lt;p&gt;เป็นส่วนที่จัดการกับ framework ที่เราใช้ในโปรเจกต์ ในส่วนนี้เราอาจจะไม่ได้เขียนโค้ดมาก แต่ก็เป็นส่วนที่สำคัญ เพราะเราเอาไว้ใช้ ติดต่อกับ framework ต่างๆ ที่เราใช้ เช่น การเขียนโค้ดเพื่อสร้าง database connection เป็นต้น&lt;br&gt;
.&lt;/p&gt;

&lt;p&gt;และนี่ก็คือ..​. แทบจะเป็นทฤษฎีของ The Clean Architect ที่เราลองเขียนสรุปตามความเข้าใจของเรามาให้ทุกคนได้ลองรู้จักกับสิ่งนี้ เพื่อให้การเขียนโค้ดของเราดีขึ้นนะคะ และจริงๆ แล้ว ถ้าจะเล่าให้ฟังให้เห็นภาพมากขึ้น เราน่าจะต้องทำความเข้าใจในการ apply ด้วยว่าถ้าจะเอา Clean Architecture ไปใช้งานจริงๆ แล้วเราจะทำยังไงกันนะ...&lt;br&gt;
.&lt;br&gt;
ซึ่งเราขอ spoil ตอนต่อไปเลยละกันว่า..​ เราจะพาทุกคนไปทำความคุ้นเคยมากขึ้น ว่าถ้าเกิดเอาไปใช้กับโปรเจกต์ที่เขียนด้วย golang ล่ะ มันทำยังไงกัน! เพราะฉะนั้นติดตามตอนต่อไปได้เลยจ้าาาา 😎&lt;/p&gt;

&lt;h3&gt;
  
  
  Reference
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html" rel="noopener noreferrer"&gt;https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cleanarchitecture</category>
      <category>go</category>
      <category>designpattern</category>
      <category>unclebob</category>
    </item>
    <item>
      <title>Comparing Boolean Expression to True</title>
      <dc:creator>Chakrit Wichian</dc:creator>
      <pubDate>Wed, 17 Mar 2021 17:47:19 +0000</pubDate>
      <link>https://dev.to/prodigy9/comparing-boolean-expression-to-true-357d</link>
      <guid>https://dev.to/prodigy9/comparing-boolean-expression-to-true-357d</guid>
      <description>&lt;p&gt;This has to be the oldest trick in the book in the sense that only really early beginner make these mistakes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Instead of
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_valid?&lt;/span&gt;
    &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt;
    &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Do this
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_valid?&lt;/span&gt;
    &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Boolean expressions eventually resolve to either &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;. Comparing them again to &lt;code&gt;true&lt;/code&gt; wastes computation and adds extra cognitive load without actually adding to the readability or explicitlness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not?
&lt;/h2&gt;

&lt;p&gt;Sometimes you don't always have a binary &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; values. For example, you can have &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt; values in other languages. In which case, comparing them to &lt;code&gt;true&lt;/code&gt; do have a use because you want to avoid the other two (or three) possibility of the value not existing, or the value being &lt;code&gt;false&lt;/code&gt; at the same time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                  &lt;span class="c1"&gt;// default options `{}`&lt;/span&gt;
&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;    &lt;span class="c1"&gt;// explicit options&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;htmlEscape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may, however, confuses the reader because the absence of value is implicit in this context. Calling out implicitness usually improves readability but reduce succintness and adds conginitive load. So depending on your situation, shorter may be better or explicit may be better.&lt;/p&gt;

&lt;p&gt;One way to make this explicit is to split apart the two concerns in the code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checking for absence of value&lt;/li&gt;
&lt;li&gt;Checking for the value itself&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;htmlEscape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code calls out to the reader to be on the lookout for the absence of values in the &lt;code&gt;options&lt;/code&gt; hash. That not all options maybe passed into the function.&lt;/p&gt;

&lt;p&gt;Alternatively, we can eliminate 1) entirely by supplying defaults:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// now we are sure the 'escape` option will always be specified&lt;/span&gt;
  &lt;span class="c1"&gt;// our check is now straightforward&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;htmlEscape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An experienced coder will also notice that the pattern of "applying defaults" can be made more generic and applied uniformly throughout the codebase. This is exactly the usecase of &lt;a href="https://www.geeksforgeeks.org/lodash-_-defaults-method/"&gt;lodash's _.defaults() method&lt;/a&gt; which we can use to make the code more succinct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// eliminate any "absence of value" cases&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;htmlEscape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can avoid Lodash entirely and use null-coalescing operator &lt;code&gt;??&lt;/code&gt; if your language supports them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;htmlEscape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>style</category>
      <category>codequality</category>
    </item>
    <item>
      <title>[WIP] Write Better Code</title>
      <dc:creator>Chakrit Wichian</dc:creator>
      <pubDate>Wed, 17 Mar 2021 17:46:37 +0000</pubDate>
      <link>https://dev.to/prodigy9/write-better-code-3fgc</link>
      <guid>https://dev.to/prodigy9/write-better-code-3fgc</guid>
      <description>&lt;p&gt;This series is meant to be a collection of tips, tricks and techniques for writing a more readable and maintainable code. The content will &lt;strong&gt;focus exclusively on the style&lt;/strong&gt; and other subjective elements of code writing. There are already many other content on the web that talk about the semantics and how a piece of code or an algorithm "works". We focus, here, instead on how the code "reads".&lt;/p&gt;

&lt;p&gt;That being said, this does not mean we will forego the concern of making sure the code work entirely. We believe, rather, that correctly working code are a result of not only it having correct semantics, but also &lt;strong&gt;because the programmer writing/maintaining it can reason about it easily&lt;/strong&gt; because the code was written with such high readability standards.&lt;/p&gt;

&lt;p&gt;In other words, we believe making the code more readable makes it more correct as well.&lt;/p&gt;

&lt;p&gt;The content are purely derived from my own personal experience writing, reading and debugging unbelievable number of lines of code over 20+ years. Contributions are, of course, welcome and if this proves to be useful to many people, I'd be happy to open source and license it.&lt;/p&gt;

&lt;p&gt;Some of the content found here may feels familiar to readers of coding style books, but, again, I'd like to emphasize that this is distilled from my personal experience only and not summarized from any book. It also have no set plans or publishing schedule, I'll add to it as I have time and feel like I have something useful to contribute. Other times, it may stay static for months or years.&lt;/p&gt;

&lt;p&gt;I do believe, however, that there is an ultimate answer to all code styling issues. I believe that after a certain point in the career of programming and software development, most of us eventually come to the same or similar realization/conclusion. So it should be of no coincidence that some concepts found here may have already been explained in some book or some blog post somewhere on the interwebs. In which case , I'll add links and references to the relevant pages.&lt;/p&gt;

</description>
      <category>style</category>
      <category>codequality</category>
    </item>
  </channel>
</rss>
