Java 進階 hello world! - 中級程序員之路

Java 進階 hello world! - 中級程序員之路

Java是一種跨平臺的語言,號稱:「一次編寫,處處運行」,在世界編程語言排行榜中穩居第二名(TIOBE index)。html

本文目標是幫助 Java 程序員瞭解中級程序員應有的水平,避免陷入惟「高技術、新概念」的陷阱。Java 編程入門相對比較容易(推薦:Java入門教程)。學完語法後,不少人但願做一些進階學習,開始編寫網站、訪問數據庫等應用。然而,當程序比較多時,你又以爲 Java 程序很複雜。所以,咱們有必要了解 Java 程序的結構與開發理念,站在項目的高度去看 Java 中級程序員須要哪些知識和能力。java

1. 約定優於配置(Convention over Configuration/CoC)

1.1 環境配置

  • 操做系統 windows/Linix
  • Java 虛擬機 1.8
  • Maven 3.3+
  • IDE IntelliJ IDEA / Eclipse

1.2 概念與起源

維基百科:約定優於配置是一種軟件框架使用的設計範式(原則),旨在減小軟件開發人員需作決定的數量,使軟件既不失靈活性,且簡潔易於理解。程序員

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 的理念),不用關心如何實現快速交付、部署等問題,則是約定優於配置要解決的問題。數據庫

1.3 Maven 與約定

如今的核心問題是要作哪些約定,如何保證約定的實施?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 導入項目,就能夠看到這樣的程序結構:

hello-image

(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 項目作了許多工做:

  1. 下載 junit 庫
  2. 複製資源文件
  3. 編譯
  4. 測試
  5. 打包

結果,在 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 四個元素惟一表示了項目的部件、版本、發佈方式。
又稱爲項目座標
一般,合理的命名展現了通常公司項目的管理結構。

  • 項目庫目錄: $USER_HOME/.m2/repository/;
  • 公司目錄:com/mycompany/;
  • 項目目錄:helloproj/;
  • 部件與版本目錄:helloworld/0.0.1/。

經過結構約定,咱們定義了企業項目管理的基本方式。

(3)約定開發流程

maven 能支持項目開發不一樣的生命週期階段 (lifecycle phase )。可是最經常使用的是默認的 Maven生命週期 (default Maven lifecycle )。一個 Jar 包的階段包括:

  • process-resources 階段:resources:resources
  • compile 階段:compiler:compile
  • process-classes 階段:(默認無目標)
  • process-test-resources 階段:resources:testResources
  • test-compile 階段:compiler:testCompile
  • test 階段:surefire:test
  • prepare-package 階段:(默認無目標)
  • package 階段:jar:jar

每一個階段有默認目標。 maven 命令就是 mvn goal ,經常使用目標有:

  • clean 清除全部階段的成果
  • compile 編譯
  • test 執行前面階段任務,直到測試完成
  • package 打包
  • install 發佈到內部項目倉庫

最多見命令之一就是:

$ 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 的教程,只是說明經過約定一些基本規則,程序開發編程更加簡單、高效,更易於多人協同,共享成果。

2. 測試驅動的開發(Test-Driven Development/TDD)

2.1 概念與起源

測試驅動的開發是敏捷開發(短週期迭代)的一種生產實踐,它要求程序的功能或特性(需求)在開發出來的同時,測試案例(程序)同步完成,並用於需求驗證。

概念起源於 Kent Beck 的【極限編程/Extreme Programming】實踐。若是你沒有讀過,越忙越要抽空讀。Kent Beck是項目經理出身,因此也知道你很忙,因此書的很薄,你一定有許多共鳴的。Kent 喜歡講故事,怎麼作就讓你本身領會了,【硝煙中的scrum和xp】書能夠幫你。

Kent Beck 發現,在錯誤(bug 可能來源於業務邏輯,也多是結構設計)比較多的程序上迭代,積累誤差會迅速放大,致使程序愈來愈難以調試與維護。所以,須要低成本的手段保障每次迭代產品的品質,因而提出了 TDD 的概念。

2.2 持續集成

假設一箇中型項目按特定的結構建設,這個結構包含兩個方面:

  • 邏輯結構,也稱包結構,指一個 Java 應用的類命名空間(惟一的可管理的命名)。
    例如:helloworld 應用中, App 類的命名空間是 com.mycompany.helloworld。則這個類全稱是:
    com.mycompany.helloworld.App。帶來的便利是不易命名重複,易於查找、使用和管理。
  • 物理結構,也稱部署結構,指一個 Java 應用哪些類、資源組成一個部件(如 Jar 文件)。
    這樣,每一個子項目對應一個部件,1-3個開發人員負責一個子項目的開發。帶來便利是項目分解爲若干獨立部件,
    子項目能夠獨立開發、測試、升級與維護。

假設這個中型項目劃分爲以下依賴關係的部件:

integration

集成測試過程以下:

  1. 按依賴順序從 Git 加載程序,使用 Maven clean deploy 構建每一個子部件,並放入本地倉庫。稱爲「單元測試
  2. 按集成策略,編寫三個集成測試用例,測試部件的組合。稱爲「集成測試

這樣,每一個部件程序員不只要編寫業務程序,也須要負責使用 Junit 或 TestNG 測試本身的模塊。
測試程序員僅編寫集成測試,測試部件組合後的正確性。實際測試中會複雜一些,會使用 mock 測試技術。

因爲這樣的測試能夠天天晚上用 shell 腳本執行,因此也稱爲 「每日構建(Daily Building)」 或 「冒煙測試(smoking Test)

參考:基於Maven的持續集成實踐

2.3 快速交付

快速交付指按固定迭代週期(2-4 周)將產品交付客戶試用,及時獲取客戶反饋。
因此,每一個迭代須要花2-3天作產品系統測試。

2.4 TDD是必需的嗎?

在沒有 TDD 以前,項目進展都是經過程序的日報/週報等方式評估的。項目經理從程序員獲取信息,而後作項目進度圖。
開始,項目進展很是快,%20,%40,%60,%80,%90,%95,%99 。。。延期,再延期。

  • 主管抱怨:bug 太多,時間不夠
  • 程序員抱怨:PPT 作的好的人(PPT程序猿)常常受表揚,難道程序員作好 PPT 比作好程序重要?

TDD 改變了這一切,每一個人天天收到報告,有多少測試沒經過?已經過 xx%。顯式度量調動了程序員積極性。
測試數據與程序員分離,有力提高 bug 發現的能力。

TDD 也不是萬能的,對於 10 幾個開發者的團隊,那 1-2 核心程序員纔是品質的保證。他們完成絕大多數代碼,
TDD 對這些人驅動的意義不大,TDD 成本高於僅作系統測試。

3. 總結

本文雖然僅討論了約定優於配置(CoC)和測試驅動的開發(TDD),能實施這兩點的程序猿必定在中級或以上。
由於,掌握 CoC 和 TDD 對於一個團隊來講意味着:

  • CoC 你熟悉一個以上領域程序的基本結構(邏輯結構與部署結構)與每一個部分的關鍵技術(初級架構師要求)
  • TDD 你按項目週期合理組織項目部件的開發,並實現天天進度的量化管理(初級項目經理要求)

這證實中級程序猿有能力作一個小型開發團隊(3~7人)的技術經理。由於精確度量,領導喜歡你;
由於架構和進度的優良控制,程序猿也省心,特別是哪些喜歡與計算機打交道的天才會成爲你的中堅;
PPT程序猿會自動離開。

掌握 CoC 和 TDD 本質是就是 Java 開發團隊具體實施敏捷開發實踐的要點,它知足敏捷四條宣言:

  • 個體交互賽過過程與工具
  • 能夠工做的軟件賽過面面俱到的文檔
  • 客戶協做賽過合同談判
  • 響應變化賽過遵循計劃

在 hello world 這樣規模的程序上實踐,你是不可能徹底理解 CoC、TDD的重要性的。
掌握一個應用領域程序的邏輯結構與部署結構,組織天天測試在實踐中會有無數障礙(不作不知道)。
要成爲合格的中級程序員,須要進一步努力,例如:

  • 作一個網上商店這樣規模的 web 程序
  • 軟件架構基本知識
  • 學習測試技術與技巧
  • 源代碼管理與持續集成
  • 學習 Java 設計模式,瞭解更多面向對象的設計約定
  • 學習分佈式基礎技術,提高系統的性能與可靠性

等等

相關文章
相關標籤/搜索