一、實驗報告封面
課程:Java程式設計 班級:1652班
指導教師:婁嘉鵬 實驗日期:2018年4月27日
實驗時間:13:45 - 15:25 實驗序号:實驗三
實驗名稱:靈活開發與XP實踐
實驗内容:
- XP基礎
- XP核心實踐
- 相關工具
實驗要求:
- 沒有Linux基礎的同學建議先學習《Linux基礎入門(新版)》《Vim編輯器》 課程
- 完成實驗、撰寫實驗報告,實驗報告以部落格方式發表在部落格園,注意實驗報告重點是運作結果,遇到的問題(工具查找,安裝,使用,程式的編輯,調試,運作等)、解決辦法(空洞的方法如“查網絡”、“問同學”、“看書”等一律得0分)以及分析(從中可以得到什麼啟示,有什麼收獲,教訓等)。報告可以參考範飛龍老師的指導
- 嚴禁抄襲,有該行為者實驗成績歸零,并附加其他懲罰措施。
二、實驗内容及步驟
(一)編碼标準
- 安裝alibaba 插件,解決代碼中的規範問題。具體流程如下:
- 打開
->Settings
->Plugins
Browse
...repositories
- 在搜尋框輸入
即可看到alibaba
插件,點選Alibaba Java Code Guidelines
進行安裝,然後重新開機IDE生效:Install
- 使用比較簡單:在項目名稱上單擊右鍵,在彈出菜單上選擇
:編碼規約掃描
出現下圖内容:
不規範的地方,有中文提示并且定位到了行,alibaba把問題分為
block/critical/major
三個等級,有些規則可以一鍵修複。
Java中的一般的命名規則有:
- 要展現各自的含義
- 包、類、變量用名詞
- 方法名用動賓
- 包名全部小寫,如:io,awt
- 類名第一個字母要大寫,如:HelloWorldApp
-
變量名第一個字母要小寫
,如:userName
- 方法名第一個字母要小寫:setName
規範後的代碼格式
import java.util.concurrent.Callable;
public class CodeStandard {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer();
buffer.append('S');
buffer.append("tringBuffer");
System.out.println(buffer.charAt(1));
System.out.println(buffer.capacity());
System.out.println(buffer.indexOf("tring"));
System.out.println("buffer = " + buffer.toString());
if (buffer.capacity() < 20) {
buffer.append("1234567");
}
for (int i = 0; i < buffer.length(); i++) {
System.out.println(buffer.charAt(i));
}
}
}
任務一:在IDEA中使用工具(Code->Reformate Code)格式化代碼,并學習Code菜單的功能
IDEA中的Code菜單如下:
幾個比較常用的功能總結如下:
-
(Ctrl+O):重載基本類的方法;Override Methods
-
Implement Methods
(Ctrl+I):完成目前類 implements 的(或者抽象基本類的)接口的方法;
Generate(Alt+Insert):建立類裡面任何字段的 getter 與 setter 方法;
-
(Ctrl+Alt+T):使用if-else、try-catch、do-while等包裝代碼段;Surround With
-
(Ctrl-J):執行一些記不起來的 Live Template 縮寫;Insert Live Template
-
(Ctrl+斜杠)/Comment with Line Comment
(Ctrl+Shift+斜杠):用 Ctrl+斜杠 與 Ctrl-Shift-/ 來注釋(或反注釋)代碼行與代碼塊。 用Ctrl+斜杠單行注釋标記(“ //… ”)來注釋(或反注釋)目前行或者選擇地代碼塊。而 Ctrl+Shift+斜杠則可以用塊注釋标記(“ /* */”)把所選塊包圍起來。要反注釋一個代碼塊就在塊中任何一個地方按 Ctrl+Shift+斜杠 即可;Comment with Block Comment
-
(Ctrl+Alt+L):将代碼按标準格式縮進;Reformat Code
-
:按照格式自動對齊show reformat file dialog
-
:可以優化imports,去除不必要的importsOptimize imports
-
:将某行、表達式向下、向上移動一行Move Line/statement Down/Up
(二)靈活開發與XP
任務二:下載下傳搭檔實驗二的Complex代碼,加入不少于三個JUnit單元測試用例
搭檔的Complex代碼如下:
需要測試的方法有:
ComplexAdd()
,
ComplexSub()
,
ComplexMulti()
,
ComplexDiv()
;
編寫測試代碼并上傳到搭檔碼雲項目上:
import junit.framework.TestCase;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Created by sxx on 2018/4/26.
*/
public class ComplexTest extends TestCase {
Complex c1 = new Complex(0.0, 2.0);
Complex c2 = new Complex(-1.0, -1.0);
Complex c3 = new Complex(1.0,2.0);
@Test
public void testgetRealpart() throws Exception{
assertEquals(0.0,Complex.getRealPart(0.0));
assertEquals(-1.0,Complex.getRealPart(-1.0));
assertEquals(1.0,Complex.getRealPart(1.0));
}
@Test
public void testgetImagePart() throws Exception{
assertEquals(2.0,Complex.getImagePart(2.0));
assertEquals(-1.0,Complex.getImagePart(-1.0));
assertEquals(2.0,Complex.getImagePart(2.0));
}
@Test
public void testComplexAdd() throws Exception{
assertEquals("-1.0+1.0i",c1.ComplexAdd(c2).toString());
assertEquals("1.0+4.0i",c1.ComplexAdd(c3).toString());
assertEquals("0.0+1.0i",c2.ComplexAdd(c3).toString());
}
@Test
public void testComplexSub() throws Exception{
assertEquals("1.0+3.0i",c1.ComplexSub(c2).toString());
assertEquals("-1.0",c1.ComplexSub(c3).toString());
assertEquals("-2.0-3.0i",c2.ComplexSub(c3).toString());
}
@Test
public void testComplexMulti() throws Exception{
assertEquals("2.0-2.0i",c1.ComplexMulti(c2).toString());
assertEquals("-4.0+2.0i",c1.ComplexMulti(c3).toString());
assertEquals("1.0-3.0i",c2.ComplexMulti(c3).toString());
}
@Test
public void testComplexDiv() throws Exception{
assertEquals("-1.0-1.0i",c1.ComplexDiv(c2).toString());
assertEquals("0.4+0.8i",c1.ComplexDiv(c3).toString());
assertEquals("-0.6-0.6i",c2.ComplexDiv(c3).toString());
}
}
(三)重構
重構(Refactor),就是在不改變軟體外部行為的基礎上,改變軟體内部的結構,使其更加易于閱讀、易于維護和易于變更 。
我們要修改軟體,萬變不離其宗,無非就是四種動機:
- 增加新功能;
- 原有功能有BUG;
- 改善原有程式的結構;
- 優化原有系統的性能 。
需要重構的地方:
代碼重複、方法過長、參數列過長、條件邏輯過度複雜、分支語句
一個完整的重構流程包括:
- 從版本控制系統代碼庫中Check out code
- 讀懂代碼(包括測試代碼)
- 發現bad smell
- Refactoring
- 運作所有的Unit Tests
- 往代碼庫中Check in code
任務三:下載下傳搭檔的代碼,至少進行三項重構
如上代碼存在以下幾個問題:
- 類名不符合命名規則;
- 類中變量沒有被封裝;
- 方法沒有被封裝;
練習
任務四:以結對的方式完成Java密碼學相關内容的學習,結合重構、git、代碼标準等
Java安全體系結構總共分為4個部分:
- JCA( Java Cryptography Architecture, Java加密體系結構):JCA提供基本的加密架構, 如證書、 數字簽名、消息摘要和密鑰對産生器。
- JCE( Java Cryptography Extension, Java加密擴充包):JCE在JCA的基礎上作了擴充, 提供了各種加密算法、 消息摘要算法和密鑰管理等功能。JCE的實作主要在javax.crypto包( 及其子包) 中
- JSSE( Java Secure Sockets Extension, Java安全套接字擴充包):JSSE提供了基于SSL( Secure Sockets Layer,安全套接字層) 的加密功能。 在網絡的傳輸過程中, 資訊會經過多個主機(很有可能其中一台就被竊聽) , 最終傳送給接收者, 這是不安全的。這種確定網絡通信安全的服務就是由JSSE來提供的。
- JAAS( Java Authentication and Authentication Service, Java鑒别與安全服務):JAAS提供了在Java平台上進行使用者身份鑒别的功能。
進行了學習之後,我與搭檔選擇了實作凱撒密碼的加解密算法,并以結對的方式完成了代碼編寫的工作。
凱撒密碼算法:将字母表中的字母移動一定位置而實作加密。
-
具體步驟:
(1)根據凱撒密碼特性設計算法
(2)傳入需要計算的字元串
(3)處理計算結果
- 僞代碼:
定義main方法
傳入參數
參數判斷,是否有非法輸入,若有,抛出異常
進行加解密,大小寫區分
輸出結果
-
産品代碼:
Caesaar.java
public class Caesar {
public static void main(String[] args) throws EadException {
String s = args[0];
int key = Integer.parseInt(args[1]);
String es = "";
for (int i = 0; i < (s.length()); i++) {
char c = s.charAt(i);
//自定義異常類
try {
boolean exist = ((c > 64) && (c < 91)) || ((c > 96) && (c < 123) || c == 32 || c == 33);
if (exist == false) {
throw new EadException(s);
}
} catch (EadException e) {
System.out.println(e.warnMess());
}
//小寫字母
if (c >= 'a' && c <= 'z') {
//移動key%26位
c += key % 26;
//向左超界
if (c < 'a') {
c += 26;
}
//向右超界
if (c > 'z') {
c -= 26;
}
}
//大寫字母
else if (c >= 'A' && c <= 'Z') {
c += key % 26;
if (c < 'A') {
c += 26;
}
if (c > 'Z') {
c -= 26;
}
}
es += c;
}
System.out.println(es);
}
}
EadException.java
public class Caesar {
public static void main(String[] args) throws EadException {
String s = args[0];
int key = Integer.parseInt(args[1]);
String es = "";
for (int i = 0; i < (s.length()); i++) {
char c = s.charAt(i);
//自定義異常類
try {
boolean exist = ((c > 64) && (c < 91)) || ((c > 96) && (c < 123) || c == 32 || c == 33);
if (exist == false) {
throw new EadException(s);
}
} catch (EadException e) {
System.out.println(e.warnMess());
}
//小寫字母
if (c >= 'a' && c <= 'z') {
//移動key%26位
c += key % 26;
//向左超界
if (c < 'a') {
c += 26;
}
//向右超界
if (c > 'z') {
c -= 26;
}
}
//大寫字母
else if (c >= 'A' && c <= 'Z') {
c += key % 26;
if (c < 'A') {
c += 26;
}
if (c > 'Z') {
c -= 26;
}
}
es += c;
}
System.out.println(es);
}
}
運作結果:
除了實作凱撒密碼算法之外,我還運作了其他算法:
DES算法
- 檔案key1.dat中生成的密鑰
- 儲存密鑰編碼并列印
- 用DESede加密
- 用DESede解密
RSA加密
RSA解密
MD5算法
(五)實驗過程中遇到的問題及解決方法
- 在做重構相關内容的實驗時,由于對重構的内容并不是非常了解,小夥伴的代碼也大都是書上的代碼,找了好多,都沒有發現太多需要重構的地方。
-
解決方法:在學習了實驗三 靈活開發與XP實踐——婁老師的部落格,以及參考了Java代碼重構的幾種模式詳解
java 代碼重構(系列講解)後,我再次檢視夥伴的代碼,找到了幾處可以規範的地方。
(六)實驗體會與總結
通過本次實驗,我主要學習到了代碼标準,代碼重構,Java中密碼學算法等内容。
代碼标準和重構的學習,使我注意到自己之前編寫代碼時的很多不規範之處,而且通過使用alibaba的實時編碼掃描,使我在編寫代碼的同時,注意規範代碼的标準格式,使寫出的代碼更加明了可觀,類名和變量名的規範,也使我在編寫代碼時,減少了許多不必要的注釋。
有了之前四則運算結對程式設計的鍛煉,在本次實驗過程中,我與我的小夥伴合作的比較融洽,節約了一些不必要的時間,結對程式設計效率有了一定的提高。
一、實驗報告封面
課程:Java程式設計 班級:1652班
指導教師:婁嘉鵬 實驗日期:2018年4月27日
實驗時間:13:45 - 15:25 實驗序号:實驗三
實驗名稱:靈活開發與XP實踐
實驗内容:
- XP基礎
- XP核心實踐
- 相關工具
實驗要求:
- 沒有Linux基礎的同學建議先學習《Linux基礎入門(新版)》《Vim編輯器》 課程
- 完成實驗、撰寫實驗報告,實驗報告以部落格方式發表在部落格園,注意實驗報告重點是運作結果,遇到的問題(工具查找,安裝,使用,程式的編輯,調試,運作等)、解決辦法(空洞的方法如“查網絡”、“問同學”、“看書”等一律得0分)以及分析(從中可以得到什麼啟示,有什麼收獲,教訓等)。報告可以參考範飛龍老師的指導
- 嚴禁抄襲,有該行為者實驗成績歸零,并附加其他懲罰措施。
二、實驗内容及步驟
(一)編碼标準
- 安裝alibaba 插件,解決代碼中的規範問題。具體流程如下:
- 打開
->Settings
->Plugins
Browse
...repositories
- 在搜尋框輸入
即可看到alibaba
插件,點選Alibaba Java Code Guidelines
進行安裝,然後重新開機IDE生效:Install
- 使用比較簡單:在項目名稱上單擊右鍵,在彈出菜單上選擇
:編碼規約掃描
出現下圖内容:
不規範的地方,有中文提示并且定位到了行,alibaba把問題分為
block/critical/major
三個等級,有些規則可以一鍵修複。
Java中的一般的命名規則有:
- 要展現各自的含義
- 包、類、變量用名詞
- 方法名用動賓
- 包名全部小寫,如:io,awt
- 類名第一個字母要大寫,如:HelloWorldApp
-
變量名第一個字母要小寫
,如:userName
- 方法名第一個字母要小寫:setName
規範後的代碼格式
import java.util.concurrent.Callable;
public class CodeStandard {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer();
buffer.append('S');
buffer.append("tringBuffer");
System.out.println(buffer.charAt(1));
System.out.println(buffer.capacity());
System.out.println(buffer.indexOf("tring"));
System.out.println("buffer = " + buffer.toString());
if (buffer.capacity() < 20) {
buffer.append("1234567");
}
for (int i = 0; i < buffer.length(); i++) {
System.out.println(buffer.charAt(i));
}
}
}
任務一:在IDEA中使用工具(Code->Reformate Code)格式化代碼,并學習Code菜單的功能
IDEA中的Code菜單如下:
幾個比較常用的功能總結如下:
-
(Ctrl+O):重載基本類的方法;Override Methods
-
Implement Methods
(Ctrl+I):完成目前類 implements 的(或者抽象基本類的)接口的方法;
Generate(Alt+Insert):建立類裡面任何字段的 getter 與 setter 方法;
-
(Ctrl+Alt+T):使用if-else、try-catch、do-while等包裝代碼段;Surround With
-
(Ctrl-J):執行一些記不起來的 Live Template 縮寫;Insert Live Template
-
(Ctrl+斜杠)/Comment with Line Comment
(Ctrl+Shift+斜杠):用 Ctrl+斜杠 與 Ctrl-Shift-/ 來注釋(或反注釋)代碼行與代碼塊。 用Ctrl+斜杠單行注釋标記(“ //… ”)來注釋(或反注釋)目前行或者選擇地代碼塊。而 Ctrl+Shift+斜杠則可以用塊注釋标記(“ /* */”)把所選塊包圍起來。要反注釋一個代碼塊就在塊中任何一個地方按 Ctrl+Shift+斜杠 即可;Comment with Block Comment
-
(Ctrl+Alt+L):将代碼按标準格式縮進;Reformat Code
-
:按照格式自動對齊show reformat file dialog
-
:可以優化imports,去除不必要的importsOptimize imports
-
:将某行、表達式向下、向上移動一行Move Line/statement Down/Up
(二)靈活開發與XP
任務二:下載下傳搭檔實驗二的Complex代碼,加入不少于三個JUnit單元測試用例
搭檔的Complex代碼如下:
需要測試的方法有:
ComplexAdd()
,
ComplexSub()
,
ComplexMulti()
,
ComplexDiv()
;
編寫測試代碼并上傳到搭檔碼雲項目上:
import junit.framework.TestCase;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Created by sxx on 2018/4/26.
*/
public class ComplexTest extends TestCase {
Complex c1 = new Complex(0.0, 2.0);
Complex c2 = new Complex(-1.0, -1.0);
Complex c3 = new Complex(1.0,2.0);
@Test
public void testgetRealpart() throws Exception{
assertEquals(0.0,Complex.getRealPart(0.0));
assertEquals(-1.0,Complex.getRealPart(-1.0));
assertEquals(1.0,Complex.getRealPart(1.0));
}
@Test
public void testgetImagePart() throws Exception{
assertEquals(2.0,Complex.getImagePart(2.0));
assertEquals(-1.0,Complex.getImagePart(-1.0));
assertEquals(2.0,Complex.getImagePart(2.0));
}
@Test
public void testComplexAdd() throws Exception{
assertEquals("-1.0+1.0i",c1.ComplexAdd(c2).toString());
assertEquals("1.0+4.0i",c1.ComplexAdd(c3).toString());
assertEquals("0.0+1.0i",c2.ComplexAdd(c3).toString());
}
@Test
public void testComplexSub() throws Exception{
assertEquals("1.0+3.0i",c1.ComplexSub(c2).toString());
assertEquals("-1.0",c1.ComplexSub(c3).toString());
assertEquals("-2.0-3.0i",c2.ComplexSub(c3).toString());
}
@Test
public void testComplexMulti() throws Exception{
assertEquals("2.0-2.0i",c1.ComplexMulti(c2).toString());
assertEquals("-4.0+2.0i",c1.ComplexMulti(c3).toString());
assertEquals("1.0-3.0i",c2.ComplexMulti(c3).toString());
}
@Test
public void testComplexDiv() throws Exception{
assertEquals("-1.0-1.0i",c1.ComplexDiv(c2).toString());
assertEquals("0.4+0.8i",c1.ComplexDiv(c3).toString());
assertEquals("-0.6-0.6i",c2.ComplexDiv(c3).toString());
}
}
(三)重構
重構(Refactor),就是在不改變軟體外部行為的基礎上,改變軟體内部的結構,使其更加易于閱讀、易于維護和易于變更 。
我們要修改軟體,萬變不離其宗,無非就是四種動機:
- 增加新功能;
- 原有功能有BUG;
- 改善原有程式的結構;
- 優化原有系統的性能 。
需要重構的地方:
代碼重複、方法過長、參數列過長、條件邏輯過度複雜、分支語句
一個完整的重構流程包括:
- 從版本控制系統代碼庫中Check out code
- 讀懂代碼(包括測試代碼)
- 發現bad smell
- Refactoring
- 運作所有的Unit Tests
- 往代碼庫中Check in code
任務三:下載下傳搭檔的代碼,至少進行三項重構
如上代碼存在以下幾個問題:
- 類名不符合命名規則;
- 類中變量沒有被封裝;
- 方法沒有被封裝;
練習
任務四:以結對的方式完成Java密碼學相關内容的學習,結合重構、git、代碼标準等
Java安全體系結構總共分為4個部分:
- JCA( Java Cryptography Architecture, Java加密體系結構):JCA提供基本的加密架構, 如證書、 數字簽名、消息摘要和密鑰對産生器。
- JCE( Java Cryptography Extension, Java加密擴充包):JCE在JCA的基礎上作了擴充, 提供了各種加密算法、 消息摘要算法和密鑰管理等功能。JCE的實作主要在javax.crypto包( 及其子包) 中
- JSSE( Java Secure Sockets Extension, Java安全套接字擴充包):JSSE提供了基于SSL( Secure Sockets Layer,安全套接字層) 的加密功能。 在網絡的傳輸過程中, 資訊會經過多個主機(很有可能其中一台就被竊聽) , 最終傳送給接收者, 這是不安全的。這種確定網絡通信安全的服務就是由JSSE來提供的。
- JAAS( Java Authentication and Authentication Service, Java鑒别與安全服務):JAAS提供了在Java平台上進行使用者身份鑒别的功能。
進行了學習之後,我與搭檔選擇了實作凱撒密碼的加解密算法,并以結對的方式完成了代碼編寫的工作。
凱撒密碼算法:将字母表中的字母移動一定位置而實作加密。
-
具體步驟:
(1)根據凱撒密碼特性設計算法
(2)傳入需要計算的字元串
(3)處理計算結果
- 僞代碼:
定義main方法
傳入參數
參數判斷,是否有非法輸入,若有,抛出異常
進行加解密,大小寫區分
輸出結果
-
産品代碼:
Caesaar.java
public class Caesar {
public static void main(String[] args) throws EadException {
String s = args[0];
int key = Integer.parseInt(args[1]);
String es = "";
for (int i = 0; i < (s.length()); i++) {
char c = s.charAt(i);
//自定義異常類
try {
boolean exist = ((c > 64) && (c < 91)) || ((c > 96) && (c < 123) || c == 32 || c == 33);
if (exist == false) {
throw new EadException(s);
}
} catch (EadException e) {
System.out.println(e.warnMess());
}
//小寫字母
if (c >= 'a' && c <= 'z') {
//移動key%26位
c += key % 26;
//向左超界
if (c < 'a') {
c += 26;
}
//向右超界
if (c > 'z') {
c -= 26;
}
}
//大寫字母
else if (c >= 'A' && c <= 'Z') {
c += key % 26;
if (c < 'A') {
c += 26;
}
if (c > 'Z') {
c -= 26;
}
}
es += c;
}
System.out.println(es);
}
}
EadException.java
public class Caesar {
public static void main(String[] args) throws EadException {
String s = args[0];
int key = Integer.parseInt(args[1]);
String es = "";
for (int i = 0; i < (s.length()); i++) {
char c = s.charAt(i);
//自定義異常類
try {
boolean exist = ((c > 64) && (c < 91)) || ((c > 96) && (c < 123) || c == 32 || c == 33);
if (exist == false) {
throw new EadException(s);
}
} catch (EadException e) {
System.out.println(e.warnMess());
}
//小寫字母
if (c >= 'a' && c <= 'z') {
//移動key%26位
c += key % 26;
//向左超界
if (c < 'a') {
c += 26;
}
//向右超界
if (c > 'z') {
c -= 26;
}
}
//大寫字母
else if (c >= 'A' && c <= 'Z') {
c += key % 26;
if (c < 'A') {
c += 26;
}
if (c > 'Z') {
c -= 26;
}
}
es += c;
}
System.out.println(es);
}
}
運作結果:
除了實作凱撒密碼算法之外,我還運作了其他算法:
DES算法
- 檔案key1.dat中生成的密鑰
- 儲存密鑰編碼并列印
- 用DESede加密
- 用DESede解密
RSA加密
RSA解密
MD5算法
(五)實驗過程中遇到的問題及解決方法
- 在做重構相關内容的實驗時,由于對重構的内容并不是非常了解,小夥伴的代碼也大都是書上的代碼,找了好多,都沒有發現太多需要重構的地方。
-
解決方法:在學習了實驗三 靈活開發與XP實踐——婁老師的部落格,以及參考了Java代碼重構的幾種模式詳解
java 代碼重構(系列講解)後,我再次檢視夥伴的代碼,找到了幾處可以規範的地方。
(六)實驗體會與總結
通過本次實驗,我主要學習到了代碼标準,代碼重構,Java中密碼學算法等内容。
代碼标準和重構的學習,使我注意到自己之前編寫代碼時的很多不規範之處,而且通過使用alibaba的實時編碼掃描,使我在編寫代碼的同時,注意規範代碼的标準格式,使寫出的代碼更加明了可觀,類名和變量名的規範,也使我在編寫代碼時,減少了許多不必要的注釋。
有了之前四則運算結對程式設計的鍛煉,在本次實驗過程中,我與我的小夥伴合作的比較融洽,節約了一些不必要的時間,結對程式設計效率有了一定的提高。