code

顯示具有 Software Engineering 標籤的文章。 顯示所有文章
顯示具有 Software Engineering 標籤的文章。 顯示所有文章

2017年11月27日 星期一

Software Testing 5 - Code Review and Defects

Code review

code review / inspection對找出defects很有幫助,不過實務上似乎很少進行。通常能透過code review找到的defects如下:

1. 缺少或是錯誤的comments
2. 重複性的code
3. 過於複雜的設計
4. 無法測試的路徑
5. 錯誤使用技術
6. coding errors (這啥?!)

 細分的話,其實code review還可以分成以下三類:
1. walkthru:
找個senior的幫你看一些部分,稱為peer review。

2. code review:
這是最常進行的,可能牽涉多個reviewers,主要檢查implementation。


3. inspection
這是最正式的code review流程,可以有以下腳色:

Moderator – works with author to schedule inspection, send out materials, runs meeting, follows up with author on follow-ups from inspection (often team lead or project manager)
·         Author – provides moderator with inspection material, explains material as needed, responds to questions, responsible for rework based on inspection comments
·         Reader – walks though the code, saying what it does in English and stops for comments on that piece
·         Reviewer – technical experts for the document being inspected; provides comments and questions

·         Recorder – one of the reviewers who agrees to document issues raised at the meeting; usually compiles a list with categories (defect, suggestion, comment, etc.) and distributes to all after meeting; opens internal defect reports to help track fixes


Defect Management

俗稱bug XD,就是不按照design發生的行為。

defect不一定能找出來,找出來也不一定要或能修改,修改後也不一定正確。
所以必須要有系統性的方法來面對defects,需要一個defect tracking system。

defect 可以有類似以下的tracking status:



Defect Report


defect reports不只是展現QA人員的專業,也是developers的重要資產。
defect report需要包含以下:
1. isolation: 切割出可以復現的操作方法
2. generalization: 即便切割出來,但仍需要考量此defect對整體性的影響
3. severity: bug分級定義,根據發生機率以及衝擊性

綜合以上,一個可能的defect report template長這樣:

Item
Description
Title
A unique, concise and descriptive title for a defect is vital. It will allow the defect to be easily identified and discussed.
Good : “Closed” field in “Account Closure” screen accepts invalid date
Bad : “Closed field busted”
Severity
An assessment of the impact of the defect on the end user
Status
The current status of the defect
Initial configuration
The state of the program before the actions in the “steps to reproduce” is to be followed. All too often this is omitted and the reader must guess or intuit the correct pre-requisites for reproducing the defect.
Software
Configuration
The version and release of software-under-test as well as any relevant
hardware or software platform details (e.g. Win 7 vs Win Vista)
Steps to Reproduce
An ordered series of steps to reproduce the defect
Good :
1. Enter “Account Closure” screen
2. Enter an invalid date such as “54/01/07” in the “Closed” field
3. Click “Okay”
Bad: If you enter an invalid date in the closed field it accepts it!
Expected behavior
What was expected of the software, upon completion of the steps to reproduce.
Good: The functional specification states that the “Closed” field should only
accept valid dates in the format “dd/mm/yy”
Bad: The field should accept proper dates.
Actual behavior
What the software actually does when the steps to reproduce are followed.
Good: Invalid dates (e.g. “54/01/07”) and dates in alternate formats (e.g.
“07/01/54”) are accepted and no error message is generated.
Bad: Instead it accepts any kind of date.
Impact
An assessment of the impact of the defect on the software-under-test. It is
important to include something beyond the simple “severity” to allow readers to understand the context of the defect report.
Good: An invalid date will cause the month-end “Account Closure” report to crash the system and corrupt all affected customer records.
Bad: This is serious dude!
(Proposed solution)
An optional item of information testers can supply is a proposed solution.
Testers often have unique and detailed information of the products they test and suggesting a solution can save designers and developers a lot of time.
Priority
An optional field to allow development managers to assign relative priorities to defects of the same severity
Root Cause
An optional field allowing developers to assign a root cause to the defect such as “inadequate requirements” or “coding error”



Root Cause Analysis

root cause analysis通常有助於降低未來defect發生的可能性,可能的種類如下:

Classification
Description
Requirements
The defect was caused by an incomplete or ambiguous requirement with the result assumption differing from the intended outcome.
Design Error
The design differs from the stated requirements or is ambiguous or incomplete resulting in assumptions.
Code Error
The code differs from the documented design or requirements or there was a syntactic or structural error introduced during coding.
Test Error
The test as designed was incorrect (deviating from stated requirements or design) or was executed incorrectly or the resultant output was incorrectly interpreted by the tester, resulting in a defect “logged in error”.
Configuration
The defect was caused by incorrectly configured environment or data.
Existing bug
The defect is existing behavior in the current software (this does not determine whether or not it is fixed).



2017年11月25日 星期六

Software Testing 4 - Test case, suite, report

Testing the design

requirement / documentation / spec 其實也可以test,主要針對以下五個方向去檢驗:
1. specific: 越明確越好
2. measurable: 能夠量化
3. testable: 其實就是1. 2. 的結果
4. consistent: 要跟先前的spec一致
5. exclusive: 把"不該做的"也明列出來。


non-functional (non-feature) test cases

非功能性的tests,包括:
1. usability
2. scalability
3. performance
4. security
5. logging
6. reliability
.
.
.
通常是functional test通過之後,才會進行non-functional tests。


Performance testing

舉performance testing來說,一個明顯困難點在於通常不能用production environment來測試,因為會影響營運,所以必須有一個test environment來模擬production environment。

此外performance testing重點在測試系統弱點,這屬於白箱測試,只有系統開發者知道哪些是可能的弱點,不要因為"政治因素"害怕去測試這些點的極限。

此外要有baseline當比較對象,因為有些時候performance improvement沒什麼太大意義,如果baseline profile已經達到,可能不需要投入資源去提升performance。

performance testing包括以下種類:
1. load testing: 測試在不同的load狀態下,系統有什麼behavior
2. stress testing: 找出系統能承受的最大capacity
3. soak(endurance) testing: 主要瞄準長時間狀態下,系統的在某個load的承受能力
4. spike testing: 這是測試突然增加極大load會讓系統產生什麼行為


Test plan的重要性

test是要規劃的! 不是自己隨興加減測試,事實上這是一個挑戰!
先要有個認知是: 100% coverage是不可能的。

事實上要把test plan當成一個project,所以也會有project management中需要考量的三元素: resource / budget / schedule

所以選擇測試標的,也是一個學問,可能的方向:
1. 趕時間做出來的item
2. remote data / api 接介
.
.

test coverage廣度: 盡可能發現系統中潛在bug
test coverage深度: 在某些容易發生bug的系統,大量重複深入測試


Test Suite

就是一堆test cases的集合,歸類成某一類。


Test report

可能包含以下項目:

1. scope: 測試涵蓋了那些範圍,也該列出未涵蓋的範圍
2. 測試通過標準: 那些問題一定要fix,test cases通過率
3. 測試方法
4. 最後結果
5. defects/status: 列出目前測試出來,尚未解決的defects

上面講的有點籠統,主要是還是要看相關人員想要看到資訊才能做後續決策。




2017年11月18日 星期六

Software Testing 3 - UAT (User Acceptance Testing) and Usability Testing

Human Testing

UAT就是提出requirement的user去驗證(validation)我們寫的程式是否符合他們requirement。
UAT test plan在design phase就會底定,UAT會在開發完成後進行。
UAT不只是以requirement為基礎來validate,也應該要以user scenario來驗證。

UAT的主要挑戰

如果定義UAT在開發完成後才進行,所以要改變需求或是feature是很困難的,通常是不允許的。

敏捷開發建議客戶參與開發流程的意味,事實上這是比較好的方式,漸進式mini UAT變成正式開發流程之一,要求UAT測試者簽署測試通過文件(formal acceptance),確保嚴重的design defects不會在開發結束才發現。


各種Acceptance Testing

不是只有UAT,還有:

1. Factory Acceptance Testing: 經銷商在供貨前測試
2. Site Acceptance Testing:在客戶端安裝後測試,主要是整合性
3. Operation/Production acceptance testing: 主要測試功能性
4. Compliance/Regulation acceptance testing:法規測試

Usability Testing

這是關於好用與否,主要領域是HCI / UX,在此掠過。


Alpha/Beta Testing

alpha主要是內部測試,beta是外部測試。
alpha階段應該就要找出工程上的major defects,讓beta階段著重在使用者回饋修改,因為beta階段可以算是模擬營運階段。


Software Testing 2 - Autotest and Statement Coverage

節省成本

長期來說,理想上寫一次test case卻能無限多次測試,這是非常節省時間與成本,又增進software robustness的方法。

多人共同開發的必須流程

特別是在agile methods的規範中,一天可能會release several times,每次integration回去main branch一定要經過大量的測試,此時需要auto test cases。


製作Auto test cases的代價

unit test很簡單,也很快速可以寫完,在開發過程就可以順便做完。
function test (integration test)則要花更多時間,因為他是要測試模組間的互動,以及一些code path,所以有時候其實手動測試會比寫一個function test快,視情況而定。

事實上 testing program 也是code,理論上所有開發流程都也該應用在test cases上,包括test the test cases!
不過這樣有點弔詭,理論上寫得夠清楚的話,test cases不需要再被test,要不然不就沒完沒了。

test cases也要被放入一個testing repository,就跟一般的code一樣需要版本管理與維護,這些都是成本!

如果test cases需要時常更改變動,那可能這個project不適合auto test,因為維護成本會大於效益。


Automate 什麼標的?

1. 有testing framework support的語言或是開發環境
2. 很穩定不常變動的requirement / spec
3. 重複性高的測試,regression bugs
4. 人類能力無法勝任的test
5. 多組input data / cross platform tests
6. concurrency
7. 花大量時間者 (可以auto test就跑回家睡覺)


JUnit

JUnit可以寫unit test也可以寫function test,語言當然就是Java,所以叫JUnit。

JUnit提供一些predicates,回傳某些條件的true or false,unit test最好只要測試一個predicate,這樣才能說是"unit test",否則如果使用了兩個以上的predicates,由於第一個predicate failed的話, JUnit就會停止測試這個test,那會讓測試者誤以為整體program的test failure很少的錯覺,因為同一個unit test中的其他的predicates都沒被測試到。


Code Statement Coverage

下圖的default constructor需要兩個test cases,分別測試constructor中的兩個instance variable值是否正確:


注意每個test case應該都只能測試一個值!
為什麼我們要測試這個相當簡單的assignment statement? 因為這是spec,如果未來有人改變了constructor中的assignment,就是違反了spec,則我們的test cases就能抓到!

test cases如下:




以下的second constructor需要四個test cases,分別是執行line32, 36, 39, 40,if statement不需要測試,因為那無法驗證什麼東西:


相對應的test cases如下:





通常我們不需要測試getters,因為他的執行是trivial顯而易見的:


以下這個method事實上只需要一個test case就可以測試所有statements line 59,62,63,65:


因為全部都是連動的。

test case如下:




Branch coverage

branch coverage重點在要執行過所有conditional statement的true / false test,在上面提到的constructor中:


這邊需要4個test cases來測試兩個if,else statement則是跟隨著第一個if被測試了。
如果同時做statement coverage的話(已經測試所有if 為true,以及else為true,共3個branch被covered),我們這邊只需要再做一個test case 來測試第二個if 是false的狀態即可。

同樣的,對以下的method來說,如果已經做了statement coverage,則branch coverage只要再加上一個while condition evaluates to false的condition即可:





Path Coverage

path就是測試所有method最後return的路徑,例如上述的constructor:


有三個paths: 兩個throw statement,以及都沒有throw exception,最後隱性的從Line41 return的path。



Data Coverage

這邊稍微紀錄一下data coverage,主要就是測試spec中的臨界值,光是statement coverage是無法測試到所有的臨界值或是極大小或是特殊值。

2017年11月17日 星期五

Agile Software Development 9 - Agile Methods 評比

Ugly (太過極端或是因咽忘食)

1. 不做早期requirement analysis與架構設計: 先期的analysis是必要的,不要太過火就好。
2. user stories不能取代requirement spec
3. test也不能當作requirement spec: 因為test cases不夠全面,是點狀
4. 忽略或是否認系統components之間的dependency: 幾乎是不可能independent
5. Scrum Master應該要寫code
6. TDD 代替analysis - 太極端
7. manager腳色被替代 - self organizing team是個理想,完全取消manager是個幻想
8. 不考慮未來extendibility/reusability - 太短視近利


Hype (不重要的主張)

1. pair programming - 之前說過了
2. 開放辦公空間
3. self-organizing team - 理想
4. 可持續性步調 - 我認為這是重要主張,只是時常現實面達不到
5. MVP - 這也是要看客戶需求而定
6. planning poker - ?
7. cross functional team - team內還是有專家的
8. embedded customers - 通常這類人員代表性不足,也很難在開發過程中產生作用


Good (agile methods中值得採用的方法)

1. acceptance of change - 闡明"改變"是軟體開發的本質之一,接受這個本質,甚至可以變成競爭力
2.  iterative development - 應該是"short"iteration才是重點
3. code是重點 -沒錯,不要一直"討論討論討論"
4. tests是重點 - 這真的是重點!!!!!!!!!!!!!!!!!!!!!!
5. 常態性regression tests
6. velocity - 給progress一個衡量指標
7. no branch - 這邊我不確定原因為何,看來作者同意multiple branches是個危險的設定,需要找更多相關資訊。
8. product burndown chart - velocity的視覺化,這讓所有參與者知道目標快達成(落後)了沒?
9. daily meeting - 有心理學上的意義


Brilliant (軟體工程中的高明見解)

1. short iterations - 哈,看來我看法跟他一樣
2. closed-window rule - 在iteration中不能改任何requirement / spec
3. refactoring - 不斷精進
4. 所有的functionality都該有associated test - 達到quality software的基本要求
5. 伴隨第一點就是以及no branch就是Continuous Integration


Quality is Key

and is King


2017年11月16日 星期四

Agile Software Development 8 - Artifacts

Artifacts (用來support agile practices的工具)

很怪的名字。


User Story

可以使用小卡片(story cards),用來表示最不可分割的requirement。



Task card: story card的companion task。

Use case

可以說是複查精確版的user story,用來描述如何透過系統中或外的各種互動來達成某個task / business goal,是UML diagram的一種類型:



Product backlog (Scrum)

包含以下功能:



Task board

這是product backlog的具體化:


所以trello介面基本上就是一個task board

Velocity (Scrum)

這是scrum嘗試要描述project progress的指標,可以用各種想要的指標,具體化的artifacts是burndown chart:


Bullpen (XP)

大開放空間,方便溝通,資訊流通。


2017年11月11日 星期六

Software Testing 1 - test basics

Validation & Verification

validation = 達到使用者的需求功能
verification = 做出來的需求功能,有正確implement

這兩個面向都正確,才能說這個software正確


好的Test Cases特徵

1. 一次只測試一個部分
2. 測試的目的必須要明確符合規範
3. 描述方式要簡單清楚
4. 範圍要小
5. 要獨立,不依賴任何其他test cases
6. 要最可能精簡
7. 要跟spec/requirement相關
8. 要能重複結果
9. 描述用詞要一致


Software Development Life Cycle (SDLC) model

理想上來說,testing應該要發生在SDLC的各個階段:
1. 需求分析階段:  分析需求是否能測試
2. 系統設計階段: 發展test coverage plan, 以及設計usability test
3. 實作階段: 實作unit tests / automatic tests
4. 整合階段: integration tests
5. 發布階段: UAT (user acceptance test) / usability test (scenario based)
6. 營運階段: regression test如果有任何code change

以上是理想狀態 XD


白箱與黑箱測試

白箱:測試者能 access source code,e.g. unit tests
黑箱:白箱的相反,e.g. UAT


Test Coverage

有三種coverages:

1. code coverage: 理想上是100% statement coverage,也就是所有的code都有tests“照顧”到。很多開發framework都有code coverage tools,例如Android Studio。

又可依照詳細程度分為statement coverage / path coverage / branch coverage

2. data coverage: 測試涵蓋一些代表性的input數據。我們通常不可能有100% data coverage,例如不可能測試所有的integers。不過可以測試一些特殊cases:


  • boundary condition - 各種邊界值
  • typical data - 代表性的input
  • pre / post conditions - input前後的facts
  • bad data - 測試不合API的值,例如null / 極多極少量 / 空集合 / 未初始化
3. model-based coverage: 這個採用分析整個程式與input domain來建立test case的測試模型,算是非常分析導向的,在此略過了,因為我現實上應該不會採用這樣的approach。


Unit Test

通常這是開發者的責任,可以視為開發過程跟寫code一樣重要的產出,某些agile methods可以讓testers跟developers一起合作寫出unit tests。

unit tests最好是很小的單位,例如function / method / class,而且最好能100% code coverage。
如果有100 code coverage,不能保證沒有bug,但是能提高code change時的信心與品質,特別是需要做refactoring的時候


Functional Test 

這應該就是integration test,測試整個program的inputs / outputs / features。
這可以算是黑箱測試,你要假裝不知道整個program的implementation。

當然最好是automated tests。

Design Patterns 3 - Structural Patterns (Composite / Proxy / Decorator )

Composite Pattern

看了這個影片,我終於懂了這個composite pattern在幹嘛了 @@
原來就是把fractal (碎形) 應用在software construnction中。

composite pattern其實就是一個tree structure,每個node (包含leaf)都是某個type,透過implementing某個interface,或是繼承某個super class:





non-leaf node就是另一個 subtree,由同樣type的nodes組成,所以這不就是fractal嗎???

不過這邊需要語言支援polymorphism,也就是在runtime時候,同樣的interface能流向不同sublcass定義的implementation。

composite pattern好處是,我們不用type-checking! 完全依賴polymorphism幫我們做事,而且建構簡單,整體邏輯性都很清楚。

舉例來說,我們定義一個interface讓所有"建築"都必須要遵從:


某個叫做"Housing"的subclass就是一個non-leaf node,因為他也可以由其他 IStructure type objects 組成 (composite of):


可以看到這個Housing class還有一個collection of other IStructures,因為它是一個Composite node,不是lead node,也就是這個Housing建築體是由其他IStructure建築體組成的:

如果是leaf node的話,定義為不由其他IStructure建築體組成,所以只要單純implement IStructure interface就好:



結論: 如果建構一個東西,是有fractal特性的話,那就使用composite pattern,不過這需要語言有polymorphism支援,應該所有的OOP都有吧,因為那是OOP的根本元素。



Proxy Pattern

某個class A的代理人或是替身稱為proxy,為何要使用proxy呢?

1. 耗運算或是硬體資源的物件,可以有個lightweight self / or cache當作替身
2. 防護性,讓外界接觸不到真正的物件 (讓子彈飛之黃四郎?!?!)
3. 遠端物件的local替身,這其實跟第一點也差不多
4. 當作任務dispatcher,implement額外的功能,分配給適當的A instances

這邊比較有趣的是,proxy是某個class A的替身(藉由讓兩者都implement一樣的interface,但是A是proxy的delegate,因為真正執行proxy的功能是要給A去做:


Decorator Pattern

這主要是要解決怎麼在runtime增加一個class的功能的難題。如果利用subclass / extension (swift / kotlin),則是在compile time才有辦法定義。所以這邊的邏輯就是“利用aggregation取代subclassing“。

藉由層層reference,下圖中C "has a" B,而B "has a" A,stack上層物件能增益其包含物件的功能:



注意A B C是同一個type (藉由implement 同一個interface)。

Decorator pattern要用實際例子來解釋比較容易懂。假設一個網頁的該有的基本interface如
下:

我們的網頁class (concrete class) BasicWebPage 也implement了這個interface:



現在我們想要runtime“增益augment"這個BasicWebPage class,讓他變成更多功能的網頁,我們需要一個abstract Decorator class,也implement了網頁必有的interface:



所以這個decorator是一個“網頁”(因為有implement WebPage interface),他的concrete subclass instance當然也是一個"網頁",所以只要這個subclass定義某個額外的功能(例如驗證身份),就擴增了網頁instance 的能力(變成可以驗證身份的網頁)。



注意這個Decorator的有包含basic功能的WebPage,所以就像前面stack A B C圖示所說,這是一個aggregation

另外注意這些decorator instances的display()透過呼叫了super.display(),層層往下傳到basic BasicWebPage class的display(),這是合乎設計初衷的,因為非擴充的功能應該要使用最原始的stack最下層的implementation

以下是UML diagram:



至於client要怎麼使用Decorator pattern才能runtime擴增功能呢?


1. 我們先建立了一個BasicWebPage instance,

2. 然後製作一個decorator AuthorizedWebPage instance去stack在 BasicWebPage上面,

3. 然後在stack AuthenticatedWebPage instance去stack在 AuthorizedWebPage上面

4. 由於這三個class都有implement WebPage interface,所以可以用同一個object reference指向這三個instance

5. 在呼叫display的時候,AuthenticatedWebPage instance先往下一直到底呼叫了 BasicWebPage implement的display(),這就是最基本的功能,然後往上return時,又由下而上層層執行了每個擴增instance所implement的display(),這樣就完成了Decorator的架構實現。



用Decorator的好處就是不用implement各種擴充功能的排列組合所可能需要的subclasses,而是直接stack各種功能就好。


2017年11月10日 星期五

Agile Software Development 7 - Testing Practices

Agility achieved thru Testing

agility = speed + quality,而quality只能透過不斷的testing達成。

Code and Tests 這是agile methods核心兩物體。


所有程式都一定要有unit tests (XP)

XP這個宣言是比較嚴格,但不見得是極端的宣言。
伴隨這個宣言就是,所有unit tests要通過才能進入下一個開發 phase。

所以這邊可以使用Lean中的Waste定義:沒有通過unit tests的code基本上就是waste!
這是要極力避免的。

YOU
    SHALL
          NOT
                PASS!!!!!


Test-first Development (XP)

使用tests來取代spec,也被generalize成一種開發方法,稱為test-driven development。


最主要的優點是,等於永遠保持最新的regression tests 定義!
regression test就是過往已經測試過但是failed的tests,開發過程中,一個已經解決的bug通常有機會因為code變動又出現了,所以如果採用test-driven開發的話,基本上等於一直在測試所有過去定義過的tests,也就是可以發現是否發生了failed regression tests。

Bug是沒有測試到的部分 (XP)

bug在test-driven development (TDD)眼中,重新定義成沒有被test cover的部分,所以要fix bug跟開發一個新的function一樣,先寫test!!!!

這其實是相當先進的觀念,我覺得能徹底執行一定很棒。

Root-cause Analysis (XP / Scrum)

這好像沒啥好說的,基本上fix bug本來就該知道root cause不是?

Automating User Acceptance Tests (UAT)

這其實就是automated tests,不過是以UAT 為出發點來寫test cases。這樣也能確保regression tests不會重啟問題。

另一個比較有趣的:可以出版UAT score給team知道,讓大家知道目前版本對過去automated UAT測試的狀態。


Agile Software Development 6 - Scrum Release Practices

Frequent Release Policy

這是agile的中心思想,而且這是執行spring / short iteration的必然結果。有時候甚至一天可以有好幾個release。


Continuous Integration

不間斷地透過testing把所有人的code保持整合(integrated / merged) 狀態。
好處:
1. 越小變動,越好整合
2. team每次整合都能學到東西
3. 早期發現問題可以小成本更動
4. 重複的模組可以早期消除

Small release / incremental deployment

這是上面兩個policy貫徹後的結果。


at most 10-min build

這是要讓 continuous integration 更順暢的方法,要不然每次build非常久的話,很難貫徹incremental integration/deployment。


Agile Software Development 5 - XP Development Practices

爭議的Pair programming

兩個人坐在一起programming:
1. 明確說出自己的邏輯
2. 兩個人互相砥礪 (監視 XD)
3. 腦力激盪

爭議在於這樣是否浪費人力?是否有提高生產力?
結果一些研究證明,pair programming並沒有較好的生產力。


Single code base (不要有任何branch)

這在現今的工作環境應該很少見了,我想好壞處都有,可能case by case吧。

Share Code (XP)

agile practices不建議讓code expertise只落在一個人身上,最好整個team都能了解。
這個變成禍福與共,以及減低人員流動造成的斷層風險。

Optimization Last

這個common sense。


Simplest Design and Refactor Often

這當然也是大家追求的目標


Incremental Design

這個容易被誤解,他主要精神應該是“不要太快抽象化(abstraction)”,例如太快決定要用什麼design pattern,因為design pattern就是一個高階抽象思考的代表。為什麼不要太快抽象化?因為有個“優先採用最簡單設計”為前提的思考,然後看program如何演變再來打造,這也隱含了deliver first, refactor later的概念。

不過批評者認為花時間做abstraction thinking才是一個好的programmer該有的特色,而且前期花的時間不會白費,當然deliver 時間會稍微晚一點 (相比於上段所描述)。


System Metaphor

用metaphor來思考系統設計? 有點怪。


Refactoring

也是老生常談了。


2017年11月8日 星期三

Agile Software Development 4 - Meeting Practices

Daily meeting (XP / Scrum)

每天早上15分鐘的站立會議,所有重要roles都必須要參加,主要focuses:

1. 描述昨日進度與今日規劃
2. 發現阻礙

每天描述進度是一個心理學技巧,讓人不至於說空話打混,因為每天都有人記得你昨天說了什麼,也能夠檢視。此外公開承諾會有心理壓力,可以克服拖延症。


Sprint Beginning meeting (Scrum)

Scrum sprint在開始之前會有最多一個整天的會議,上半天是讓product owner + team member  討論出"product backlog",分出product features的輕重緩急。
下半天是team內針對product features決定tasks,並且分出輕重緩急,產出"sprint backlog"。

Sprint End meeting (Scrum)

這稱為retrospective meeting,所謂對內的檢討大會,參與者當然就是所有的team members。主要討論這個sprint做對了或是做錯了什麼事。

最多三小時。

Review meeting

這是對外的成果檢討會。


簡單來說,各種會議主要就是幫助sprint推動往更好的方向。

2017年11月7日 星期二

Design Patterns 2 - Structural Patterns (Facade / Adapter)

Facade Pattern

facade的中文是"建築物正面",在軟體系統中代表進入某個subsystem的入口,所以使用facade pattern主要是在一個大型複雜的系統中,提供每個subsystem一個"店面入口",但是把店的整個複雜度都隱藏起來。

算是一個中間wrapper class,client透過此facade class來使用subsystem。

未使用facade的client,可能需要分別跟所有subsystems (存款 / 支票 / 提款)打交道:



如果把這些subsystems統一包覆在某個 facade BankService:



其實facade應該是鰻直覺的,多數人即便沒學過facade應該直覺會再包一層,不會讓人直接面對subsystems,因為同理心想像自己是client programmer的時候,應該會瘋掉吧。

注意對不同subsystems來說,他們都需要implement一個IAccount interface,這主要是讓facade class與subsystems溝通用,也就是facade class也不需要知道subsystems的specific implementation:


再來就是facade class的定義。實務上,subsystems有很多功能,facade class可以選擇性包裹要那些功能給client看到就好:



client code就是乖乖使用facade export出來的functionalities,完全不會直接跟subsystems打交道:


優點
1. information hiding: 把subsystem相關資訊隱藏起來
2. decoupling: client code跟subsystem implementation無關
3. simplified interaction: client code不需要跟複雜的subsystems打交道


Adapter Pattern (轉接器)

ps2 轉 usb 的轉接器就是一個adapter。
在軟體工程上,兩個system之間的input/output可能缺乏可以溝通的介面,例如型態不同的問題。簡單來說,adapter pattern就是一個中間翻譯的腳色,讓client能透過target interface介面與提供資源存取的adaptee溝通:



舉例來說:WebClient想要存取WebService,但是不能接受Json格式,此時就需要一個WebAdapter class去implement WebRequester interface,讓WebClient能透過此interface 存取WebService:



WebRequester interface可能長這樣:

WebAdapter部分,可以看到它implement了target interface:



Client部分,使用了target interface:



整個program長這樣:


可以看到client根本不需要知道adaptee (service)是什麼,他只在乎adapter能否讓他透過target interface得到他想要的服務。Adapter基本上就是把adaptee包覆起來,是一個wrapper class

所以adapter class主要用在當我們沒有權力改變adaptee的interface的時候(通常這都是第三方的library或是REST API),並且也不想改變我們自己(client)的interface的時候,因為通常我們自己的interface也被其他人或是subsystems使用,改變會造成連鎖的改變需要。


Agile Software Development 3 - Roles

Agile最醒目的特徵就是redefine manager!!!

傳統經理人工作

1. 設定工作目標
2. 設定交期
3. 分派任務
4. 與高層溝通
5. 與客戶溝通
6. 檢驗客戶需求
7. 檢驗工作成果
8. 強制交期
9. 輔導訓練
10. 規定方法與規範


Strict Scrum的3種腳色

scrum的最大貢獻是在管理方法的改變上,完全廢除了manager的腳色。

1. self-organizing team
(a) cross functional: members有專業交集,不會有一人獨占某個專業或是事項
(b) 心理學研究較好組合 5~9人
(c) 對某特定sprint (iteration)規劃目標與實作
(d) team自己分配工作
(e) 能嘗試任何方法,只要方向朝向結果
(f) sprint結束後,向product owner展示工作成果

可以看到team已經分擔了傳統經理人不少的工作,其中又有"core members/participants" 以及 "fellow travelers"兩種投入程度不一的腳色,主導者主要應該是core members,而fellow travelers可以在被諮詢時發表意見,但不參與主導腳色。

2. product owner


比較像是project manager的腳色

3. scrum master

這個比較像是manager的腳色,主要目的是確保Scrum被正確的推動:

關於scrum master不參與開發(真的寫code)是蠻有爭議的,不見得每個scrum implementation都會採用這種認知。


這邊要特別講一下什麼是impediments,就是任何讓team開發速度慢下來的事物,包括:
1. 硬體資源不足 (SSD?!?!?)
2. requirements不清楚
3. 軟體資源不足 / 測試資源不足
4. 高層干預
5. 官僚制度


Other Roles

1. expert-users: Crsytal提出一個腳色為真的user但是對整個產品或是project能提供專業意見者。

2. Customers: XP提出customer是一個重要的腳色,這其實跟exper-users差不多。主要就是在開發團隊中要有一個user/customer的腳色提供意見。

3. developers: 這好像不用多說吧

4. trackers (XP,Scrum):tracker在追蹤一個重要的指標稱為"velocity",定義為理想的task完成時間 / 實際task的完成時間。此外還包括velocity改變, 加班時數, failed tests比例,這些都是tracker用來評估project進度的重要指標。

5. coach: 這個其實就是Scrum master,包含以下責任:









2017年10月28日 星期六

Agile Software Development 2 - Agile Principles

Waterfall (1970, Royce) :

就是五十年後我們仍然最常用的model。




這是很理想性的,甚至只能是教育性的,主要問題:
(a) coding phase來的太晚,software只關乎coding成果,結果真的實作卻是放在如此後面的流程
(b) requirements一旦決定之後,基本上進入program design之後就不能改變
(c) 現實中的維護maintenance phase沒考慮到,但實際上佔了軟體工程成本的70% (?)


Agile view on Requirements

對requirement的agile 方面的批評是
1. requirement實務上是常改變(changing)的,太早固定只是自以為是
2. requirement文件基本上是個浪費(waste)

XP: 蒐集requirements是一個經常性的動態活動,而非產出一個靜態固定的文件

Scrum: 沒有前期的analysis / design phase,而是一直處於不斷的sprints cycle來蒐集requirements

Lean: 看不懂!


總之,agilist 認為requirement gathering phase不該太長,也不該是靜態性的結束。(不過要注意很多自認apply agile methods的人,過分低估前期的requirements gathering,造成工程上的大災難)。


Common Agile Principles (只是參考,不該形成教條)

1. 顧客為主:XP希望引入顧客成為team member (embedded customer),但實務上很難找到這樣的顧客,而且顧客有可能代表性不足。Scrum: 定義product owner來取代傳統manager,這是體制內的角色,比起embedded customer來說較為權責相符。

2. Accept Change: 這對應到OOP中的extendibility,但是實務上不一定能簡單做到。

3. self-organized team: 這仍是對manager角色的弱化,manager主要功能在agilist眼中:
  • 鼓勵進度
  • 幫忙找出問題
  • 移除障礙
  • 對困境提供協助
  • 鼓舞成員,抵消負面批評
  • 授權team member能直接面對客戶

4. 可持續步伐:不要壓榨才能長久

5. 只做出使用者要的feature,不要做自己想像的: 降低複雜度,也省非常多錢 (亂做一堆features會使得cost非線性成長)

Toyota的車廠管理衍生出Lean management,以下是幾種可能的"software waste":


(a) 就是產能過剩,做出沒人要的東西
(b) 庫存太多,做了不賣浪費時間浪費錢,打擊士氣
(c) 做一堆對產出產品無用的步驟
(d) 技能或經驗不足所以花一堆時間在蒐集資訊
(e) 沒被找出的bug costs money!
(f) 等待相關人士給予意見
(g) 不同framework之間的協調時間

極簡者 / 短視者 觀點: minimum viable product / 不需要中間產物 (文件 圖片等)。但這也招致了不少software engineering從業者的批評,本課程認為這些觀點過於極端,不是好的software engineering。

6. iteration時間縮短但是更多,iteration過程中要freeze requirement

傳統的development iteration的模式是先建立infrastructure,然後一層層往上疊起,但這就讓usable product/code 能出現的時間往後延長了不少:


agilists preferred的方式是快速但partial functional的release:


不過這門課老師覺得可以採用dual development,首先對risk最高的底層infrastructure花全力去完成 (比一般agile iteration更長),之後才進入agile iteration。


7. 所有tests未通過前,不要implement new features
這個被列為最重要的agile教條之一,但是實務上我覺得要怎麼推動是一個問題,如果tests都是類似unit tests,那應該是比較容易推動。

8. use cases / scenarios 來描述requirements
好處是這讓測試的規格確定,同樣老師批評:




Lean specific principles

Lean的waste觀點:


這是一個不錯的negative impact checklist,可以實際用來檢視專案是否有浪費的情況。

Lean的learning觀點 (這是積極採取行動,透過資訊蒐集):


1. test給我們關於code的更多資訊
2. 嘗試各種solution會比寫文件或是花時間規畫能得到更多的資訊

以上五點其實就是讓我們盡量在開發時獲得資訊最大化的方法,agilist也希望能delay decision making,直到更明確information獲得之後,所以他們不喜歡大量的事前planning,但是要小心可能造成拖延症! 這個拿捏可能跟經驗有關



Crystal specific principles

Crystal方法主要focus在"focus" XD

1. 不要讓developer multitasking,避免分心
2. 不要中斷developer的開發連續流程,至少保持兩小時不打擾
3. team需要明確知道goal是什麼,只focus在goal

4. 人本尊重 (鼓勵發表意見的安全感,不受嘲弄)


XP specific principles

1. 人本尊重

  • 安全感
  • 成就感
  • 歸屬感
  • 成長性
  • 親密感(?!)



Lean / Scrum specific principles

天下武功,為快不破。要對要建立在快速information gathering
每個iteration中,盡快給出end product,獲得feedback,進入下一個iteration。

Scrum specific principles

user stories (requirements)認為是可以獨立存在的,不依賴其他的user stories。
這就是所謂的feature independence。

不過這還是case by case。