<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Teamwork｜林鼎淵 Dean Lin</title>
    <link>https://deanlin.net/tags/teamwork/</link>
    <image><url>https://deanlin.net/images/author_hu_aa256fc934e9a932.jpg</url><title>Teamwork｜林鼎淵 Dean Lin</title><link>https://deanlin.net/tags/teamwork/</link><width>144</width><height>144</height></image>
    <description>林鼎淵（Dean Lin）的部落格：生成式 AI 企業內訓講師、外商資安公司軟體專家、7 本書作者。400 多篇文章用白話分享生成式 AI 實戰、Claude Code 與 Vibe Coding 教學、團隊合作與職場成長。</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <copyright>© 2020–2026 林鼎淵 Dean Lin</copyright>
    <lastBuildDate>Sat, 11 May 2024 10:32:39 +0800</lastBuildDate>
    <atom:link href="https://deanlin.net/tags/teamwork/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>[Gitlab] 建立 Merge Request Templates，讓團隊合作更加順利！</title>
      <link>https://deanlin.net/blog/202405/gitlab-merge-request-templates/</link>
      <pubDate>Sat, 11 May 2024 10:32:39 +0800</pubDate>
      <guid>https://deanlin.net/blog/202405/gitlab-merge-request-templates/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>團隊合作</category>
      <description>在多人協作的開發過程中，我們通常會需要透過 Merge Request 來進行 Code Review。 但這時會遇到一個問題：「每個人對專案的認知有差異，且文字表達能力不同。」 這會導致 Code Review 的人需要花更多的時間來理解程式，甚至浪費寶貴的時間在溝通上。</description>
      <media:content url="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-og_hu_d992785d9459a49.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>在多人協作的開發過程中，我們通常會需要透過 Merge Request 來進行 Code Review。</p>
<p>但這時會遇到一個問題：「每個人對專案的認知有差異，且文字表達能力不同。」</p>
<p>這會導致 Code Review 的人需要花更多的時間來理解程式，甚至浪費寶貴的時間在溝通上；有些交代不清楚的 Merge Request 如果被合併了，也容易在未來發現 Bug 時難以釐清問題。</p>
<p>而解決上面問題的方式也很簡單：「建立 Template（模板）」</p>
<p>如果大家都按照模板撰寫，就能保證每個 MR 都有一定的品質。</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-01.webp" width="1147" height="645" alt="\[Gitlab\] 建立 Merge Request Templates，讓團隊合作更加順利！（圖 1）" fetchpriority="high" decoding="async"></p>
<h2 id="merge-request-要有哪些資訊">Merge Request 要有哪些資訊？<a class="h-anchor" href="#merge-request-%e8%a6%81%e6%9c%89%e5%93%aa%e4%ba%9b%e8%b3%87%e8%a8%8a" aria-label="這個段落的連結"></a></h2>
<p>筆者個人建議一個好的 Merge Request 要包含以下元素：</p>
<ol>
<li><strong>概要 &amp; 背景</strong>：簡短描述這次 Merge Request 的目的，讓 Code Review 的人可以快速理解前因後果。</li>
<li><strong>相關資訊</strong>：放上專案需求規格連結、關聯的 Project/branch、會議紀錄等資訊。</li>
<li><strong>變更內容</strong>：說明新增/修改/移除了什麼內容，如果邏輯複雜可以簡述演算法。</li>
<li><strong>測試步驟</strong>：描述如何驗證這次的變更，包括需要運行的測試和預期結果。</li>
</ol>
<p>大家可以參考我的 Merge Request Template 格式（Markdown 語法）：</p>
<pre tabindex="0"><code># 概要 &amp; 背景

# 相關資訊

- 需求規格: 
- 關聯的 Project/branch: 
- 任務 Ticket/會議紀錄: 

# 變更內容

- [新增] xxx
- [修改] yyy
- [移除] zzz

# 測試步驟

### 測試項目 1

- STEP 1: 
- STEP 2: 
- STEP 3: 

預期結果:
</code></pre><p>英文版：</p>
<pre tabindex="0"><code># Summary &amp; Background

# Relevant Information

- Requirement Specifications: 
- Associated Project/Branch: 
- Task Ticket/Meeting Notes: 

# Changes

- [Added] xxx
- [Modified] yyy
- [Removed] zzz

# Testing Steps

### Test Case 1

- STEP 1: 
- STEP 2: 
- STEP 3: 

Expected Result:
</code></pre><hr>
<h2 id="在-gitlab-建立-merge-request-templates-的步驟">在 Gitlab 建立 Merge Request Templates 的步驟<a class="h-anchor" href="#%e5%9c%a8-gitlab-%e5%bb%ba%e7%ab%8b-merge-request-templates-%e7%9a%84%e6%ad%a5%e9%a9%9f" aria-label="這個段落的連結"></a></h2>
<h3 id="step-1-選擇-project-default-branch建立存放-templates-的資料夾">STEP 1: 選擇 Project default branch，建立存放 Templates 的資料夾<a class="h-anchor" href="#step-1-%e9%81%b8%e6%93%87-project-default-branch%e5%bb%ba%e7%ab%8b%e5%ad%98%e6%94%be-templates-%e7%9a%84%e8%b3%87%e6%96%99%e5%a4%be" aria-label="這個段落的連結"></a></h3>
<p>我們要先在根目錄下建立 <code>.gitlab/merge_request_templates/</code> 的資料夾。</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-02.webp" width="1400" height="407" alt="STEP 1: 選擇 Project default branch，建立存放 Templates 的資料夾（圖 2）" loading="lazy" decoding="async"></p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-03.webp" width="1400" height="137" alt="STEP 1: 選擇 Project default branch，建立存放 Templates 的資料夾（圖 3）" loading="lazy" decoding="async"></p>
<blockquote>
<p><strong>小提醒</strong>：一定要在「default branch（ex: main、develop）」下建立，否則是沒有效的。</p>
</blockquote>
<h3 id="step-2-在資料夾下建立md的-templates">STEP 2: 在資料夾下建立「.md」的 Templates<a class="h-anchor" href="#step-2-%e5%9c%a8%e8%b3%87%e6%96%99%e5%a4%be%e4%b8%8b%e5%bb%ba%e7%ab%8bmd%e7%9a%84-templates" aria-label="這個段落的連結"></a></h3>
<p>你可以直接複製筆者在前面提供的 Markdown Template，這邊我將檔案命名為「merge.md」。</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-04.webp" width="1400" height="915" alt="STEP 2: 在資料夾下建立「.md」的 Templates（圖 4）" loading="lazy" decoding="async"></p>
<p>這邊我開一個測試的 branch 來做 Merge request，大家可以看到在 Description 旁邊有一個下拉選單，裡面的 merge 就是我們剛剛新增的模板。</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-05.webp" width="1400" height="669" alt="STEP 2: 在資料夾下建立「.md」的 Templates（圖 5）" loading="lazy" decoding="async"></p>
<p>選擇後就能看到剛剛建立的 Merge request Template：</p>
<p><img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-06.webp" width="1400" height="747" alt="STEP 2: 在資料夾下建立「.md」的 Templates（圖 6）" loading="lazy" decoding="async"></p>
<p>相信一個好的 Merge request Template 能提高專案的品質，並加速團隊的協作流程，減少不必要的溝通成本。</p>
<a class="linkcard" href="https://dean-lin.medium.com/list/7f3c9b6e2442" target="_blank" rel="noopener">
  <span class="lc-body">
    <span class="lc-title">軟體工程</span>
    <span class="lc-desc">Edit description</span>
    <span class="lc-site"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M7 17 17 7M8.5 7H17v8.5"/></svg>dean-lin.medium.com</span>
  </span>
  <span class="lc-thumb">
    <img src="https://deanlin.net/blog/202405/gitlab-merge-request-templates/images/gitlab-merge-request-templates-card-01_hu_8de84ea4754d7f76.webp" width="320" height="320" alt="" loading="lazy" decoding="async">
  </span>
</a>

]]></content:encoded>
    </item>
    <item>
      <title>如果沒有明確的工作流程，團隊將會無所適從 — 工程師血淚史</title>
      <link>https://deanlin.net/blog/202207/clear-workflow-for-teams/</link>
      <pubDate>Fri, 29 Jul 2022 09:27:07 +0800</pubDate>
      <guid>https://deanlin.net/blog/202207/clear-workflow-for-teams/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>團隊合作</category>
      <description>在流程不明確的狀態下，團隊成員只能憑藉自己的直覺做事；如果彼此對一件事的認知不同就容易造成誤會，甚至爆發不必要的衝突。</description>
      <media:content url="https://deanlin.net/blog/202207/clear-workflow-for-teams/images/clear-workflow-for-teams-og_hu_c5f433820b22353.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>在流程不明確的狀態下，團隊成員只能憑藉自己的直覺做事；如果彼此對一件事的認知不同就容易造成誤會，甚至爆發不必要的衝突。</p>
<p>由於過去許多工作流程都是口頭制定，沒有明確的文字敘述，因此想透過這篇文章來整理流程，並在日後的實踐中不斷優化與完善。</p>
<p><img src="https://deanlin.net/blog/202207/clear-workflow-for-teams/images/clear-workflow-for-teams-01.webp" width="1400" height="730" alt="如果沒有明確的工作流程，團隊將會無所適從 — 工程師血淚史（圖 1）" fetchpriority="high" decoding="async"></p>
<pre tabindex="0"><code>大綱
ㄧ、專案初始
二、初始任務
 ➤ 評估每個階段的時程
 ➤ 撰寫 Ticket 的需求規格
 ➤ 估計每個 Ticket 的時數
 ➤ 確認 Ticket 的總時數是否在專案的截止日期內
 ➤ Ticket 分配
 ➤ 專案初始環境建置
 ➤ Server 建置
三、專案進行中
 ➤ 進度回報
 ➤ 工程師之間的合作
 ➤ 工程師與 PM 的合作
 ➤ 了解為什麼都要由 PM 來開 Ticket
</code></pre><h2 id="ㄧ專案初始">ㄧ、專案初始<a class="h-anchor" href="#%e3%84%a7%e5%b0%88%e6%a1%88%e5%88%9d%e5%a7%8b" aria-label="這個段落的連結"></a></h2>
<p>STEP 1：由 PM 與客戶討論具體需求。</p>
<p>STEP 2：請 UI/UX 設計師依造需求初步完成 Wireframe。</p>
<p>STEP 3：PM、UI/UX、Tech Lead 一起確認流程、功能的可行性，判斷是否有需要調整的部分。</p>
<p>STEP 4：待客戶認可 Wireframe 後，請 UI/UX 設計師將其升級成 Mockup。</p>
<p>STEP 5：由 Tech Lead 確認 Mockup 上需要注意的細節（ex：哪些欄位適合拿來搜尋、不同權限看到的畫面、有哪些元件可以設計為共用模組）。</p>
<p>STEP 6：在 UI/UX 設計師調整為 Prototype 後，由 PM（或 UI/UX 設計師）向團隊成員說明系統的功能與流程，確保大家理解這個專案要完成的目標。</p>
<p>STEP 7：由 Tech Lead 向工程師團隊說明各功能在設計上要注意的細節（ex：哪些欄位要設計 Auto-Complete、是否有特別的 Validation Rules、某些功能需要提前 Survey 避免卡關）。</p>
<blockquote>
<p>良心建議：專案初始的設計盡量從 Wireframe 開始，就算專案規模較小也不要直接畫 Mockup；因為客戶的需求在前期會時常變動，就算突然加大投資，小專案突然變成大專案也是很常見的，若使用 Mockup 會要花更多的時間在調整上面。</p>
</blockquote>
<hr>
<h2 id="二初始任務">二、初始任務<a class="h-anchor" href="#%e4%ba%8c%e5%88%9d%e5%a7%8b%e4%bb%bb%e5%8b%99" aria-label="這個段落的連結"></a></h2>
<h3 id="-評估每個階段的時程">評估每個階段的時程<a class="h-anchor" href="#-%e8%a9%95%e4%bc%b0%e6%af%8f%e5%80%8b%e9%9a%8e%e6%ae%b5%e7%9a%84%e6%99%82%e7%a8%8b" aria-label="這個段落的連結"></a></h3>
<p>由 PM 將專案的需求拆分成不同的 Phase，這樣工程師比較能集中注意力在特定事物上，每個 Phase 都需要把如下的任務納入考量：</p>
<ol>
<li>要完成的功能（ex：前端、後端）</li>
<li>撰寫測試程式的時程（ex：單元測試、壓力測試）</li>
<li>QA 團隊測試的時程</li>
<li>測試、正式環境部署的時程</li>
</ol>
<blockquote>
<p>規劃時要保留「緩衝時間」，因為測試一次就過基本上是不可能發生的事情，往往需要預留 15~30% 的時間來修 Bug。</p>
</blockquote>
<h3 id="-撰寫-ticket-的需求規格">撰寫 Ticket 的需求規格<a class="h-anchor" href="#-%e6%92%b0%e5%af%ab-ticket-%e7%9a%84%e9%9c%80%e6%b1%82%e8%a6%8f%e6%a0%bc" aria-label="這個段落的連結"></a></h3>
<p>由 PM 在專案管理系統上為每項任務建立 Ticket，建議需求規格的內容要包含：</p>
<ol>
<li>Prototype 截圖：讓工程師明白功能具體的位置在哪。</li>
<li>需求描述：說明這個功能是用來做什麼的，它跟哪些功能有相依性。</li>
<li>相關計算規則：以計算商品總價來說，就會有「產品搭配、折價卷、信用卡優惠…」等多種排列組合。</li>
<li>使用的邏輯：搜尋欄位可以查詢的欄位有哪些？搜尋的邏輯是 And 還是 Or？</li>
<li>關聯需求：像是後端做完 API 後交付給前端，就需要將兩個 Ticket 關聯。</li>
</ol>
<h3 id="-估計每個-ticket-的時數">估計每個 Ticket 的時數<a class="h-anchor" href="#-%e4%bc%b0%e8%a8%88%e6%af%8f%e5%80%8b-ticket-%e7%9a%84%e6%99%82%e6%95%b8" aria-label="這個段落的連結"></a></h3>
<p>不同 Ticket 的難易度不同，這邊會由 Tech Lead 分別向 Frontend、Backend 工程師確認 Ticket 的估時。</p>
<p>此時工程師千萬不要勉強自己，估出一個很難完成的時數，不然在卡關時，會影響到後續一系列的時程規劃。（但也不要估出不合理的時數）</p>
<blockquote>
<p>如果某個 Task 預估的時程超過 6 小時，建議要再做細分，否則很難衡量每天實作的進度。</p>
</blockquote>
<h3 id="-確認-ticket-的總時數是否在專案的截止日期內">確認 Ticket 的總時數是否在專案的截止日期內<a class="h-anchor" href="#-%e7%a2%ba%e8%aa%8d-ticket-%e7%9a%84%e7%b8%bd%e6%99%82%e6%95%b8%e6%98%af%e5%90%a6%e5%9c%a8%e5%b0%88%e6%a1%88%e7%9a%84%e6%88%aa%e6%ad%a2%e6%97%a5%e6%9c%9f%e5%85%a7" aria-label="這個段落的連結"></a></h3>
<p>只要是專案就一定有截止日期，如果將每個預估的時數加總後，發現已經超過了專案的截止日期，那勢必要做一些調整，比如：</p>
<ol>
<li>簡化部分功能（ex：原本要用 Auto-Complete，現在改用一般的搜尋）。</li>
<li>規劃 MVP 先交出去讓客戶使用（ex：原本要經過一系列複雜的流程才能建立的資料，先用 Seeder 代替，以此大幅減少工程師的開發時程）。</li>
</ol>
<blockquote>
<p>這邊不建議堅持原計劃完成所有功能，因為快速開發所累積的技術債，於未來要花更多的時間處理。</p>
</blockquote>
<h3 id="-ticket-分配">Ticket 分配<a class="h-anchor" href="#-ticket-%e5%88%86%e9%85%8d" aria-label="這個段落的連結"></a></h3>
<p>由 PM 規劃在這個 Sprint 中要完成的 Ticket，然後在 Sprint Planning 時進行細節分工；假設一個 Sprint 為 2 週，建議每個人身上掛的 Task 時數不要超過 60 小時，因為：</p>
<ol>
<li>時常會有臨時的會議、需求、Bug…等意外事件，需要保留緩衝時間。</li>
<li>在專案的初始階段，我們無法保證是否由遺漏的規劃、邏輯的錯誤，若把時間塞滿就很難有轉圜的餘地。</li>
<li>舊的維護專案，有時會有緊急的狀況需要優先處理，這也會吃掉不少時間。</li>
</ol>
<h3 id="-專案初始環境建置">專案初始環境建置<a class="h-anchor" href="#-%e5%b0%88%e6%a1%88%e5%88%9d%e5%a7%8b%e7%92%b0%e5%a2%83%e5%bb%ba%e7%bd%ae" aria-label="這個段落的連結"></a></h3>
<p>由 Tech Lead 或是 Senior Engineer 負責專案初始環境建置，初始化的專案需要在 README.md 中有以下說明：</p>
<ol>
<li>環境需求：Node.js 版本、PHP 版本、MySQL 版本…</li>
<li>如何在 Local 端建立：安裝流程、環境變數…</li>
</ol>
<h3 id="-server-建置">Server 建置<a class="h-anchor" href="#-server-%e5%bb%ba%e7%bd%ae" aria-label="這個段落的連結"></a></h3>
<p>由 Tech Lead 開出專案系統所需的硬體配置（正式機、測試機）、DNS、要安裝的軟體/套件（ex：Ubuntu Server、MySQL、Node.js、PHP…各自的版本），並請 PM 填寫需求單讓 MIS 依照此規格進行建置。</p>
<hr>
<h2 id="三專案進行中">三、專案進行中<a class="h-anchor" href="#%e4%b8%89%e5%b0%88%e6%a1%88%e9%80%b2%e8%a1%8c%e4%b8%ad" aria-label="這個段落的連結"></a></h2>
<h3 id="-進度回報">進度回報<a class="h-anchor" href="#-%e9%80%b2%e5%ba%a6%e5%9b%9e%e5%a0%b1" aria-label="這個段落的連結"></a></h3>
<p>如果團隊有使用專案管理系統，為了日後方便追朔與釐清狀況，建議填寫的內容如下：</p>
<ol>
<li>如果實作的方向是討論出來的，請紀錄「與會人員」與「決議結果」。</li>
<li>如果使用到特別的演算法、技術、套件，請特別附註。</li>
<li>如果該 Ticket 完成後要由其他人接手處理（ex：後端完成 API 後交付給前端），請說明要執行哪些指令（ex：DB Migration、Seeder…），並提供相關的 API 文件。</li>
<li>如果發現該 Ticket 完成所花時間與當初的估計有所不同，請與 PM 討論並調整。</li>
</ol>
<h3 id="-工程師之間的合作">工程師之間的合作<a class="h-anchor" href="#-%e5%b7%a5%e7%a8%8b%e5%b8%ab%e4%b9%8b%e9%96%93%e7%9a%84%e5%90%88%e4%bd%9c" aria-label="這個段落的連結"></a></h3>
<ol>
<li>Ticket 執行順序：一個 Sprint 中，每個工程師都會有很多的 Ticket，但有些 Ticket 會有所謂的「前置條件」，建議在開始作業前要先彼此商議，避免出現等待的空窗期。</li>
<li>回報 API Bug：請說明是在「哪個系統」、「哪隻 API」、「什麼參數下」會發生。</li>
<li>回報 Web Bug：請說明是在「哪個系統」、「哪個畫面（截圖）」、「什麼操作下」會發生。</li>
<li>遇到自己無法解決的問題：請說明是在「哪個系統」、「哪個 Ticket」、「你做過哪些嘗試」、「你認為可能的解決方案」。</li>
</ol>
<h3 id="-工程師與-pm-的合作">工程師與 PM 的合作<a class="h-anchor" href="#-%e5%b7%a5%e7%a8%8b%e5%b8%ab%e8%88%87-pm-%e7%9a%84%e5%90%88%e4%bd%9c" aria-label="這個段落的連結"></a></h3>
<ol>
<li>PM 請工程師完成 Sprint 以外的需求時，請說明「任務優先度」、「為什麼會有這個需求」、「可以先將哪個 Ticket 排後面一點」。</li>
<li>如果工程師在開發過程中收到其他團隊的需求，請將對話窗口轉移到 PM。</li>
<li>如果工程師要請 PM 協助開 Ticket，需描述：「哪個系統」、「要處理的任務/Bug」、「預計要做的事項」、「預計完成所需時間」。</li>
<li>若身上的 Ticket 數量爆炸多、任務分配不均，請及時反應。</li>
</ol>
<blockquote>
<p>如果是同一個專案，我們可以輕鬆的排出任務的優先順序；但如果多個專案同時發起優先度高的任務，工程師在這種狀況下會不知所措，需要由 PM 協助排出優先順序。</p>
</blockquote>
<h3 id="-了解為什麼都要由-pm-來開-ticket">了解為什麼都要由 PM 來開 Ticket<a class="h-anchor" href="#-%e4%ba%86%e8%a7%a3%e7%82%ba%e4%bb%80%e9%ba%bc%e9%83%bd%e8%a6%81%e7%94%b1-pm-%e4%be%86%e9%96%8b-ticket" aria-label="這個段落的連結"></a></h3>
<ol>
<li>如果大家都自己開 Ticket，PM 會無法掌握每個人實際在做的任務，即使有 Tag 到 PM，PM 也未必有辦法看到每一則訊息。</li>
<li>工程師心中的任務優先順序可能與 PM 不同，這會造成最後在核對完成的任務時，因為彼此的認知落差產生爭執。</li>
<li>每個任務完成所需的時間成本不同，可能有些任務是可以不必做，又或者是能交給其他人去做的，讓 PM 從整體的角度去看較不會出現勞逸不均的狀況。</li>
</ol>
<hr>
<blockquote class="pullquote"><p>制定大家願意共同遵守的工作流程，在了解彼此的權利＆義務後，相信團隊的運作會更為順利；文章的流程未必適用於每個團隊，僅為筆者過去經驗的彙整。</p>
</blockquote>
<hr>
<pre tabindex="0"><code>工程師血淚史
▋ 團隊在系統開發上遇到了哪些問題
▋ 需求不斷變更，到底哪個環節出錯了
▋ 當 Scrum Master 跟 PM 同時存在，權力與責任該如何區分？
▋ 如果沒有明確的開發流程，團隊將會無所適從(本篇)
▋ 你知道對專案來說，README.md 有多麼重要嗎？
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>讓開發團隊更好協作的方式 — 下班有約系列文</title>
      <link>https://deanlin.net/blog/202202/better-dev-team-collaboration/</link>
      <pubDate>Thu, 24 Feb 2022 13:50:10 +0800</pubDate>
      <guid>https://deanlin.net/blog/202202/better-dev-team-collaboration/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>團隊合作</category>
      <description>前面兩篇文章分享了工程師容易卡住的問題、常犯的錯誤，而這篇文章會聚焦在「協作」這個部分，提供一些方法讓開發團隊發揮更穩定的效能。</description>
      <media:content url="https://deanlin.net/blog/202202/better-dev-team-collaboration/images/better-dev-team-collaboration-og_hu_5d8a0192ac47ec41.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>前面兩篇文章分享了工程師容易卡住的問題、常犯的錯誤，而這篇文章會聚焦在「協作」這個部分，提供一些方法讓開發團隊發揮更穩定的效能。</p>
<p><img src="https://deanlin.net/blog/202202/better-dev-team-collaboration/images/better-dev-team-collaboration-01.webp" width="1400" height="745" alt="讓開發團隊更好協作的方式 — 下班有約系列文（圖 1）" fetchpriority="high" decoding="async"></p>
<pre tabindex="0"><code>大綱
➤ 可以一起遵守的 Coding Style
➤ 使用相同的程式碼 Format 工具
➤ 沒有明確 Git Flow 機制會發生什麼事？
➤ 制定團隊 Git Flow 的規則
</code></pre><h2 id="-可以一起遵守的-coding-style">可以一起遵守的 Coding Style<a class="h-anchor" href="#-%e5%8f%af%e4%bb%a5%e4%b8%80%e8%b5%b7%e9%81%b5%e5%ae%88%e7%9a%84-coding-style" aria-label="這個段落的連結"></a></h2>
<p>即使是有經驗的工程師，在同一個專案中也很常不小心有多種命名的風格，下面列出幾個建議：</p>
<ul>
<li><strong>變數與函式：</strong>都用小駝峰式（camelCase）的命名，ex：downloadDoc、deleteDoc。</li>
<li><strong>常數命名：</strong>會建議使用全大寫英文命名，字詞間使用下底線（_）連接，ex：VUE_APP_ROOT_API。</li>
<li><strong>少用簡寫或自己發明縮寫：</strong>就算是本人，幾個月後也會忘記自己當時創造的東西。</li>
<li><strong>不要拼錯英文單字：</strong>當程式結構越來越大，我們會透過搜尋來找答案，如果你拼錯就會造成大家的困惑。</li>
<li><strong>字串單引號、雙引號統一：</strong>儘管在 JavaScript 中兩者皆可運行，但在閱讀體驗上就會有點不舒服。</li>
</ul>
<h2 id="-使用相同的程式碼-format-工具">使用相同的程式碼 Format 工具<a class="h-anchor" href="#-%e4%bd%bf%e7%94%a8%e7%9b%b8%e5%90%8c%e7%9a%84%e7%a8%8b%e5%bc%8f%e7%a2%bc-format-%e5%b7%a5%e5%85%b7" aria-label="這個段落的連結"></a></h2>
<p>其實上面的問題大部分可以透過「工具」來解決，但必須律定團隊使用「統一」的工具。</p>
<p>如果團隊沒有統一的工具，會導致你每次在更新專案時，明明只更新一行，但<strong>因為每個人 Format 工具不同導致在 Merge Branch 時看起來幾乎是重寫</strong>。</p>
<p>這邊推薦使用 VSCode Extensions 的 <a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode">Prettier</a>，他支援大部分程式語言的 Format；當然知名的 <a href="https://eslint.org/">ESLint</a> 也是團隊協作時的好選擇。</p>
<blockquote>
<p>不同 Format 工具的斷行字數、單引號、雙引號、結尾有沒有「;」…的習慣都不一樣，如果大家不統一，你看 diff 時會覺得很崩潰並且浪費時間。</p>
</blockquote>
<h2 id="-沒有明確-git-flow-機制會發生什麼事">沒有明確 Git Flow 機制會發生什麼事？<a class="h-anchor" href="#-%e6%b2%92%e6%9c%89%e6%98%8e%e7%a2%ba-git-flow-%e6%a9%9f%e5%88%b6%e6%9c%83%e7%99%bc%e7%94%9f%e4%bb%80%e9%ba%bc%e4%ba%8b" aria-label="這個段落的連結"></a></h2>
<p>如果沒有一套基礎簡單的規則，你可能會遇到以下障礙：</p>
<ul>
<li><strong>Deploy（部署）沒有基準</strong>：正式機、測試機要用哪個 Branch？如果每次都不一樣，那遲早都會出事。</li>
<li><strong>花很多時間在 Merge Branch（合併分支）上</strong>：如果不是從同一條 Branch 分支出去，那在 Merge 時很容易出現各種衝突需要解決。</li>
<li><strong>難以從 Branch 追蹤作業進度</strong>：有些人會只用一條 Branch 從頭做到尾，造成單純看這個分支無法理解他到底完成了哪些功能。</li>
<li><strong>無法理解的 commit 內容</strong>：每個人都有自己的 commit 風格，導致追溯歷史時很難找到節點。</li>
<li><strong>任務交接時的困擾</strong>：有些人沒有定期 push 的習慣，喜歡累積非常多的 commit 再一次 push；這樣如果他突然請假，或剛好在忙其他事情時，職務代理人並無法協助處理他的任務，甚至重工浪費時間。</li>
</ul>
<h2 id="-制定團隊-git-flow-的規則">制定團隊 Git Flow 的規則<a class="h-anchor" href="#-%e5%88%b6%e5%ae%9a%e5%9c%98%e9%9a%8a-git-flow-%e7%9a%84%e8%a6%8f%e5%89%87" aria-label="這個段落的連結"></a></h2>
<p>下面是筆者團隊在各個 Branch 的規則：</p>
<h3 class="h-nomark" id="-master">🏷️ Master<a class="h-anchor" href="#-master" aria-label="這個段落的連結"></a></h3>
<ul>
<li><strong>功能</strong>：部署到正式機的 branch</li>
<li><strong>Merge request</strong>：由資深工程師或是技術主管審核</li>
</ul>
<h3 class="h-nomark" id="-develop">🏷️ Develop<a class="h-anchor" href="#-develop" aria-label="這個段落的連結"></a></h3>
<ul>
<li><strong>功能</strong>：部署到測試機的 branch</li>
<li><strong>Merge request</strong>：由資深工程師或是技術主管審核</li>
</ul>
<h3 class="h-nomark" id="-feature">🏷️ Feature<a class="h-anchor" href="#-feature" aria-label="這個段落的連結"></a></h3>
<ul>
<li><strong>命名方式</strong>：依功能命名，如果有任務編號的話一同附上，方便日後追蹤</li>
<li><strong>基礎規則</strong>：原則上都是從 Develop 分支出去，每個 Feature 的功能盡量細分到可以在一天內完成</li>
</ul>
<h3 class="h-nomark" id="-hotfix">🏷️ Hotfix<a class="h-anchor" href="#-hotfix" aria-label="這個段落的連結"></a></h3>
<ul>
<li><strong>命名方式</strong>：依功能命名，如果有任務編號的話一同附上，方便日後追蹤</li>
<li><strong>基礎規則</strong>：原則上是為了解決正式機上面的緊急 Bug，因此通常是從 Master 分支出去；完成修改後再合併回 Master、Develop</li>
</ul>
<h3 class="h-nomark" id="-release">🏷️ Release<a class="h-anchor" href="#-release" aria-label="這個段落的連結"></a></h3>
<ul>
<li><strong>命名方式</strong>：依釋出的版本命名</li>
<li><strong>基礎規則</strong>：當有一個大版本準備部署到正式機，為了保證系統穩定性，會先從 Develop 分支 Release 的版本</li>
</ul>
<p>以及其他希望大家一起遵守的細節：</p>
<ul>
<li>完成 Feature 時要 push 一版，並通知協作夥伴確認功能。</li>
<li>如果該 Feature branch 已經 merge 回 develop，且不會再使用該 branch，就需要把它給 delete 掉，避免線上有太多分支，會不清楚哪一個才是有在作用的。</li>
<li>每天下班前至少要 push 一版，讓管理者容易掌握進度。</li>
<li>commit 可以用「新增功能、變更功能、修補 Bug」作為 title 的分類，然後將調整的內容條列式寫入 description，這樣其他人在 Code Review 時可以知道重點，範例如下：</li>
</ul>
<pre tabindex="0"><code>### title
修補 Bug：解決職員列表 issues
### description
1. 解決排序無效 bug
2. 在「異常」欄位增加是否為 null 的判斷，避免字串切割異常
3. 解決 pagination 參數沒有傳送到的問題
</code></pre><blockquote>
<p>筆者認為「簡單、易懂」為第一優先，中英文表達都可以。</p>
</blockquote>
<hr>
<blockquote class="pullquote"><p>相信還有很多可以讓開發團隊協作更愉快的工具與方法，期待大家的留言分享～</p>
</blockquote>
<p><strong>如果你對目前的職涯感到迷茫，想從不同視角檢視自己的選擇，相信《<a href="https://www.tenlong.com.tw/products/9786264142083">工程師下班有約</a>》這本書能為你帶來靈感與啟發：</strong></p>
<figure class="figure"><img src="https://deanlin.net/blog/202202/better-dev-team-collaboration/images/better-dev-team-collaboration-02.webp" width="1400" height="319" alt="林鼎淵著作《工程師下班有約：企業內訓講師帶你認清職涯真相！》" loading="lazy" decoding="async">
  <figcaption><a href="https://www.tenlong.com.tw/products/9786264142083">https://www.tenlong.com.tw/products/9786264142083</a></figcaption>
</figure>

<pre tabindex="0"><code>下班有約系列文
▋ [前端]新手工程師容易卡住的問題
▋ [前端＆後端]工程師常犯的錯誤
▋ 讓開發團隊更好協作的方式(本篇)
▋ 談談 Pair Programing
▋ 談談工程師的話語權
▋ 出社會後，新鮮人要及早知道的 5 件事
▋ 面試的性向測驗竟然準到讓人心裡發寒？
▋ 反其道而行的任務分配
▋ 現在的 Daily Scrum 真的適合團隊嗎？
▋ 用低成本也能請到好員工？資深 HR 不想告訴你的秘密！
</code></pre>]]></content:encoded>
    </item>
  </channel>
</rss>
