Java是一種跨平臺的語言,號稱:「一次編寫,處處運行」,在世界編程語言排行榜中穩居第二名(TIOBE index)。html
本文目標是幫助 Java 程序員瞭解中級程序員應有的水平,避免陷入惟「高技術、新概念」的陷阱。Java 編程入門相對比較容易(推薦:Java入門教程)。學完語法後,不少人但願做一些進階學習,開始編寫網站、訪問數據庫等應用。然而,當程序比較多時,你又以爲 Java 程序很複雜。所以,咱們有必要了解 Java 程序的結構與開發理念,站在項目的高度去看 Java 中級程序員須要哪些知識和能力。java
維基百科:約定優於配置是一種軟件框架使用的設計範式(原則),旨在減小軟件開發人員需作決定的數量,使軟件既不失靈活性,且簡潔易於理解。程序員
David Heinemeier Hansson 在使用 Ruby on Rails 開發 web 應用時提出這個概念,由於長期作同類項目,項目中程序的組織、命名習慣都會造成最佳實踐,遵循這些最佳實踐就不只能夠節約開發者溝通時間,並且有利於程序的構建等工做。例如,咱們用 MVC 結構去開發 web 程序,程序員都知道控制器類在哪一個目錄下,完成哪些任務。web
咱們在第一次學習計算機語言時都會知道概念編碼習慣(code conventions)、編程風格(programming idioms)。它們偏向於某種語言的編碼規範,例如 C++,Java,Python 都有本身的編碼標準,如 google 的編碼規範,Pep8編碼規範等,這樣,IDE 使用這些規範檢查你的程序是否符合標準。shell
約定優於配置偏向於程序的組織於結構,這樣編譯等工做就能夠按約定習慣進行。咱們在編譯 PyQt 這樣的框架時,很是佩服編寫 make 腳本的程序員,./configuration
, make
, make install
這些複雜的腳本是如何保證正確的?簡化開發過程當中各階段的配置,讓應用開發人員集中精力編寫業務處理程序(Java 的理念),不用關心如何實現快速交付、部署等問題,則是約定優於配置要解決的問題。數據庫
如今的核心問題是要作哪些約定,如何保證約定的實施?apache
不一樣領域的應用約定是不同的,對於 Java 應用則由構建工具(如: Maven,Gradle)負責一些約定的實現,其餘就是特定應用框架如 Spring MVC 等示例代碼造成的無形習慣。對於一個普通 Java 程序,它的約定是什麼?編程
(1)生成程序框架windows
在hello-world目錄下,輸入以下命令:設計模式
$ mvn archetype:generate -DarchetypeCatalog=internal -DgroupId=com.mycompany.helloproj -DartifactId=helloworld -Dpackage=com.mycompany.helloworld -Dversion=0.0.1
參考:使用mvn archetype:generate生產maven工程,響應很慢
選默認,回車,回車。
Maven 使用慣例優於配置的原則 。它要求在沒有定製以前,全部的項目都有以下的結構:
目錄 | 目的 |
---|---|
${basedir} | 存放 pom.xml |
${basedir}/src/main/java | 項目的 java源代碼 |
${basedir}/src/main/resources | 項目的資源,好比說 property文件、圖片等 |
${basedir}/src/test/java | 項目的測試類,好比說 JUnit代碼 |
${basedir}/src/test/resources | 測試使用的資源 |
使用 IntelliJ IDEA 導入項目,就能夠看到這樣的程序結構:
(2)約定應用與組織規範
舉例說明,Java 訪問資源文件如xxx.xml,若是寫成:classpath:/xxx.xml
,這個類必定默認加載main/resources/xxx.xml
。
相似的應用約定不少,學習的辦法只有一個,積累!積累!積累!,見多識廣。
再看 pom.xml 文件內容:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 項目座標 --> <groupId>com.mycompany.helloproj</groupId> <artifactId>helloworld</artifactId> <version>0.0.1</version> <packaging>jar</packaging> <!-- 項目名稱 --> <name>helloworld</name> <url>http://maven.apache.org</url> <!-- 屬性變量 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <!-- 項目依賴 --> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
在 pom.xml 所在目錄下,輸入:
$ mvn package
咱們看到 maven 項目作了許多工做:
結果,在 target 目錄下,出現了 helloworld-0.0.1.jar
文件。
$ mvn install
結果,在 $USER_HOME/.m2/repository/com/mycompany/helloproj/helloworld/0.0.1/ 出現了 helloworld-0.0.1.jar
文件。
在 Maven 配置中, groupId:artifactId:packaging:version 四個元素惟一表示了項目的部件、版本、發佈方式。
又稱爲項目座標。
一般,合理的命名展現了通常公司項目的管理結構。
經過結構約定,咱們定義了企業項目管理的基本方式。
(3)約定開發流程
maven 能支持項目開發不一樣的生命週期階段 (lifecycle phase )。可是最經常使用的是默認的 Maven生命週期 (default Maven lifecycle )。一個 Jar 包的階段包括:
每一個階段有默認目標。 maven 命令就是 mvn goal ,經常使用目標有:
最多見命令之一就是:
$ mvn clean package install
經過對 jar, war, ear 等工程流程(階段)的約定,簡單的配置、簡單的命令就實現了開發過程自動化,
程序員僅需關注業務。
(4)擴展任務
約定了開發階段(這也是有人認爲 Maven 不靈活的因素),經過插件(plug in)就在不一樣階段基礎上擴展新目標。
例如:
<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <mainClass>com.mycompany.helloworld.App</mainClass> </configuration> </plugin> </plugins> </build>
在 pom.xml 中添加 exec-maven-plugin 插件,就能夠用 mvn exec:java
執行程序。
參見: Exec Maven Plugin使用
若是你須要打包成可執行的 jar,jar 和 assembly 插件最經常使用,參見
本文不是 maven 的教程,只是說明經過約定一些基本規則,程序開發編程更加簡單、高效,更易於多人協同,共享成果。
測試驅動的開發是敏捷開發(短週期迭代)的一種生產實踐,它要求程序的功能或特性(需求)在開發出來的同時,測試案例(程序)同步完成,並用於需求驗證。
概念起源於 Kent Beck 的【極限編程/Extreme Programming】實踐。若是你沒有讀過,越忙越要抽空讀。Kent Beck是項目經理出身,因此也知道你很忙,因此書的很薄,你一定有許多共鳴的。Kent 喜歡講故事,怎麼作就讓你本身領會了,【硝煙中的scrum和xp】書能夠幫你。
Kent Beck 發現,在錯誤(bug 可能來源於業務邏輯,也多是結構設計)比較多的程序上迭代,積累誤差會迅速放大,致使程序愈來愈難以調試與維護。所以,須要低成本的手段保障每次迭代產品的品質,因而提出了 TDD 的概念。
假設一箇中型項目按特定的結構建設,這個結構包含兩個方面:
假設這個中型項目劃分爲以下依賴關係的部件:
集成測試過程以下:
這樣,每一個部件程序員不只要編寫業務程序,也須要負責使用 Junit 或 TestNG 測試本身的模塊。
測試程序員僅編寫集成測試,測試部件組合後的正確性。實際測試中會複雜一些,會使用 mock 測試技術。
因爲這樣的測試能夠天天晚上用 shell 腳本執行,因此也稱爲 「每日構建(Daily Building)」 或 「冒煙測試(smoking Test)」
快速交付指按固定迭代週期(2-4 周)將產品交付客戶試用,及時獲取客戶反饋。
因此,每一個迭代須要花2-3天作產品系統測試。
在沒有 TDD 以前,項目進展都是經過程序的日報/週報等方式評估的。項目經理從程序員獲取信息,而後作項目進度圖。
開始,項目進展很是快,%20,%40,%60,%80,%90,%95,%99 。。。延期,再延期。
TDD 改變了這一切,每一個人天天收到報告,有多少測試沒經過?已經過 xx%。顯式度量調動了程序員積極性。
測試數據與程序員分離,有力提高 bug 發現的能力。
TDD 也不是萬能的,對於 10 幾個開發者的團隊,那 1-2 核心程序員纔是品質的保證。他們完成絕大多數代碼,
TDD 對這些人驅動的意義不大,TDD 成本高於僅作系統測試。
本文雖然僅討論了約定優於配置(CoC)和測試驅動的開發(TDD),能實施這兩點的程序猿必定在中級或以上。
由於,掌握 CoC 和 TDD 對於一個團隊來講意味着:
這證實中級程序猿有能力作一個小型開發團隊(3~7人)的技術經理。由於精確度量,領導喜歡你;
由於架構和進度的優良控制,程序猿也省心,特別是哪些喜歡與計算機打交道的天才會成爲你的中堅;
PPT程序猿會自動離開。
掌握 CoC 和 TDD 本質是就是 Java 開發團隊具體實施敏捷開發實踐的要點,它知足敏捷四條宣言:
在 hello world 這樣規模的程序上實踐,你是不可能徹底理解 CoC、TDD的重要性的。
掌握一個應用領域程序的邏輯結構與部署結構,組織天天測試在實踐中會有無數障礙(不作不知道)。
要成爲合格的中級程序員,須要進一步努力,例如:
等等