<?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>Project Management｜林鼎淵 Dean Lin</title>
    <link>https://deanlin.net/tags/project-management/</link>
    <image><url>https://deanlin.net/images/author_hu_aa256fc934e9a932.jpg</url><title>Project Management｜林鼎淵 Dean Lin</title><link>https://deanlin.net/tags/project-management/</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/project-management/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/202402/freelance-pitfalls/</link>
      <pubDate>Sun, 11 Feb 2024 14:36:09 +0800</pubDate>
      <guid>https://deanlin.net/blog/202402/freelance-pitfalls/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>團隊合作</category>
      <description>很多人想透過接案來增加收入、豐富履歷，但往往踏入後，才發現這原來是一個踩地雷遊戲！</description>
      <media:content url="https://deanlin.net/blog/202402/freelance-pitfalls/images/freelance-pitfalls-og_hu_ea0d9b41dcac3188.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>很多人想透過接案來增加收入、豐富履歷，但往往踏入後，才發現這原來是一個踩地雷遊戲！</p>
<p>筆者過去接過的案子涵蓋網頁設計、APP 製作、網路爬蟲、專欄文章、線上課程、企業內訓…</p>
<p>不管是好的、壞的，還是奇怪的甲方全都遇過，所以在上設計管理的課程時很有「共鳴感」。</p>
<p><strong>如果你有接案的打算，那這篇文章一定要讀到最後，別人踩過的坑，我們沒必要親自體會。</strong></p>
<blockquote>
<p>PS. 這篇文章沒有要批評任何一方的意思，其實無論甲方還是乙方都需要後天學習，沒有人天生就會。</p>
</blockquote>
<p><img src="https://deanlin.net/blog/202402/freelance-pitfalls/images/freelance-pitfalls-01.webp" width="1145" height="640" alt="為什麼接案就像踩地雷？苦主幫你來掃雷 ── 設計管理系列文（圖 1）" fetchpriority="high" decoding="async"></p>
<pre tabindex="0"><code>文章大綱

ㄧ、與客戶初步接洽
二、初步認識＆討論
三、深入釐清需求
四、提供報價單
五、提供時程
六、提供合約＆簽約
七、結語
</code></pre><blockquote>
<p>文章大綱所列出的，是接案常見的流程，可能會根據實際狀況增減。</p>
</blockquote>
<h2 id="ㄧ與客戶初步接洽">ㄧ、與客戶初步接洽<a class="h-anchor" href="#%e3%84%a7%e8%88%87%e5%ae%a2%e6%88%b6%e5%88%9d%e6%ad%a5%e6%8e%a5%e6%b4%bd" aria-label="這個段落的連結"></a></h2>
<p>建議先跟客戶確認以下 3 點，避免浪費彼此的時間：</p>
<ul>
<li><strong>時程</strong>: 了解客戶對專案時程的期待，確認彼此的時程能對上；當遇到急件時，你一定要考慮自己是否能夠如期完成。</li>
<li><strong>類型</strong>: 判斷自己是否做過類似的專案，以及是否擅長這類型的專案。</li>
<li><strong>預算</strong>: 你要初步提供自己可以接受的報價區間，避免談到後面才發現客戶無法負擔。</li>
</ul>
<p>很多人會因為害怕或缺乏經驗，不敢在一開始跟客戶確認以上事宜，導致專案在一個很模糊的狀態下進行；但殊不知，這些模糊地帶往往會導致合作到後期彼此撕破臉。</p>
<p>另外你不要想著每次接洽都會成功，因為客戶可能一次聯繫很多人，避免出狀況時沒有備案。</p>
<p>這次沒有選你，未必是你不好，只是他們心目中的第一名接下了這個專案。</p>
<hr>
<h2 id="二初步認識討論">二、初步認識＆討論<a class="h-anchor" href="#%e4%ba%8c%e5%88%9d%e6%ad%a5%e8%aa%8d%e8%ad%98%e8%a8%8e%e8%ab%96" aria-label="這個段落的連結"></a></h2>
<p>客戶選擇你，不代表他了解你。</p>
<p>所以在跟客戶第一次見面時，建議你要先介紹自己過去的作品、做事的流程，讓客戶判斷自己是否能配合。</p>
<p>同時你也要了解客戶對這個專案的期待，像是專案的目標與背景資訊。</p>
<p>這邊也建議你了解一下客戶過往的做事流程，在資訊透明的狀態下才有可能合作愉快。</p>
<hr>
<h2 id="三深入釐清需求">三、深入釐清需求<a class="h-anchor" href="#%e4%b8%89%e6%b7%b1%e5%85%a5%e9%87%90%e6%b8%85%e9%9c%80%e6%b1%82" aria-label="這個段落的連結"></a></h2>
<p>在初步確定合作意向後，建議約一個較大型的會議。</p>
<p>在這階段要讓專案相關利害人一同加入討論，以確認對方的需求。</p>
<hr>
<h2 id="四提供報價單">四、提供報價單<a class="h-anchor" href="#%e5%9b%9b%e6%8f%90%e4%be%9b%e5%a0%b1%e5%83%b9%e5%96%ae" aria-label="這個段落的連結"></a></h2>
<p>如果沒有白紙黑字，那報價就只是憑感覺；以下是撰寫報價單要注意的事項：</p>
<ul>
<li><strong>不要有模糊空間</strong>: 規格要講清楚，能修改幾次要列出來，要明訂具體的流程。</li>
<li><strong>附上但書</strong>: 具體寫上你不做的部分；並寫上如果真的要做，你會如何報價。</li>
</ul>
<p>而這份報價單可以：</p>
<ul>
<li><strong>讓客戶思考預算</strong>: 有時客戶天馬行空，我們需要透過報價單把他拉回現實；如果有預算考量，可以在這個階段幫客戶收斂專案範圍，讓他對內容進行取捨。</li>
<li><strong>幫我們初步篩選客戶</strong>: 在報價後，有些客戶會開始殺價或是提出不合理的需求；如果覺得對方的行為讓你覺得不舒服，那建議不要繼續合作下去，因為通常會越來越痛苦。</li>
</ul>
<blockquote>
<p><strong>Tips</strong>: 與其消耗能量克服痛苦，不如一開始就選擇合適的客戶？</p>
</blockquote>
<hr>
<h2 id="五提供時程">五、提供時程<a class="h-anchor" href="#%e4%ba%94%e6%8f%90%e4%be%9b%e6%99%82%e7%a8%8b" aria-label="這個段落的連結"></a></h2>
<p>有些專案的時程會長達幾個月，甚至以年為單位。</p>
<p>為了確保雙方的認知相同，我們要與客戶討論：</p>
<ul>
<li><strong>重要檢核點（里程碑）</strong>: 除了規畫專案時程外，還要列出每個階段可以驗收的項目；並在進行驗收前，確保相關利害關係人皆可參與這些重大會議（不然可能在後續被有決策權的人推翻重來）。</li>
<li><strong>專案交付時間</strong>: 定下時間後，後續合約就會按照這個時間走。</li>
</ul>
<hr>
<h2 id="六提供合約">六、提供合約<a class="h-anchor" href="#%e5%85%ad%e6%8f%90%e4%be%9b%e5%90%88%e7%b4%84" aria-label="這個段落的連結"></a></h2>
<p>前面細節都確認完後，就可以準備簽約了，但簽約有很多細節需要注意，筆者有空時會再寫另一篇文章分享。</p>
<p>不過這邊也要提醒大家，簽約不代表有保障，就算對象是大公司也一樣。</p>
<p>因為法律流程跑起來曠日費時，我就聽說過有的公司的樓梯間堆滿法院傳票。</p>
<hr>
<h2 id="七結語">七、結語<a class="h-anchor" href="#%e4%b8%83%e7%b5%90%e8%aa%9e" aria-label="這個段落的連結"></a></h2>
<p>你沒看錯，這篇文章談的只是「接案前要注意的事項」。</p>
<p>還有很多細節沒有寫進文章，比如: <a href="https://deanlin.net/blog/202402/freelance-pricing/">如何報價</a>、<a href="https://deanlin.net/blog/202402/raise-freelance-rates/">如何提高報價</a>、<a href="https://deanlin.net/blog/202403/find-good-freelance-clients/">如何接到好專案、如何判斷是否為好客戶</a>…</p>
<p>接案其實很累，因為前期的溝通也是專案的成本。</p>
<p>如果在這個階段發現客戶不合適，建議及時停損，勉強的結果通常不好。</p>
<p>同時提醒大家，如果你在有正職的狀態下接案，請謹慎評估自己的身心狀況；因為接案而搞砸本業，那就真的本末倒置了。</p>
<blockquote>
<p>以上是「職涯必修設計管理學」的 Part 2心得筆記 ，如果覺得我的分享對你有幫助，歡迎 <a href="https://dean-lin.medium.com/subscribe">Follow</a> 我吸收更多知識。</p>
</blockquote>
<a class="linkcard" href="https://deanlin.net/series/design-thinking/">
  <span class="lc-body">
    <span class="lc-title">設計思考</span>
    <span class="lc-desc">一個工程師眼中的設計思考：同理、提問、定義問題，把「解決問題」變成可以練習的能力。</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="M5 12h14M13 6l6 6-6 6"/></svg>林鼎淵 Dean Lin</span>
  </span>
</a>

]]></content:encoded>
    </item>
    <item>
      <title>你知道對專案來說，README.md 有多麼重要嗎？ ── 工程師血淚史</title>
      <link>https://deanlin.net/blog/202208/why-readme-matters/</link>
      <pubDate>Fri, 05 Aug 2022 11:33:37 +0800</pubDate>
      <guid>https://deanlin.net/blog/202208/why-readme-matters/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>團隊合作</category>
      <description>如果公司的專案很多，README.md 又沒有寫好，那後續接手的人會非常痛苦；如果公司專案的規模很大，README.md 又缺乏維護，那這個專案已經半隻腳踏進棺材。</description>
      <media:content url="https://deanlin.net/blog/202208/why-readme-matters/images/why-readme-matters-og_hu_e7a8e04e53680ef2.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>如果公司的專案很多，README.md 又沒有寫好，那後續接手的人會非常痛苦；如果公司專案的規模很大，README.md 又缺乏維護，那這個專案已經半隻腳踏進棺材。</p>
<p>身為工程師，我理解大部分的人都想把精力放在寫出更好的程式，但專案能否長期發展，其實是取決於「文件」；如果文件亂七八糟，或者甚至根本沒有制式文件，那這個專案的未來發展性堪憂。</p>
<p>從管理的角度來說，我們要去思考：「如果負責專案的工程師明天就不在了，這個專案能否進行下去？」</p>
<p><img src="https://deanlin.net/blog/202208/why-readme-matters/images/why-readme-matters-01.webp" width="1400" height="733" alt="你知道對專案來說，README.md 有多麼重要嗎？ ── 工程師血淚史（圖 1）" fetchpriority="high" decoding="async"></p>
<pre tabindex="0"><code>大綱
一、為什麼 README.md 很重要？
二、有哪些是 README.md 一定要提供的資訊？
 ➤ 專案介紹 — Description
 ➤ 運行環境需求 — Requirement
 ➤ 環境檔（.env）有哪些欄位要自己填寫 — .env Setting
 ➤ 在 Local 端的安裝＆運行步驟 — Build Setup(Local)
 ➤ 在 Server 端的安裝＆驗證步驟- Build Setup(Server)
 ➤ 可提供支援的同仁 ── Support
 ➤ 注意事項 — Warning
三、如果 README.md 有這些資訊，會讓日後維運更加順利
 ➤ 系統架構圖 — System architecture
 ➤ 使用者操作手冊 — User Manual
 ➤ Demo 影片 — Demo Video
 ➤ UI/UX 設計稿 — UI/UX Design
 ➤ Function map
 ➤ 單元測試、整合測試 — Unit Testing、Integration Testing
</code></pre><h2 id="一為什麼-readmemd-很重要">一、為什麼 README.md 很重要？<a class="h-anchor" href="#%e4%b8%80%e7%82%ba%e4%bb%80%e9%ba%bc-readmemd-%e5%be%88%e9%87%8d%e8%a6%81" aria-label="這個段落的連結"></a></h2>
<p>因為開發人員第一次接觸專案時，就是透過 README.md 來了解的。</p>
<p>它就像是一張專案的地圖，如果破損、缺乏維護，那踏上旅途的人勢必會遇上迷航、陷阱。</p>
<p>在沒有律定 README.md 該有什麼內容時，每個人都是自由發揮；除了內容可能有短缺外，每份專案的撰寫風格也不盡相同，因此想透過這篇文章律定基礎架構。</p>
<blockquote>
<p>這邊提醒讀者，本篇文章所建議的 README.md 內容是提供給「內部開發人員」看的；如果你的專案是對外開放，部分內容請自行斟酌。</p>
</blockquote>
<hr>
<h2 id="二有哪些是-readmemd-一定要提供的資訊">二、有哪些是 README.md 一定要提供的資訊？<a class="h-anchor" href="#%e4%ba%8c%e6%9c%89%e5%93%aa%e4%ba%9b%e6%98%af-readmemd-%e4%b8%80%e5%ae%9a%e8%a6%81%e6%8f%90%e4%be%9b%e7%9a%84%e8%b3%87%e8%a8%8a" aria-label="這個段落的連結"></a></h2>
<p>下面列出的項目，是筆者認為對第一次接觸專案、準備維護專案的人有幫助的資訊。</p>
<h3 id="-專案介紹--description">專案介紹 ── Description<a class="h-anchor" href="#-%e5%b0%88%e6%a1%88%e4%bb%8b%e7%b4%b9--description" aria-label="這個段落的連結"></a></h3>
<p>簡述專案目標，讓第一次接觸的人也能在短時間初步了解專案（如果使用到少見的專有名詞，請附加說明）。</p>
<blockquote>
<p>如果是前後端分離的專案，請附上前端/後端的專案連結。</p>
</blockquote>
<h3 id="-運行環境需求--requirement">運行環境需求 ── Requirement<a class="h-anchor" href="#-%e9%81%8b%e8%a1%8c%e7%92%b0%e5%a2%83%e9%9c%80%e6%b1%82--requirement" aria-label="這個段落的連結"></a></h3>
<p>描述這個專案運行所需要的環境，比如說：</p>
<ul>
<li><strong>前端（Frontend）</strong>：NVM、Yarn、Node.js</li>
<li><strong>後端（Backend）</strong>：PHP、Composer、Laravel、MySQL</li>
</ul>
<blockquote>
<p>隨著技術進步，各項工具的版本不斷更迭；因此建議要附上能讓專案順利運行的「版本」，因為許多工具並沒有向下相容。</p>
</blockquote>
<h3 id="-環境檔env有哪些欄位要自己填寫--env-setting">環境檔（.env）有哪些欄位要自己填寫 ── .env Setting<a class="h-anchor" href="#-%e7%92%b0%e5%a2%83%e6%aa%94env%e6%9c%89%e5%93%aa%e4%ba%9b%e6%ac%84%e4%bd%8d%e8%a6%81%e8%87%aa%e5%b7%b1%e5%a1%ab%e5%af%ab--env-setting" aria-label="這個段落的連結"></a></h3>
<p>以後端來說，涉及機密、隱私、個人化的參數會需要自己填寫，比如：</p>
<ol>
<li>DB 帳號密碼、IP、Port</li>
<li>JWT 有效期限</li>
<li>Mail 相關參數</li>
<li>Storage 路徑</li>
</ol>
<h3 id="-在-local-端的安裝運行步驟--build-setup-local">在 Local 端的安裝＆運行步驟 ── Build Setup (Local)<a class="h-anchor" href="#-%e5%9c%a8-local-%e7%ab%af%e7%9a%84%e5%ae%89%e8%a3%9d%e9%81%8b%e8%a1%8c%e6%ad%a5%e9%a9%9f--build-setup-local" aria-label="這個段落的連結"></a></h3>
<p>是那種「複製貼上」就能夠順利安裝的步驟，可以放一些參考連結，但不要讓使用者需要去閱讀官方文檔才知道怎麼安裝。</p>
<p>以後端舉例，指令需至少包含如下內容：</p>
<ol>
<li>專案安裝步驟</li>
<li>DB Migration</li>
<li>DB Seeder</li>
<li>運行專案</li>
</ol>
<blockquote>
<p>如果採前後端分離，可以附上 POSTMAN 的 collection 方便前端驗證。</p>
</blockquote>
<h3 id="-在-server-端的安裝驗證步驟--build-setup-server">在 Server 端的安裝＆驗證步驟 ── Build Setup (Server)<a class="h-anchor" href="#-%e5%9c%a8-server-%e7%ab%af%e7%9a%84%e5%ae%89%e8%a3%9d%e9%a9%97%e8%ad%89%e6%ad%a5%e9%a9%9f--build-setup-server" aria-label="這個段落的連結"></a></h3>
<p>如果不是採取自動部署的策略，那筆者建議紀錄如下內容：</p>
<ol>
<li>專案運行所需套件，及其對應的指令</li>
<li>伺服器端參數（ex：API 最長可執行時間、可上傳檔案容量限制、單個 IP 每分鐘存取次數）</li>
<li>不同環境對應的 Server ip</li>
<li>相關參數調整後，重啟使其生效的指令</li>
<li>部署完成後，可以透過什麼方式（工具）驗證功能皆如預期運行</li>
</ol>
<h3 id="-可提供支援的同仁--support">可提供支援的同仁 ── Support<a class="h-anchor" href="#-%e5%8f%af%e6%8f%90%e4%be%9b%e6%94%af%e6%8f%b4%e7%9a%84%e5%90%8c%e4%bb%81--support" aria-label="這個段落的連結"></a></h3>
<p>讓初次接觸專案的人知道遇到問題可以找誰詢問，建議在這個部分放上開發人員的聯絡方式（ex：座位、email）。</p>
<p>有時問題可能有其歷史背景，所以可以用附註形式，放上了解這份專案歷史的同仁（ex：主管、負責的 PM）。</p>
<h3 id="-注意事項--warning">注意事項 ── Warning<a class="h-anchor" href="#-%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a0%85--warning" aria-label="這個段落的連結"></a></h3>
<p>每個專案或多或少都會有一些特別的設計，時間拉長難免遺忘，建議把他們記錄下來，比如：</p>
<ol>
<li>如果 API 文檔是用指令產生的，請記得記錄下來</li>
<li>如果有設計排程（Schedule），把觸發的時間點列出</li>
<li>前端在不同環境的建立指令（Script）</li>
<li>如果用到特別的套件，建議簡單說明在什麼時機應用，並放上官方文檔連結</li>
<li>專案的授權條款（License）</li>
</ol>
<hr>
<h2 id="三如果-readmemd-有這些資訊會讓日後維運更加順利">三、如果 README.md 有這些資訊，會讓日後維運更加順利<a class="h-anchor" href="#%e4%b8%89%e5%a6%82%e6%9e%9c-readmemd-%e6%9c%89%e9%80%99%e4%ba%9b%e8%b3%87%e8%a8%8a%e6%9c%83%e8%ae%93%e6%97%a5%e5%be%8c%e7%b6%ad%e9%81%8b%e6%9b%b4%e5%8a%a0%e9%a0%86%e5%88%a9" aria-label="這個段落的連結"></a></h2>
<h3 id="-系統架構圖--system-architecture">系統架構圖 ── System architecture<a class="h-anchor" href="#-%e7%b3%bb%e7%b5%b1%e6%9e%b6%e6%a7%8b%e5%9c%96--system-architecture" aria-label="這個段落的連結"></a></h3>
<p>如果專案結構複雜，或是需要串接多個系統，那建議放上系統架構圖，否則接手的工程師會需要花很多時間去研究他們之間的關聯性。</p>
<figure class="figure"><img src="https://deanlin.net/blog/202208/why-readme-matters/images/why-readme-matters-02.webp" width="1044" height="904" alt="IMG from：https://commons.wikimedia.org/" loading="lazy" decoding="async">
  <figcaption>IMG from：<a href="https://commons.wikimedia.org/">https://commons.wikimedia.org/</a></figcaption>
</figure>

<h3 id="-使用者操作手冊--user-manual">使用者操作手冊 ── User Manual<a class="h-anchor" href="#-%e4%bd%bf%e7%94%a8%e8%80%85%e6%93%8d%e4%bd%9c%e6%89%8b%e5%86%8a--user-manual" aria-label="這個段落的連結"></a></h3>
<p>每份專案都一定要製作使用者操作手冊，否則 PM、工程師會不停被重複的問題打擾；有了這份手冊後，之後負責維運的工程師也能更快上手。</p>
<blockquote>
<p>形式可以是 Wiki、Word…等等，讓使用者方便閱讀為第一優先。</p>
</blockquote>
<h3 id="-demo-影片-demo-video">Demo 影片── Demo Video<a class="h-anchor" href="#-demo-%e5%bd%b1%e7%89%87-demo-video" aria-label="這個段落的連結"></a></h3>
<p>如果可以，建議在專案完成後錄製「簡單」的 Demo 影片；主要目的是讓工程師知曉專案「正常」的狀況下應該長什麼樣子。</p>
<blockquote>
<p><em>有時專案看似順利啟動了，但實際上部分功能是不完整的（ex：前端順利啟動了，但 WebSocket 異常）。</em></p>
</blockquote>
<h3 id="-uiux-設計稿--uiux-design">UI/UX 設計稿 ── UI/UX Design<a class="h-anchor" href="#-uiux-%e8%a8%ad%e8%a8%88%e7%a8%bf--uiux-design" aria-label="這個段落的連結"></a></h3>
<p>放上 Wireframe、Mockup、Prototype 等設計稿連結（如果有的話）</p>
<p><img src="https://deanlin.net/blog/202208/why-readme-matters/images/why-readme-matters-03.webp" width="1000" height="667" alt="UI/UX 設計稿 ── UI/UX Design（圖 3）" loading="lazy" decoding="async"></p>
<h3 id="-function-map">Function map<a class="h-anchor" href="#-function-map" aria-label="這個段落的連結"></a></h3>
<p>通常會以心智圖來呈現，PM 可以透過它讓工程師快速了解、評估初期的功能。</p>
<p>在遇到需求要新增或變更時，有這張圖工程師能也更快回憶，並掌握重點。</p>
<p><img src="https://deanlin.net/blog/202208/why-readme-matters/images/why-readme-matters-04.webp" width="1400" height="1566" alt="Function map（圖 4）" loading="lazy" decoding="async"></p>
<blockquote>
<p><a href="https://gitmind.com/">GitMind</a> 是個不錯的工具，推薦大家使用看看。</p>
</blockquote>
<h3 id="-單元測試整合測試--unit-testingintegration-testing">單元測試、整合測試 ── Unit Testing、Integration Testing<a class="h-anchor" href="#-%e5%96%ae%e5%85%83%e6%b8%ac%e8%a9%a6%e6%95%b4%e5%90%88%e6%b8%ac%e8%a9%a6--unit-testingintegration-testing" aria-label="這個段落的連結"></a></h3>
<p>專案的穩定，是建立在有寫測試程式的前提下；否則系統很容易因為需求的新增、變更，而導致過去的功能毀損。</p>
<p>在測試方面，除了「整體」的測試外，有時我們只需要測試「特定功能」；可以把常用的測試指令紀錄在這裡（ex：邏輯複雜、關聯廣泛的測試）。</p>
<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/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>當 Scrum Master 跟 PM 同時存在，權力與責任該如何區分？ — 工程師血淚史</title>
      <link>https://deanlin.net/blog/202207/scrum-master-vs-pm/</link>
      <pubDate>Tue, 12 Jul 2022 21:16:40 +0800</pubDate>
      <guid>https://deanlin.net/blog/202207/scrum-master-vs-pm/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>團隊合作</category>
      <description>在過去的文章中有提到，為了提高團隊成員在 Scrum 的參與度，我們改成輪流擔任 Scrum Master 的機制，但這樣真的有效果嗎？而且 Scrum Master 跟 PM 的工作高度重疊，要如何區分兩者的權力與責任呢？</description>
      <media:content url="https://deanlin.net/blog/202207/scrum-master-vs-pm/images/scrum-master-vs-pm-og_hu_1b3b0247b9449758.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>在<a href="https://deanlin.net/blog/202205/team-development-problems/">過去的文章</a>中有提到，為了提高團隊成員在 Scrum 的參與度，我們改成輪流擔任 Scrum Master 的機制，但這樣真的有效果嗎？而且 Scrum Master 跟 PM 的工作高度重疊，要如何區分兩者的權力與責任呢？</p>
<p>這篇文章將與您分享我們是如何調整，以及調整後發生哪些改變。</p>
<p><img src="https://deanlin.net/blog/202207/scrum-master-vs-pm/images/scrum-master-vs-pm-01.webp" width="1400" height="730" alt="當 Scrum Master 跟 PM 同時存在，權力與責任該如何區分？ — 工程師血淚史（圖 1）" fetchpriority="high" decoding="async"></p>
<blockquote>
<p>本文提及之專案、人物、事件純屬虛構，如有雷同，實屬巧合，請勿對號入座。</p>
</blockquote>
<pre tabindex="0"><code>大綱
ㄧ、調整的目的是什麼？
二、定義 Scrum Master 跟 PM 的權限
  ➤ Scrum Master
  ➤ PM
三、調整後發生哪些改變
  ➤ 成員對專案、團隊有更深刻的認知
  ➤ Scrum 參與度提升
  ➤ 回顧時發表更踴躍
四、總結
</code></pre><h2 id="ㄧ調整的目的是什麼">ㄧ、調整的目的是什麼？<a class="h-anchor" href="#%e3%84%a7%e8%aa%bf%e6%95%b4%e7%9a%84%e7%9b%ae%e7%9a%84%e6%98%af%e4%bb%80%e9%ba%bc" aria-label="這個段落的連結"></a></h2>
<p>明明跑的是 Scrum，卻沒有團隊合作的感覺。</p>
<p>每間公司跑 Scrum 的方式與目的不同，有些 Scrum 跑起來更像是傳統的工作匯報；即使在身處在同一個會議中，卻只有主管跟 PM 關心每個人的工作內容。</p>
<p>如果團隊成員不關心彼此的工作內容，單獨匯報或是用紙本報告其實更加省時；開 Scrum 的目的是希望大家了解彼此的任務，確認是否有需要調整的地方，避免任務的先後順序、優先度搞錯，導致專案進度延宕。</p>
<p>但如果只是口頭上說希望大家積極參與，實際效果就跟老師要學生好好聽課一樣，因此想透過流程來進行改善。</p>
<p>而我們選擇的方案是 — 讓團隊成員輪流擔任 Scrum Master。</p>
<hr>
<h2 id="二定義-scrum-master-跟-pm-的權限">二、定義 Scrum Master 跟 PM 的權限<a class="h-anchor" href="#%e4%ba%8c%e5%ae%9a%e7%be%a9-scrum-master-%e8%b7%9f-pm-%e7%9a%84%e6%ac%8a%e9%99%90" aria-label="這個段落的連結"></a></h2>
<p><strong>我們希望在提升成員參與度的同時，盡可能不要增加負擔。</strong></p>
<p>因為 Scrum Master 的工作內容與 PM 高度重疊，如果沒區分好彼此的界線，勢必會導致其他成員的困惑，比如：</p>
<ol>
<li>開單要找誰？</li>
<li>Sprint Planning 的規劃由誰負責？</li>
<li>需求規格由誰來寫？</li>
</ol>
<p>所以我們做了如下區分：</p>
<h3 id="-scrum-master">Scrum Master<a class="h-anchor" href="#-scrum-master" aria-label="這個段落的連結"></a></h3>
<ol>
<li><strong>主持 Daily Scrum Meeting</strong>：了解每個人工作的進度、預計要做的事、以及遇到的問題。</li>
<li><strong>主持 Sprint Review、Retrospective 會議</strong>：讓大家報告在這個 Sprint 中做了什麼，有哪些好的可以繼續保持，有哪些壞的要進行調整。</li>
<li><strong>參與 Sprint Planning 會議</strong>：了解下個 Sprint 要完成的事項。</li>
</ol>
<h3 id="-pm">PM<a class="h-anchor" href="#-pm" aria-label="這個段落的連結"></a></h3>
<ol>
<li><strong>專案管理</strong>：追蹤成員的進度、討論需求、協調資源…原則上工作內容不變，只是部分工作交由 Scrum Master 主持。</li>
<li><strong>輔助 Scrum Master</strong>：儘管已經簡化許多 Scrum Master 的工作，但因為部分成員並沒有接觸過敏捷開發，因此需要幫忙拾漏補遺。</li>
<li><strong>規劃 Sprint Planning</strong>：無論是規劃要完成的工作，還是與每位工程師確認工時，都是需要花費不少心力的任務，因此主要還是由 PM 專職處理。</li>
</ol>
<blockquote>
<p>之所以這樣設計，是希望成員在擔任 Scrum Master 的同時，儘可能不影響到他的本職工作，我們期待這樣的流程可以讓每位成員更融入專案，而不是取代 PM 的工作。</p>
</blockquote>
<hr>
<h2 id="三調整後發生哪些改變">三、調整後發生哪些改變<a class="h-anchor" href="#%e4%b8%89%e8%aa%bf%e6%95%b4%e5%be%8c%e7%99%bc%e7%94%9f%e5%93%aa%e4%ba%9b%e6%94%b9%e8%ae%8a" aria-label="這個段落的連結"></a></h2>
<p>目前實行了 3 個 Sprint，成員的接受度還算高（希望不是敢怒不敢言 😅）。</p>
<h3 id="-成員對專案團隊有更深刻的認知">成員對專案、團隊有更深刻的認知<a class="h-anchor" href="#-%e6%88%90%e5%93%a1%e5%b0%8d%e5%b0%88%e6%a1%88%e5%9c%98%e9%9a%8a%e6%9c%89%e6%9b%b4%e6%b7%b1%e5%88%bb%e7%9a%84%e8%aa%8d%e7%9f%a5" aria-label="這個段落的連結"></a></h3>
<p>不管是否願意，主持 Daily Scrum 時一定要了解每個人具體的狀況；原本專注在自己任務的人，也會因為主持 Sprint Review、Retrospective 而強迫了解整個專案，並更加認識團隊。</p>
<h3 id="-scrum-參與度提升">Scrum 參與度提升<a class="h-anchor" href="#-scrum-%e5%8f%83%e8%88%87%e5%ba%a6%e6%8f%90%e5%8d%87" aria-label="這個段落的連結"></a></h3>
<p>因為 Scrum Master 是輪流的，如果我今天不給你面子好好聆聽跟報告，下次換我當 Scrum Master 時可能大家會不理我；同儕間的心理因素會讓參與度變得更高（但這個情形未必適用在每個團隊身上）。</p>
<h3 id="-回顧時發表更踴躍">回顧時發表更踴躍<a class="h-anchor" href="#-%e5%9b%9e%e9%a1%a7%e6%99%82%e7%99%bc%e8%a1%a8%e6%9b%b4%e8%b8%b4%e8%ba%8d" aria-label="這個段落的連結"></a></h3>
<p>由成員來做 Sprint Retrospective 時，大家相對來說更敢發表意見；這就跟同學分組討論時比較熱絡，但當老師問同學有沒有問題時，台下直接靜音的道理一樣。</p>
<hr>
<h2 id="四總結">四、總結<a class="h-anchor" href="#%e5%9b%9b%e7%b8%bd%e7%b5%90" aria-label="這個段落的連結"></a></h2>
<p><strong>花的時間越多，就會越認真投入。</strong></p>
<p>其實並不是每位成員在剛開始的時候都願意跑 Scrum 的，因為他們覺得這是在浪費時間、單純走一個形式、對專案沒有幫助…</p>
<p>因此初期更像是每天集合匯報工作，直到要輪流當 Scrum Master 時，因為無法拒絕，所以每位成員都一定要有所了解，而這個過程促使團隊往好的方向發展（應該 🤔）。</p>
<p>當然還要更多時間來驗證，相信每次的 Sprint Retrospective 都能讓原本的流程更加完善。</p>
<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/202207/constantly-changing-requirements/</link>
      <pubDate>Thu, 07 Jul 2022 21:42:20 +0800</pubDate>
      <guid>https://deanlin.net/blog/202207/constantly-changing-requirements/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>團隊合作</category>
      <description>有些 PM 覺得跟工程師溝通很痛苦，甚至大腦會不時冒出這樣的想法：「明明只是修改一個小地方，為什麼總有各式各樣的理由拒絕跟拖延，就算答應修改，做起來也是一副心不甘情不願的樣子。」</description>
      <media:content url="https://deanlin.net/blog/202207/constantly-changing-requirements/images/constantly-changing-requirements-og_hu_3e60401d29677765.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>有些 PM 覺得跟工程師溝通很痛苦，甚至大腦會不時冒出這樣的想法：「明明只是修改一個小地方，為什麼總有各式各樣的理由拒絕跟拖延，就算答應修改，做起來也是一副心不甘情不願的樣子。」</p>
<p>其實大部分的工程師都是可以理性溝通的，但我們無法接受一直做「白工」和「重工」，今天筆者想透過一個案例來跟大家分享「客戶、PM、工程師」之間思維的差異，並提出可以改善的方案。</p>
<figure class="figure"><img src="https://deanlin.net/blog/202207/constantly-changing-requirements/images/constantly-changing-requirements-01.webp" width="1158" height="605" alt="圖片來自：123RF" fetchpriority="high" decoding="async">
  <figcaption>圖片來自：123RF</figcaption>
</figure>

<blockquote>
<p>本文提及之專案、人物、事件純屬虛構，如有雷同，實屬巧合，請勿對號入座。</p>
</blockquote>
<pre tabindex="0"><code>大綱
一、工程師說 Loading 太重，可以請你幫忙分擔嗎？
二、需求不斷變更，緩衝時間再多也不夠用！
三、可是客戶態度很強硬啊！東西真的不符合他們需求
四、整理不完的例外，變更不斷的需求
五、從源頭解決問題，不是每個問題都要靠程式解決
六、客戶未必具備工程背景，要協助他們表達需求
七、我們要如何調整，讓未來的合作更加順利
</code></pre><h2 id="一工程師說-loading-太重可以請你幫忙分擔嗎">一、工程師說 Loading 太重，可以請你幫忙分擔嗎？<a class="h-anchor" href="#%e4%b8%80%e5%b7%a5%e7%a8%8b%e5%b8%ab%e8%aa%aa-loading-%e5%a4%aa%e9%87%8d%e5%8f%af%e4%bb%a5%e8%ab%8b%e4%bd%a0%e5%b9%ab%e5%bf%99%e5%88%86%e6%93%94%e5%97%8e" aria-label="這個段落的連結"></a></h2>
<p>PM 反饋這個問題後，我打開專案管理系統，看那位抱怨 Loading 太重的工程師手上有哪些 Ticket，是否需要做適當的調整。</p>
<p>結果仔細一看才發現，儘管那位工程師在這個 Sprint 中只剩下 2 張 Ticket 尚未完成，但有一張「匯出 Excel 報表」的 Ticket 預估時程遠遠超過之前在 Sprint Planning 的預估（4➝15）。</p>
<p>因為剩下的 2 個 Ticket 都是這次 Sprint 的核心功能，且距離結束只剩不到 2 個工作天，因此 PM 希望我可以接手那個估時已經到達 15 小時的 Ticket，讓工程師專注處理剩下的 Ticket。</p>
<p>跟 PM 談到這裡的時候我覺得有點奇怪，之所以將匯出 Excel 報表的 Ticket 分配給那位工程師，就是因為他之前有實作的經驗，沒道理在這個地方卡這麼久。</p>
<hr>
<h2 id="二需求不斷變更緩衝時間再多也不夠用">二、需求不斷變更，緩衝時間再多也不夠用！<a class="h-anchor" href="#%e4%ba%8c%e9%9c%80%e6%b1%82%e4%b8%8d%e6%96%b7%e8%ae%8a%e6%9b%b4%e7%b7%a9%e8%a1%9d%e6%99%82%e9%96%93%e5%86%8d%e5%a4%9a%e4%b9%9f%e4%b8%8d%e5%a4%a0%e7%94%a8" aria-label="這個段落的連結"></a></h2>
<p>為了釐清這個問題，我跟 PM、工程師開了一個臨時會議，去了解是什麼原因導致一個不困難的 Ticket 花了這麼多時間。</p>
<p>此時我才從工程師那邊了解到另一個事實，其實對他而言，匯出 Excel 報表的功能並不複雜，<strong>Loading 太重的原因是客戶不斷變更需求，導致這個 Ticket 的估時不斷增加，但預計交付的日期並沒有延長，因此時間壓力會全部壓到工程師身上</strong>。</p>
<p>我在詢問這個需求變更的頻率有多高時，工程師表示把新版交付出去後，可能再過 3、4 個小時就會收到新的需求變更；儘管每次修改都不會花太多時間，但架不住這麼頻繁的更動啊！</p>
<blockquote>
<p>當需求變更導致一直做白工、重工，就可能讓工程師工作效率下降，甚至可能在完成功能後故意拖一段時間再交付；畢竟提早交付沒好事，只是讓自己的工作量變更多而已。</p>
</blockquote>
<hr>
<h2 id="三可是客戶態度很強硬啊東西真的不符合他們需求">三、可是客戶態度很強硬啊！東西真的不符合他們需求<a class="h-anchor" href="#%e4%b8%89%e5%8f%af%e6%98%af%e5%ae%a2%e6%88%b6%e6%85%8b%e5%ba%a6%e5%be%88%e5%bc%b7%e7%a1%ac%e5%95%8a%e6%9d%b1%e8%a5%bf%e7%9c%9f%e7%9a%84%e4%b8%8d%e7%ac%a6%e5%90%88%e4%bb%96%e5%80%91%e9%9c%80%e6%b1%82" aria-label="這個段落的連結"></a></h2>
<p>客戶花錢請我們做系統，當然是希望做出符合他們實際業務需求的產品；站在客戶的立場上，他們當然會用最嚴格的標準在看待每一個功能。</p>
<p>但站在我們的立場上，在人力資源固定的狀態下，每多一次需求變更，我們就需要花更多的時間與精力去完成，甚至導致部分同仁需要加班。</p>
<p>為了解決這個問題，我請 PM 跟客戶約一個時間，一起了解需求不停變更的原因是什麼，不然這樣一直改下去其實是在浪費彼此的時間。</p>
<hr>
<h2 id="四整理不完的例外變更不斷的需求">四、整理不完的例外，變更不斷的需求<a class="h-anchor" href="#%e5%9b%9b%e6%95%b4%e7%90%86%e4%b8%8d%e5%ae%8c%e7%9a%84%e4%be%8b%e5%a4%96%e8%ae%8a%e6%9b%b4%e4%b8%8d%e6%96%b7%e7%9a%84%e9%9c%80%e6%b1%82" aria-label="這個段落的連結"></a></h2>
<p>客戶是一個專門提供材料出貨的公司，在深入訪談後，才了解需求之所以會一直變更，是因為這個 Excel 報表始終沒有決定一個固定的版本，會這樣是因為過去客戶在填寫出貨單時沒有律定格式，同一個材料可能有 10 幾種表達方式。</p>
<p>過去沒有遇到這個問題，是因為之前的出貨單都是 Case by Case，所以他們材料名稱儘管不統一，但依舊能夠看得懂；可是如果把好幾張出貨單放在一起看，就會因為資料很難整合而產生許多問題，這也是客戶找我們做系統化的原因。</p>
<p>下面用手機來舉個例子，我們手機有前鏡頭，假使在出貨單上顯示：「前鏡頭、前置相機、front camera、Front Camera、frontCamera」我相信大家都看得懂這是指同一個東西；但如果管理階層想要知道公司這個月到底賣了多少個「前鏡頭」，下屬就需要畫很多時間做比對跟整合。</p>
<p>除了相機的案例外，這邊再舉一個螢幕的例子，每個手機螢幕的尺寸大小不同，因此出貨單上有各自的命名；當管理階層想了解這個月總共賣了多少個「螢幕」，下屬會因為出貨單的材料沒有階層的概念而整理到崩潰。</p>
<p>在了解客戶的痛點後，我們就知道這是因為過去「命名不統一、材料缺乏階層概念」導致的問題。</p>
<p>PM 一開始也是從這個方向去處理問題的，他先請客戶將期望的命名、材料的階層整理出來，然後請工程師依照規格去統整；儘管這個方案看似沒有問題，但因為客戶當時在填寫出貨單時，命名太過狂野，因此有非常多的例外需要處理，而每發現一個例外就要請工程師調整程式。</p>
<hr>
<h2 id="五從源頭解決問題不是每個問題都要靠程式解決">五、從源頭解決問題，不是每個問題都要靠程式解決<a class="h-anchor" href="#%e4%ba%94%e5%be%9e%e6%ba%90%e9%a0%ad%e8%a7%a3%e6%b1%ba%e5%95%8f%e9%a1%8c%e4%b8%8d%e6%98%af%e6%af%8f%e5%80%8b%e5%95%8f%e9%a1%8c%e9%83%bd%e8%a6%81%e9%9d%a0%e7%a8%8b%e5%bc%8f%e8%a7%a3%e6%b1%ba" aria-label="這個段落的連結"></a></h2>
<p>了解來龍去脈後，我想也許我們都把問題搞複雜了，既然我們都知道問題是在出貨單上，為什麼不要從源頭來解決這個問題呢？</p>
<p>如果出貨單的格式沒有律定，在未來同樣的問題還是會發生；因為出貨單上每天都可能會誕生新的名詞，而新的名詞會無法自動歸類，可以料想到就算現在符合客戶的需求，在未來還是會有許多衍生問題。</p>
<p>當然過去的歷史業障很難要求客戶調整，「統一名詞、確定階層」還是一個必要的工作；但也許我們可以先用過去的出貨單模擬客戶期望的 Excel，而不是不斷請工程師修改程式。</p>
<blockquote>
<p>若發現有缺少、錯誤的材料先記錄下來，累積到一定的量後再請工程師修正，不然他會改到瘋。</p>
</blockquote>
<p>同時為了讓錯誤的歷史在這個階段就停下，我們需要請客戶與填寫出貨單的部門溝通，律定「出貨單」填寫的格式。</p>
<p>如果涉及到客戶公司內部，盡可能讓他們「自行協調」，我們做好「引導的角色」就夠了，如果由我們向客戶的其他部門提出需求，那破局的機率非常高。</p>
<hr>
<h2 id="六客戶未必具備工程背景我們要協助他們表達需求">六、客戶未必具備工程背景，我們要協助他們表達需求<a class="h-anchor" href="#%e5%85%ad%e5%ae%a2%e6%88%b6%e6%9c%aa%e5%bf%85%e5%85%b7%e5%82%99%e5%b7%a5%e7%a8%8b%e8%83%8c%e6%99%af%e6%88%91%e5%80%91%e8%a6%81%e5%8d%94%e5%8a%a9%e4%bb%96%e5%80%91%e8%a1%a8%e9%81%94%e9%9c%80%e6%b1%82" aria-label="這個段落的連結"></a></h2>
<p>其實就算是公司內部的溝通也是不容易的，起初填寫出貨單的部門對律定格式這件事反彈極大，因為他們原本都做得好好的，現在變得要依規範行事。</p>
<p>在了解到客戶推行的困難點後，我們製作了一張高達數百個欄位的 Excel，並請客戶向填寫出貨單的部門展示，讓他們體會到混亂的格式造成什麼後果。</p>
<p>在這之後他們才理解為什麼格式需要律定了，也了解公司導入這個系統就是希望把流程標準化，減少報表製作的時間，不是想要刁難他們。</p>
<hr>
<h2 id="七我們要如何調整讓未來的合作更加順利">七、我們要如何調整，讓未來的合作更加順利<a class="h-anchor" href="#%e4%b8%83%e6%88%91%e5%80%91%e8%a6%81%e5%a6%82%e4%bd%95%e8%aa%bf%e6%95%b4%e8%ae%93%e6%9c%aa%e4%be%86%e7%9a%84%e5%90%88%e4%bd%9c%e6%9b%b4%e5%8a%a0%e9%a0%86%e5%88%a9" aria-label="這個段落的連結"></a></h2>
<p>儘管這個問題最後在多方的協作下圓滿解決，但其實中間有許多摩擦是可以在初期避免的。</p>
<h3 id="-tech-lead">Tech Lead<a class="h-anchor" href="#-tech-lead" aria-label="這個段落的連結"></a></h3>
<p>若發現某個 Ticket 的估時逐漸增加，要主動向工程師詢問實際狀況，因為有些細節在 Scrum Meeting 並不會提及。</p>
<p>若發現工程師在做重工、白工，要先釐清問題來源；不是每個問題都要靠程式解決，我們可以先嘗試跟客戶溝通。</p>
<h3 id="-pm">PM<a class="h-anchor" href="#-pm" aria-label="這個段落的連結"></a></h3>
<p>如果客戶提出的需求變更太過零碎、頻繁，可以先記錄下來，等累積到一定的量，或是明確需求後再交給工程師處理。</p>
<p>如果發現需求能用模擬的就先用模擬的，盡可能不要讓工程師把時間耗在有高機率做白工的需求變更上。</p>
<h3 id="-工程師">工程師<a class="h-anchor" href="#-%e5%b7%a5%e7%a8%8b%e5%b8%ab" aria-label="這個段落的連結"></a></h3>
<p>如果發現需求變更的內容不合理、次數太多，可以即時與 Tech Lead 反應，而不是用加班默默把需求的吃下來。</p>
<blockquote class="pullquote"><p>希望這個案例對讀者日後執行專案時有幫助，如果還有其他建議也歡迎留言分享喔～</p>
</blockquote>
<hr>
<pre tabindex="0"><code>工程師血淚史
▋ 團隊在系統開發上遇到了哪些問題
▋ 需求不斷變更，到底哪個環節出錯了(本篇)
▋ 當 Scrum Master 跟 PM 同時存在，權力與責任該如何區分？
▋ 如果沒有明確的開發流程，團隊將會無所適從
▋ 你知道對專案來說，README.md 有多麼重要嗎？
</code></pre>]]></content:encoded>
    </item>
  </channel>
</rss>
