TopCoder Component Development Tutorial(組件開發說明書)

【寫在前面】

    想研究TopCoder整點小外快,翻來找去只找到 @Xviewee 在2008年翻譯的文章,由於年代久遠,我對TopCoder組件開發說明書更新到最新版,看他的原文點這裏,首先對他的工作表示感謝!
    TopCoder Component Development Tutorial 英文版原文看這裏
    如果發現本文有任何錯漏敬請告知,感激不盡。
    本人小菜,想着能在TopCoder上攢經驗順帶掙些小錢,若能有大神可以指導一二,帶一帶上路,感激不盡。
    此外,如果有志同道合的朋友們可以一起交流開發經驗,那是再好不過了,一起爭取早日進步嘛。
    最後說一句,轉載請註明出處,謝謝。

1  簡介(Introduction)

1.1   TopCoder組件開發

   TopCoder使用包括 C#、Java、C++、Ruby、Flex、JavaScript 在內的多種語言,儘管這語言有較大差別,但開發過程都差不多。本指南將由始至終涵蓋整個開發過程。在不同語言差別較大的地方,會分別給出相應的說明。

1.2   開發流程

    總體上說,TopCoder組件的開發流程比較簡單。你的任務就是按照組件設計文檔開發組件並交由評審團(DesignReview Board)進行審查。通過審查稱爲優勝者之後,你還需要根據審查團提出的整改要求對組件進行修正,最後通過終審(Final Review)就行了。

    TopCoder 提供了很多關於設計和開發流程的文檔(對於某些簡單直接的組件,設計這一步驟會被省略,此時你獲得的會是需求說明書而不是設計文檔。),你需要仔細閱讀軟件開發文檔。包括成員指南(Member Guide)、開發設計(DevelopmentDesign)、審查記分表(Review Scorecard),這些文檔告訴你到底要提交些什麼。

1.3   所需軟件

    你可以在任何環境下編寫你的代碼,但是我們依靠特定的技術構建組件並對其打包;另外,我們還需要每種語言的公共庫,具體包的列表如下,除此之外還有一個UML公用工具

1、C#:

(1)  Microsoft .NETFramework v3.5:如果你喜歡用C#進行開發, 你可能已經安裝了此工具。

(2)  NUnit:這個框架可以讓你簡單快速的測試你的代碼,有關測試的內容後面會詳細描述。

(3)  MSBuild:微軟和VS的構建工具,有關構建的內容後面會詳細描述。

(4)  TC CodeDocumenter:一個編寫API文檔命令行工具,類似 JavaDoc。

(5)  NCover:代碼覆蓋工具。

2、Java:

(1)   SunJAVA SE 5.0+:Java開發要注意使用最新的JDK。

(2)   Ant:一種執行可定製、可擴展構建腳本的工具,你需要用它編譯工程和向 TopCoder 提交代碼,後面會細說構建腳本的內容。

(3)   JUnit:用於單元測試,具體內容後面說。

(4)   SunJAVA EE:只有少數組件需要用到這個包,具體看需求文檔。

(5)   Checkstyle:一種格式檢查工具,提交之前最好用他來檢查一下你的代碼。

(6)   Cobertura:Java代碼覆蓋分析工具,用來檢查你的代碼被單元測試覆蓋的百分比。

    確保系統環境符合MSBuild/Ant 的需求,注意xUnit的安裝位置,隨後的構建腳本配置裏面會說明。

1.4   註冊

    參加開發競賽之前,你必須在 TopCoder公司網站上註冊。註冊之後,你不僅可以提交你的設計和開發作品, 而且可以參加其他 TopCoder 競賽,包括算法(algorithms),概念模型(conceptualization),規格說明書(specification),架構(architecture),應用裝配(application assembly)以及測試(testing)還有馬拉松賽(marathon),點擊這裏註冊。

2  挑選項目(Picking A Project)

    項目選題是競賽取勝的第一步,你可以在這裏找到所有開放的程序開發競賽。該頁面中,你可以看到項目的開放情況、註冊、提交的截止日期。這些日期非常重要,你必須在註冊截止日期(Registration End)前確定你對哪個組件感興趣,並在提交截止日期(Submitby)前提交你的作品,包括測試文件和文檔。

    作品第一名獲得獎金,第二名獲得一半獎金,評分標準分值名爲“DR point”,有關他的更多內容看這裏

2.1   項目細節

    點開你感興趣的項目,你會看到有關這個項目的更多細節。包括項目信息、文檔鏈接、論壇鏈接、報酬信息以及綜合時間點。

2.2   決定是否參加

    找到感興趣的項目之後,第一步你要詳細查看項目設計文檔,最簡明的文檔就是需求規格說明書(Requirements Specification),它包含這個項目會用到的各種技術的信息(如SSL,LDAP,ODBC 等)。如果你依然興趣不減,可以繼續閱讀組件說明書(Component Specification),它包含了實現這個組件的更多細節信息。當然,還有其它一些文檔,但是這兩個文檔對決定一個項目是否適合你是最重要的。

    選擇一個項目之前,請確保你有足夠的時間完成它。項目期間,你是否有其他的安排和工作要做?另外,項目可能會用到一些你並不熟悉的技術。你知道在C#中怎樣使用數據庫連接嗎?你知道怎樣使用java.lang.ref 類庫嗎?你充分了解完成這個組件所需要的網絡協議嗎?最好重新閱讀一下組件說明書的1.2、1.3 節和第二節,確保你對所用到的技術比較瞭解。

2.3   項目註冊

    現在,你發現你可以勝任並有時間去完成某個項目,就可以註冊了。點擊項目細節頁面的註冊鏈接進行註冊。

3  項目啓動——環境配置(Getting Started--Environment)

    完成註冊後,你將有權限訪問項目提交程序,並且可以參加組件的開發人員論壇。

3.1   項目提交及評審

    項目提交和評審是你參加程序設計和開發競賽的核心樞紐。通過這個應用程序,你可以上傳你的作品,查看評審得分。點擊這裏登錄,你可以看到自己所有開放的項目及其狀態。點擊相應的項目名稱可以查看該項目的時間表和其它細節信息。在頁面底部,有一排對應項目當前狀態的按鈕。另外,還有一個“Contact Product Manager”按鈕,你可以隨時點擊該按鈕向項目經理(Project Manager,PM)發送問題、評論、投訴以及其他信息。

3.2   開發者論壇

    項目細節頁面上有一個指向其開發論壇的鏈接。絕大部分關於項目的交流、討論將在此處進行。你可以使用你的 TopCoder 賬戶、密碼登陸所參與項目的論壇。如果不能登錄,請及時與項目經理聯繫。

3.3   開發包

    開發人員論壇主要包括四部分:設計階段文檔(Design Phase Documents)、設計階段問題(DesignPhase Questions)、開發階段文檔(Development Phase Documents)和開發階段問題(DevelopmentPhase Questions)。你可以在開發階段文檔下找到開發包,其中包含所有與項目開發相關的文檔和文件。

通常,Java 開發包是jar 文件,.NET 開發包則是zip 文件,它們都可以用普通的解壓工具解壓。

3.4   目錄

/conf:此目錄如果存在,則會在此目錄包含組件的配置文件,有時還會包含所依賴組件的配置文件,或組件設計者寫好的配置文件的例子。如果在設計階段沒有創建這些文件,開發包裏面將沒有這個目錄。

/docs:此目錄包含組件當前的所有文檔。包括 .tcuml 格式的 UML 設計規格,需求說明書和組件說明書。有關設計文檔會在後續章節中詳細介紹。

/src:當你完成這個項目的時候,此目錄應該包含了所有源文件。開發包通常只包含一個目錄框架。開發者負責填充源文件,這將在後續章節詳細介紹。

/test_files:此目錄包括組件測試過程中用到的全部文件。包括測試所需的特殊配置文件、輸入/輸出樣例、數據庫方案和其它任何非編譯文件。開發包中一般會包含設計者創建的樣本測試數據。

1、Java:

/META-INF:這個目錄由jar 打包程序生成,可以忽略。

/build.xml:這是一個缺省的,可能未加配置的構建腳本。構建腳本的內容會在後續章節詳細介紹。

/build-dependencies.xml:這是一個包含了組建的依賴、定義的構建腳本碎片,相關內容隨後詳述。

/build.version:包含了項目元信息的配置文件,包括名稱、版本、源目錄以及包定義。

2、C#:

/<projectname>.sln:一個VS解決方案文件包含以下兩個項目。

/ComponentSources.csproj:這個項目文檔包含了主要源代碼(在主目錄裏)。

/ComponentTests.csproj:這個項目文檔包含了測試源代碼(在測試目錄裏)。

/Build.dependencies:項目的依賴性定義,隨後詳述。

/Build.version:包含項目元信息的配置文件,包括:名稱、版本、源目錄以及包定義。

/README.txt:這個文件描述瞭如何裝配和構建這個組件。

3.5   設置開發環境

    首先,你需要設置一個工作目錄。例如C:\working\、C:\proj\、~/projects/;任何你覺得合適的地方。建議爲 TopCoder 項目建立一個新的目錄,防止混亂,避免提交一些錯誤的文件。在這裏,我們假定工作目錄爲/proj/tc/。

    確定了工程放置的目錄,就可以解壓開發包了。目錄 /proj/tc/projectname將是你的工程目錄。這裏,我們假定工程名字爲 tutorial_gen。

    下一步是配置構建腳本。記住TCS不會使用你的構建腳本,不要在它上面花太多時間。按照下述說明修改路徑和庫文件引用即可。如果遇到很棘手的問題,你可以向項目經理覈實。

1、Java構建腳本——build.xml

    你需要在構建腳本里配置cobertura 的路徑,把註釋部分修改成正確的值,大部分情況下,這樣就已經可以了:

            <property name="cobertura.dir"value="${ext_libdir}/cobertura/1.8"/>

2、Java構建腳本——build-dependencies.xml 

    如果你無法添加JUnit 的 jar 包到你的 classpath 裏,那麼就需要把它放淨構建腳本里,去掉下面的註釋,並把路徑修改成正確的值:

       <property name="junit.jar" value="${ext_libdir}/junit/4.6/junit.jar"/>

    如果你的工程需要額外的庫文件,你需要在構建和運行前通過配置構建腳本來解決這個問題。在腳本中,應該有些註釋掉的庫文件的例子。

       <property name="spell_check.version" value="1.0"/>
       <property name="spell_check.jar.name" value="spell_check.jar"/>
       <property name="spell_check.path" value="spell_check/${spell_check.version}"/>
       <property name="spell_check.jar" value="${tcs_libdir}/${spell_check.path}/${spell_check.jar.name}"/>

    這樣,稍作修改即可對庫文件的不同版本進行配置,你可能已經注意到了對${tcs_libdir} 的引用。它應該在腳本文件的開始部分就已經做了如下定義:

       <property name="tcs_libdir" value="lib/tcs" />

    這個配置將在/proj/tc/tutorial_gen/lib/tcs/spell_check/1.0/spell_check.jar尋找拼寫檢查的庫文件,你可以按需要修改構建腳本里面的一些路徑或者文件名。

    你必須將你的組件構建和運行時所要用到的所有包都包含在內,雖然這部分工作可以依賴classpath,但將所有需要的包在這裏配置好是一個好的習慣。

    有關 TopCoder 的目錄依賴關係可以看這裏

3、Java——topcoder_global.properties

    或許你已經注意到,開發包中的build.xml 包含對文件“../../topcoder_global.properties”的引用。通過這個文件,你可以設置一些不隨組件而變化的屬性,如JRE1.3 的路徑。

    格式很簡單(適用於所有的Java 屬性文件):propertyname=value

    首先,在工程目錄下創建 topcoder_global.properties文件(如果當前工程是 /proj/tc/tutorialgen,你的屬性文件將放在 /proj/tc 下面)。現在,你可以設置對所有構建腳本的通用屬性。

    對於JRE,你可以添加:

         java_1_3_bootclasspath=C:\Program Files\JavaSoft\JRE\1.3.1_10\lib\rt.jar

    你也可以添加註釋:

         # I need a comment to remember what this means.
         java_1_3_bootclasspath=C:\Program Files\JavaSoft\JRE\1.3.1_10\lib\rt.jar

    還可以使用擴展屬性:

         java_home=C:\Program Files\JavaSoft\JRE\1.3.1_10
         java_1_3_bootclasspath=${java_home}\lib\rt.jar

    需要注意的是,topcoder_global.properties引用在build.xml 的最起始部分。這意味着build.xml不會在你的配置文件裏進行擴展(因爲還沒有定義)。此外,topcoder_global.properties 中設置的屬性會覆蓋build.xml中的屬性。想了解更多相關信息,請查看Ant文檔

4、C#構建腳本

    有關兩個項目(組件源碼和測試源碼),有一些宏觀上的構建目標,但都沒有包含在開發包裏,你可以點擊這裏下載到他們。下載完成之後解壓,把目標文件放到你項目的父目錄裏。例如你當前項目的路徑是 /proj/tc/tutorial-gen,你的目標文件就應該放在 /proj/tc 裏面。

    MSBuild腳本很容易配置,因爲項目文件可以直接用VS打開,直接打開解決方案文件,把兩個項目添加到你的目標項目作爲項目引用依賴,就完成了。

    項目依賴可以通過手動的編輯 Build.dependencies 文件來完成。找到源碼或測試源碼的相應部分,在包含有依賴關係的 ItemGroup 部分添加你的項目需要的東西,例如:

    對於TCS組件:

       <Reference Include="Hera.EPC.Data, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
          <SpecificVersion>False</SpecificVersion>
          <HintPath>lib\Hera.EPC.Data.dll</HintPath>
       </Reference>

    對於第三方庫:

       <Reference Include="log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905">
          <SpecificVersion>False</SpecificVersion>
          <HintPath>lib\log4net.dll</HintPath>
       </Reference>

    對於 .NET 系統庫:

       <Reference Include="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
          <RequiredTargetFramework>3.5</RequiredTargetFramework>
       </Reference>

    可能還有另外一些由設計者或者項目經理提供的設計文檔,例如配置示例以及數據庫設置。

3.6   開發過程

    正如第一節所述,你在開發過程中的角色就是實現已經創建並通過審查的設計。你應該嚴格遵循設計文檔中給出的公共API。未經項目經理和/或設計者許可,你不得擅自修改組件的公共API,包括增加或刪除public 類、方法和接口。這並不是說設計會毫無瑕疵;恰恰相反,所有的設計都有改進的空間。然而,對設計的不同意見要在設計中修正,而不是開發。在開發實行的過程修正設計方案是不合適的,除非其存在致命缺陷。TopCoder 會對設計的任何改動進行細緻審覈。

    如果你對下個修訂版有任何的改進意見和見解,請在論壇上指出。開發過程中遇到的問題也請立即在論壇上提出來。設計上的任何衝突和問題越早明確,就能越早解決。如果可能,可以閱讀一下設計論壇中的相關討論,可能這個問題已經提出並被解決了。再強調一次,如果你發現任何沒有解決的問題,請在論壇上提出來

    上面所說的一切,都是爲了鼓勵你們儘可能的做出改進。如果你能把 public類的行爲分解成私有輔助類,那就去做!如果你能提出一個更加有效的算法,那太棒了!設計中你不能改變的只有公共API 及從用戶角度來說組件的行爲。對於一個組件,一般來說,你不可以改變“是什麼”,但是有一定程度上改進“怎樣做”的自由。

3.7   開發創新

    不同的設計允許不同程度的開發創新。其一方面是設計本身複雜度的原因,另一方面是設計者的方法問題。或許有的設計方案對組件描述的如此徹底,以至於組件編碼變成了將組件說明書中的僞碼翻譯成合適的程序設計語言。或許有的設計方案僅僅給出了公共API 的定義,而將實現細節留給了開發人員。大多數設計方案則是介於這兩者之間。

    方法體的具體實現一直是程序開發者展現才華地方。對某些設計方案,添加private 或packageprivate的方法、構造函數,甚至設計文檔中沒有明確說明的類都是可行甚至必要的。如果你真要這麼做,請確保這些改動是必要而且適當的,因爲這些地方可能會引起評審團額外的注意。開發人員所添加的內容(和組件中的其他元素一樣)應有最小作用域,並且予以與其用途一致的最嚴格的訪問控制權限。對於一個任務,確保採用最恰當的對象或者基本數據類型。

3.8   生成佔位程序(Stubs)

    具體開發的第一步是生成站位程序。站位程序是可編譯的代碼框架。其中你可以找到函數體;然而,這僅僅是一個站位程序。這些站位程序刻畫了組件的全部API,但並沒有實現其內部邏輯。TopCoder 使用的UML工具可以幫你生成佔位程序。你獲得的這些站位程序很可能無法成功編譯,需要你對它們稍加整理例如在 .NET 組件中可能存在一些設計人員添加的針對系統類型的代碼,這些東西你要刪掉才行。

    站位程序的另一個問題是關聯部分。UML 文檔裏面的一些關係(例如聚合、組合)可能會被不適當的轉化成了代碼。程序開發人員負責維護API 文檔(UML 文檔和組件說明書)和可編譯代碼的一致性。

3.9   項目結構

    工程的源代碼應該放在項目的 /src 目錄下,且應具以下結構(在示範項目的 /proj/tc/tutorial_gen/ 目錄下):

路徑

描述

conf/

所有必須的配置文件

docs/

和工程有關的所有文檔

lib/

所有本地庫文件

src/

所有源代碼(包括測試代碼)

test_files/

所有非編譯的用於測試的文件

1、Java

    組件代碼放在/src/java/main/目錄下。你需要根據包名來組織你的源代碼。例如,如果組件是com.topcoder.util.tutorial ,那麼源代碼路徑應該是/src/java/main/com/topcoder/util/tutorial/。下面是典型的Java 路徑:

路徑

描述

lib/tcs/spell_check/1.0/spell_check.jar

對於這個例子,這裏表示 Tutorial Generator項目依賴的庫,你的組件可能不需要任何依賴庫,也可能依賴多個

src/java/main/

組件有關的所有代碼應該放在這裏

src/java/main/com/topcoder/util/tutorial/

對於這個例子,這裏是放佔位程序的好地方,對於你自己的項目,這個路徑會有所不同

2、C#

    組件代碼放在/src/csharp/main/目錄下。你需要根據包名來組織你的源代碼。例如,你的組件是TopCoder.Util.Tutorial.dll ,你的源代碼路徑就是/src/csharp/main/TopCoder/Util/Tutorial/。儘管C#的命名空間不要求目錄和包名完全一致,但是根據命名空間來安排的源文件是TopCoder 的慣例。下面是典型C#路徑:

Path

Description

lib/TopCoder.Util.SpellCheck.dll

對於這個例子,這裏表示 Tutorial Generator項目依賴的庫,你的組件可能不需要任何依賴庫,也可能依賴多個

src/csharp/main/

組件有關的所有代碼應該放在這裏

src/csharp/main/TopCoder/Util/Tutorial/

對於這個例子,這裏是放佔位程序的好地方,對於你自己的項目,這個路徑會有所不同

3.10 構建你的項目

    生成並整理好站位程序後,你應該可以通過構建腳本來構建你的組件了。你只需從命令行裏指定構建目標然後運行構建工具即可。

    以下是 Ant 的常用構建目標:

目標名

描述

compile

把工程編譯成功能完全的二進制單元(如果你的代碼正確)

compile_tests

編譯測試代碼,需要 compile的成功執行

test

執行測試,需要 compile_tests的成功執行,測試的結果可以在 /log 目錄找到

coveragereport 

執行測試並生成測試覆蓋報告,你可以在 /log/coverage目錄找到結果

clean

清除 /build目錄,刪除所有已經編譯代碼以及項目的中間文件

dev_submission

生成一個已經打包好的提交包,讓你在項目完成後提交

    以下是MSBuild的常用構建目標:

目標名

描述

Build

編譯 .cs 源文件到 /build 目錄下

Test

(在測試項目中運行)運行測試並且輸出單元測試結果到 /log

NCoverReport

(在測試項目中運行)生成組建的測試覆蓋報告並存放於 /log

FxCop

(在測試項目中運行)生成裝配信息,諸如可能的設計、位置、性能以及安全方面的提升

Doc 

(在測試項目中運行)生成組件的javadoc方式的 API 文檔

Dist

基於 Build,生成組建部署的二進制分佈

CleanSolution

清除 /build以及 /log 目錄,刪除所有已編譯代碼

    如果要執行構建,只需要移動到構建腳本的目錄(應該是工程的根目錄),並執行 ant <target> 或者MSBuild<project> <target>。確保你已經配置好Ant/MSBuild,否則這一步將無法執行。

    點擊查看NAnt的構建示例以及Ant的構建示例

    你的組件站位程序應該總能完全乾淨利落地按照佔位程序構建。如果它們不能成功編譯,可能是API 的問題,也可能是庫文件的配置問題。在編寫代碼和測試前就修正這些問題會簡單的多,如果可能,你也應該這樣。

3.11 告一段落

    到這裏,你已經爲工程的具體開發做好了準備。有關程序開發技術和策略方面的具體問題已經超出了這份文檔的範疇。在接下來的幾節中,我們將介紹有關文檔、單元測試和開發過程中的一些常見問題。

4  提交必備——文檔(Documentation)

    文檔對一個組件的可用性和可維護性至關重要。如果在寫的同時就對代碼添加文檔,你或許根本就不會感覺到寫文檔的負擔。評審團會評估文檔質量。並且,文檔越好,評審團就越容易看懂和評估你的作品,得分也就越高。

4.1   API文檔

    你需要對從 UML 文檔自動生成的 API 文檔進行修改,而不是把它當作最終版本。在Java 中,API 是通過 Javadoc 來註釋的,C# 中則是通過 XML 文檔來註釋。所有的類、接口、方法和變量都必須具備文檔。以下是分別是Java 和 C# 的文檔例子:

1、Java

    當鍵入如下內容,很多Java IDE(如Eclipse,IDEA 等)就可以自動生成API 文檔:

/**
* Saves the file to permanent storage, on the path specified by configuration. The path
* must not begin with a backslash, and must not contain any special characters (see component
* specification). If the filename cannot be used, an exception will be thrown.
*
* @param filename The filename to save to. May not be null or empty.
* @throws IllegalArgumentException If filename is null.
* @throws IllegalArgumentException If filename is not valid (zero length, invalid characters, etc).
* @throws IOException If an error is encountered while saving the file.
*/
public void saveAs(string filename)

    更多有關 javadoc 的內容請點擊這裏

2、C#

    Visual Studio.Net 會在你編寫代碼的時候自動生成大部分 XML 文檔,只需要在聲明前面輸入///即可。

/// <summary>
/// Saves the file to permanent storage, on the path specified by configuration. The path
/// must not begin with a backslash, and must not contain any special characters (see component
/// specification). If the filename cannot be used, an exception will be thrown.
/// </summary>
/// <param name="filename">The filename to save to. May not be null or empty.</param>
/// <exception cref= "ArgumentNullException">If filename is null.</exception>
/// <exception cref="ArgumentException">If filename is not valid
/// (zero length, invalid characters, etc).</exception>
/// <exception cref="IOException">If an error is encountered while saving the file.</exception>
public override void SaveAs(string filename)

雖然C#中不會對throws 語句進行檢查,但是在API 文檔中註明該方法可能產生的異常是個好習慣。有關 XML 文檔的更詳細信息請點擊這裏

4.2   文檔內容

    解釋組件的行爲,非法輸入及相應的異常行爲。明確對象因爲某種操作而發生的變化(對List.add(object)而言,這可能顯而易見;而對 List.screenedAccept(object,bool) 來說,可能就不是那麼明顯了)。務必註明方法的返回值、可能拋出的異常和所有的參數。此外,每個類和接口都需要有個概括性文檔,以解釋其作用以及在組建中的位置。還要有這些內容(除了exceptions以及enumerations)的線程安全情況說明。此外,編寫樣本配置以及組件的主要類的作用也是個好習慣。

    請不要在組件中包含任何個人標識信息。任何需要用到你的TopCoder 賬號(handle)的地方(例如@author 標籤),請用 TCSDEVELOPER代替,保證客觀、公平。如果你成爲了獲勝者,你可以在修正(Final Fix)階段將 handle 寫入自己的組件。

4.3   文檔讀者

    API 文檔的讀者將是組件的使用者,也即 TopCoder 軟件的客戶。在文檔中請保持專業口吻,注意使用主動語態,語言儘量具有描述性,要考慮到組件的使用者可能沒有你對語言和組件這麼熟悉。

前面已經說過,從UML 直接產生的文檔不是合適的最終版本。例如:SaveAs 函數可能會有如下的文檔:

Pullthe path info from the config file, then append the filename passed in.Attemptsto save the file to that location, throws exception otherwise.

InvalidInput: null, blank, funny characters, non-fs safeValid Input: everything else

Throws:IOException on failure, InvalidArgumentException if it is.

    這段文字描述了 SaveAs 函數的功能;但是,它更多的是爲程序開發者自己寫的,而不是其用戶。你可能想刪除其實現細節,而又清晰準確的解釋函數的行爲。然而,俏皮話可能對內部人員適用,但是對用戶來說是不行的。請將這些條目熟記於心,當你完成一個函數的時候,請重寫其API 文檔。

4.4   內嵌式文檔

    內嵌式文檔是一段代碼中解釋代碼功能的文檔。內嵌式文檔是爲組件使用者以及TopCoder 改進所用的。和任何其他程序設計過程一樣,你註釋得越詳細,代碼就越容易維護。x++,一個簡單的自增語句,沒有必要註釋;但是你寫成 loopIndex++ 或者 recordCount++可能更合適。如果一段代碼的意圖不甚明顯的話,你可能就需要添加一些註釋了。

4.5   必備文檔

    關於API 文檔和內嵌文檔並沒有硬性規定,對它們的評審將會比較主觀,然而以下幾項是基本要求,牢記這些準則可以在文檔方面獲得高分:

1、 所有文件必須有 TopCoder 版權聲明;

2、 所有 public 的 API 元素必須要有詳細的文檔註釋(參數,返回值,異常類型),注意:包括單元測試在內;

3、 所有比較複雜或者龐大的代碼段都必須包含內嵌式文檔以解釋其目和功能;

4、 文檔必須具備專業口吻以及高質量。

5  提交必備——單元測試(Unit Tests)

    組件無論大小都需測試。測試的目的是保證組件對各種輸入均有正確的行爲,也即保證魯棒性。我們的單元測試風格起源於極限編程。你不一定要以這種風格來編程,需要獲取有關極限編程和單元測試方法論的更詳盡的信息,請參這裏或者這裏

    在極限編程中,測試先行。當然,這不是必須的,但非常有效。程序API 很大程度上是不變的, 這使得對照其寫測試用例成爲可能,而不需要管是否能通過。隨着你的開發進度,不斷測試,你的組件將會通過越來越多的測試。

5.1   何爲單元測試?

    單元測試是程序功能模塊最細微的測試(測試功能的每個單元)。通常,這意味着需要單獨測試所有非private 的方法和構造函數。單元測試既需要驗證程序在合法狀態和輸入下的行爲(包括極限情況),也需要驗證其在所有可測的出錯情形下的異常行爲。

5.2   測試範圍

    單元測試的範圍可以儘可能的廣,有時候單元測試的代碼量甚至會超過被測試的代碼量。

    組件的所有public 函數都必須有相應的測試:包括準確性測試和異常測試(對應合法和非法的輸入)。測試面越廣,組件的bugs 就越容易暴露。要想覆蓋所有的輸入情形是非常困難的(有時甚至是不可能的)。但是,輸入覆蓋面越大,組件就越可靠。

除了這些小的、原子性的測試,你也應該創建測試來查看你的組件是否始終提供了所期望的功能。

5.3   創建你的測試

    第一步是在 src 文件夾下創建單元測試的目錄,每種語言因測試目的而有細微不同。

    創建 C# 單元測試的示範看這裏

    創建 Java 單元測試的示範看這裏

5.4   單元測試技巧

    將所有的單元測試放在一個函數中聽起來非常有誘惑力。但是,這樣會極大地降低測試的效果。在上面的例子中,我們可以簡單的將三個測試函數組合成一個:testSaveAs()。現在我們只有一個測試函數,而不是三個。如果三個當中任何一個失敗的話,整個測試將失敗。在大規模測試中,這種組合測試的方法論將會導致失敗條件的混亂,測試的調試將變得困難。測試用例越小,功能越單一,錯誤點和可能的原因就越明顯。以下是一些單元測試的技巧:

1、 總是對組件說明書中的demo實現測試用例;

2、 總是在assert和fail 調用中提供有意義的信息;

3、 總是像註釋組件代碼一樣註釋測試用例,編寫文檔也一樣;

4、 把測試用例組織成離散的 TestCase 類, 如果一個 TestCase 已經難於管理, 別猶豫,把他拆成兩個或者更多的類;

5、 將TestCase類中的測試用例拆分成儘可能小的功能集;這樣,組件的哪部分出現了問題就一目瞭然。你也可以用測試用例通過和失敗的情況作爲組件完成與否的標準;

6、 通過使用 setup()和 teardown() 來減少重複代碼,增加魯棒性;

7、 時間允許的情況下,用儘可能多的合法或非法輸入對每個public 函數進行測試;

8、 測試組件期望的流程。比如:載入數據、處理數據、保存數據;

9、 不要忘記清空測試環境。單元測試後,系統應保持在測試前的狀態,而不是產生了持久的影響。此問題將會在評審過程中進行檢查;

10、 除了對測試框架的特殊意義,測試類在各方面都是正常的類。這些類可以繼承介於它們自己和最終測試間的類,可以包含非測試用的方法,並且有狀態;

11、 因爲它們和被測試的組件類處於同一包或命名空間下,單元測試可以訪問具備 package-private訪問屬性或者 protected訪問屬性的類及其成員;

12、 接口不能直接測試,但是可能存在以接口爲參數的方法。這種技術使得驗證組件是否對於接口類型的域和參數有正確的行爲、組件是否正確處理了此類方法調用時拋出的異常潛力巨大;

13、 所有的配置文檔和其他要用到的資源都應該放到測試目錄裏;

14、 有時候,一些依賴關係在組件最終完成之前是無法驗證的,這個時候你就需要編寫一些模擬類,或者使用類似 JMock 或者 EasyMock 的模擬工具,但在使用前請務必向項目經理進行確認;

15、 永遠不要把數據庫連接信息硬編碼進代碼裏,請確保它在一個單獨的文件裏進行配置,這樣可以使得測試和構建過程變得更簡單靈活,這條原則也適用於其他配置信息(例如網絡配置)。

6  提交必備——問題(Problems)

    在開發過程中,你可能會遇到一些問題。或許你需要額外的組件,或許組件本身設計的有瑕疵導致開發無法進行。你或許對設計者的意圖感到疑惑,或許對組件使用的技術感到不解。別擔心,你並不孤單。如果發現設計有任何不明確的地方,你都可以在組件論壇中進行提問(從Project Submit & Review 進入)。你可能會遇到一些設計者沒有考慮到的情況。你可能錯讀了組件,或者沒有注意到一些事項。任何情況下,組件本身相關的問題都應該在組件論壇中說明。

    另一方面,如果你在寫代碼過程中遇到了困難,或對某種技術不甚瞭解,或者遇到了某種程序bug,你可能就需要去 TopCoder 自由討論區(Round Tables)而不是開發論壇了。要去自由討論區可以查看這裏,其中一般討論區或組件競賽討論區是尋求幫助的合適地點。自由討論區是一些經驗豐富的TopCoder 成員和TopCoder 軟件職員經常光顧的地方,他們都會儘可能提供幫助。

    如果你遇到一些問題,使你不能繼續你的組件,請立即給項目經理髮Email。這些問題包括文件缺失或者錯誤,訪問或者應用程序問題,重大的設計問題等。你可以通過組件的Project Submit & Review Details 頁面給項目經理髮Email。如果你不能訪問上述頁面,請發email給[email protected]

rel=”nofollow”

linktype=”raw”

linktext="[email protected]|mailto:[email protected]">[email protected]">[email protected]

    請注意寫清楚你正在開發的項目以及碰到的問題的詳細描述。

    readme 文件不是一個好的交互方法。如果需要對組件做任何大的改動,你必須與組件設計者和項目經理聯繫。

7  提交(Submission)

    艱苦的工作已經結束,此時你的組件已經通過了所有150 個測試,可以準備提交了。

    首先,你需要檢查你的代碼,確保儘可能符合評審條款,一些細枝末節的問題也會在稍後的評審過程中降低你的分數。確保你的目錄結構符合要求。

    其次,你要確保你的代碼可以編譯通過。

    最後,執行dev_submission,生成最終的壓縮包。務必檢查一下你寫的所有文件是否全部包含其中,需要的話加入缺失的文件。你的提交需要包含單元測試成功執行的日誌文件,conf/ 目錄下的所有文件,test_files/目錄下的文件及目錄。如果有時間的話,你可以將歸檔文件解壓到另外一個目錄下重新構建以確保成功。

    如果你對自己將要提交的歸檔文件已經比較滿意了,就可以通過Project Submit & Review 上傳了。

7.1   讓你的作品出類拔萃

    想要在開發競賽中勝出,你必須使你的提交出類拔萃。對於簡單、比較具體的組件來說,這是一個訣竅;即使對於較複雜、抽象一些的組件來說,也應當給與足夠的重視。有多種方法讓你提交的作品脫穎而出,這裏給出幾點建議:

1、寫簡潔、清晰而高效的代碼。雖然這方面沒有明確的評審條目,不過評審員總是喜歡那些對他們來說易讀易懂的代碼。高效的代碼可以使你的程序在壓力測試和基準測試中表現優異,從而得到一些額外的分數。

2、單元測試務必全面。你可能會爲測試不足付出高昂的代價,因爲在評審條目中有好幾條是關於單元測試的。單元測試應該覆蓋所有非私有方法,並且需要良好的文檔註釋。在測試方面的良好表現會是贏得組件的重要砝碼,因爲單元測試是很容易被忽略的部分。

3、提供卓越的文檔註釋。類和方法的文檔是由開發人員負責,但是似乎很少有人給它應有的重視。良好的文檔必須清晰,容易理解。瞭解並熟悉Javadoc 的文檔。例如:任何HTML標籤都可以插到文檔註釋中,適當的應用這種特性將會非常有效。試着站在別的程序開發人員的角度問自己:你想要知道組件的什麼信息,然後將其寫下來。瞭解並遵循Sun 或Microsoft的文檔註釋指南,以及相關如何寫API 規範的文檔。

4、完全符合要求,提供所有要求的功能。或許,這是理所當然的;但是任何差錯都會減少你獲勝的機會。小心特殊情況和非正常輸入。

5、注意任何設計者忽視的問題。比如:線程安全,可移植性(即使是Java 或者.NET也存在移植性問題)。請在設計框架內仔細斟酌,使你的提交具備想要的特性。

8  評審(Review)

    一旦提交,評審團就會對你的作品按照以下標準進行評分,在評分之前會有一個篩選階段,你可以點這裏查看一個篩選評分卡的示例,點擊這裏你可以找到一份非常詳細的評分卡總結,在這裏你可以看到一份評審積分卡的示例。

8.1   功能

    功能評審是最重要的,評審團會檢查你的作品是否已經實現了所有的需求、是否已經提供了設計文檔裏定義的所有功能、是否用合適的技術來完成(例如是否恰當地連接了數據庫、是否使用了恰當的XML配置)。如果你在對組件設計中指明使用的複雜算法進行了改進,也是非常值得鼓勵的,但如果你不確定你使用的算法是否正確,請在論壇提問。

8.2   定義  

    另一個重要的方面是你的作品中的變量和聲明是否和設計文檔中的定義完全一致(可視性、類型、修飾詞、名稱、異常列表)。未經設計者或者項目經理同意,不得刪除、添加或者修改任何非私有API。你可以創造新的功能類或函數,但應當把他們的作用域縮減到最小。

8.3   代碼

1、 評審團會對代碼中的對象類型進行檢查,看是否做出了最好的選擇,例如你可能會使用決定用一個TreeMap 去存儲一些鍵值對。然而,除非你需要保持鍵的相對順序,否則你應該使用HashMap 。在這裏,“最好的選擇”通常是與效率相關。不要寫無用和臃腫的編碼,不要有代碼冗餘,你的代碼應該是清晰明瞭且儘可能精簡的;

2、 這項可能有些主觀,但是也有客觀參照:你一般不應該對三元選擇運算符進行套嵌(例如: good ? "great!" : ok ? "I suppose" : bad ?or_is_it ? "darn" : "phew" : "who knows?"),這樣的代碼非常不清晰。同樣的,對於大段的代碼,如果某個方法超過了50行,那就把它拆分成多個函數。例如說你正在畫圖,你應該要有一個 drawAxes() 方法、drawData()方法和一個drawLegend()方法,而不是一個非常大的代碼塊。效率方面,很小的改進也可以產生明顯的效果。當你已經達到期望值的時候,從查找中跳出。智能設置控制條件,運用短路求值法。不要把你的代碼寫的過於複雜,能簡化的儘量簡化。

3、 所有代碼,包括測試用例,都應當遵循TopCoder 編碼規範。我們的編碼規範是已發佈的Java和C#標準。你可以通過以下鏈接查看:

Java編程規範

.Net編程規範

8.4   文檔

    完成的代碼必須附帶關於類、方法和變量的詳細文檔,並以 Java/C# 編碼標準所要求的Javadoc/XML風格編寫。文檔語法必須正確:不能有描述不存在的元素的文檔、不能有晦澀難懂的文檔。更詳細的信息請參照前文有關文檔的內容。

8.5   單元測試 

1、 單元測試應該正確、徹底地測試了所有的方法和構造函數。單元測試應當包含一個演示組件如何使用的Demo,該demo需要在要求的環境中完成。例如:對於 web 組件,你的 demo 應當以web 應用的形式給出。

2、 單元測試應當合理配置測試環境,不能在測試之後還有任何的文檔或連接處於打開狀態,經常在tear-down方法中清理環境是個好習慣。

3、 應當像註釋組件代碼一樣註釋單元測試。此外,三個程序評審員都會寫單元測試,以探查你提交的組件的精確性、適當的異常行爲以及壓力測試的表現。基於以上各方面的測試結果,你的組件將會獲得一個評分。

9  申訴(Appeals)

    評審結束後,你將有幾天時間查看你的組件得分並進行申訴。你將看到分數卡上關於以上每一條的評論,而且可以爲分數進行爭辯。需要注意的是,你的申訴必須理由充分,否則將會被拒絕。如果評審員的陳述與設計相沖突,或者評審出現了差錯,不要顧忌,申訴!另外,觀念性的問題一般不要申訴。如過你是組件的獲勝者,在修正階段你將有機會討論評審員的評判。

10    修正(Final Fixes)

    祝賀你!你是組件的獲勝者!

    然而,仍然有一些工作需要你去做。你可以通過Project Submit & Review看到評審分數卡。在那裏,你可以找到評審團提出的所有有關你的提交的問題。它包括對提交作品必需的和推薦的修正。

1、 必須項是必須解決的,任何一項沒有完成,你的工作都不能結束;

2、 推薦項則需要你嘗試去解決。顯然,他們的優先級僅次於必須項,如果時間允許,也應該完成;

3、 別忘了把你的作品裏的TCSDEVELOPER 改成你自己的賬號(handle)!

10.1 交流

    在修正階段,交流比在其他任何時候都重要。

    無論什麼原因,如果你對評審有疑問或意見,及早提出來。如果問題嚴重,請立即致信項目經理,並且發佈於論壇上,他將會查看這些問題,並確保主評審員(Primary Reviewer)會來解決這些問題。如果你覺得一些必需項是不可能做到的,請在論壇上提出來。絕對不要重複提交沒有修正的組件或者僅僅在 readme 文件中聲明這些問題。和評審員保持聯繫,以避免發生上述情況。你反映得越及時,提供的資料越詳細,這個過程就會越順利。和評審團交流的大門將一直對開發人員敞開,他們可能沒有注意到設計或者你提交作品中的某些細節。不要害怕對評審團提出質疑。質疑和評論表明你在關注這些問題,並在積極參與。沒有交流,評審團將無法闡明他們的要求,也無法得知你做了什麼工作。

11    最終提交審覈(Final Submissionand Review)

    這僅僅是一次dev_submission 的構建過程。遵循同樣的指導原則,保證上傳了所有文件。使你的提交儘可能完善。這樣將節省所有人的時間,包括你自己。

如果你的提交已經滿足了所有要求,通過了所有評審的測試,組件也就完成了,並將添加到目錄中。你的工作也就完成了。

    注意,如果有任何工作沒有完成,你會被打回 Final Fixes。

12    獎金(Prizes)

    再次祝賀!到了這一步你就已經可以獲得獎金了,但要注意再接再厲!

12.1   可靠性獎金

    對於你最近完成的15個組件開發任務,如果他們的評分都比較高,你將可以獲得獎金。詳細內容可以看這裏

12.2   DR獎金

  Digital Run可以讓你獲得更多獎金,有關它的內容看這裏。PlacementPoints定義了過去提交的作品中通過評審的數量,有關它的內容看這裏

13    總結(Conclusion)

    再次祝賀你!經過註冊、開發、測試、提交、被審查、申訴、獲勝、修正並再次提交,你得到了報酬,並且還可以從你所做的工作中得到版稅!有什麼慶祝方式會比再註冊一個新的項目並且完成它更好呢?


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章