Bad design

最近項目中有個需求是關於下載進度條的。原來我們在 cloud 上面下載文件,點擊下載之後,實際上要先計算出要下載哪些文件(因為可能包含文件夾,文件夾內的文件需要網路請求才知道),然後開始真正的多線程下載。我們把之前的計算階段稱為 calculating 階段或 preparing 階段,後面的下載階段稱為 downloading 階段。如下兩幅圖所示:

prepare_no_animation

download_blocks_style

以前在 calculating 階段,進度條上進度顯示為0,要等 calculating 結束,downloading 開始了進度條才會前進。這樣 calculating 階段 UI 看起來是沒有響應的,對用戶不太友好。現在我們要在 calculating 階段顯示一個 Marquee style progress bar.像這樣:

Snipaste_2018-01-18_14-09-50

本來這是一個很簡單的需求,progress bar是用 windows form 寫的,我們只需要在 calculating 階段的開始和結束分別設置 Marquee styleBlocks style 即可。但是項目中的 progress bar 做得比較複雜,做了很多封裝。在 download worker thread 中修改 progress bar 的進度是通過一個叫作 IProgressBarReporter 的介面來實現的。這個介面裡面定義了一個 TransferStatus 方法用來告訴progress bar當前下載了多少,然後設置好當前進度。

public interface IProgressReporter
{
...
void TransferStatus(int serviceId, string serviceName, string fileId, string current, double percent, double speed);
...
}

我一開始直接在 progress bar 初始化的時候設置了當前 style 為 Marquee,然後傳遞了一個設置progress bar style 的 callback 給 download worker thread。當 download worker thread 中 calculating 階段結束時再通過這個 callback 設置 progress bar style 為 Blocks. 領導說這有2個問題,一個是在 progress bar 初始化時設置 Marquee style 改變了以前的行為,可能會造成 progress bar 閃爍(實際測試並未出現閃爍情況);另一個是原來的代碼都是通過 IProgressBarReporter 介面來操作 progress bar UI的,加一個 callback 與之前的行為不太和諧。所以領導建議我在 IProgressBarReporter 介面裡面加一個改變 Progress bar style 的方法。不過這樣也有一個問題,就是這個 IProgressBarReporter 從名稱上來看是報告進度的,也就是在 Blocks style 情況下設置具體進度用的,把改變 Progress bar style 的方法加進來有一點名不副實。當然這個如果能夠忍受的話也沒什麼太大的問題。

不過,最後並沒有採用上面所說的2種辦法。因為我們發現這個 TransferStatus 方法居然還有一個功能是設置 progress bar style. 這個是在介面實現代碼裡面看見的。所以最後直接用這個方法在 calculating階段的開始和結束分別設置了 MarqueeBlocks style.

// this will make progress bar type marquee
progress.TransferStatus(0, string.Empty, string.Empty, Properties.Resources.PREPARE_OPERATION_LABEL, -1, 0);

由於這個方法,代碼改動很少,但我覺得這個方法確實是一個很壞的設計。因為它做了它聲明中沒有說明的事情。單單從名稱和參數上來看,你絕無可能知道它居然還能設置 progress bar style. 而且,即使你看了它的實現,也很難知道如何設置它的各個參數才能設置 progress bar style. 我想如果沒有找到以前使用這個方法設置progress bar style的代碼,我大概不可能這樣做。我想到了 《Effective C++》中說的一條:讓介面容易被正確使用,不易被誤用。這個介面的使用應該說非常令人費解了,其實應該重構一下的,不過已有的代碼都是這樣用的,估計領導不會讓我重構了。

發表評論

郵箱地址不會被公開。 必填項已用*標註