作者認為不管是變數、函式或類別的名稱都要告訴人為什麼會在這裡出現、要做什麼,以及如何使用它。舉例而言,
較差的命名方式:
pulic List<int[]> getThem() {
List<int[]> list1 = new ArrayList<int[]>();
for (int[] x: theList)
if (x[0]==4)
list1.add(x);
return list1;
}
修改後,才知道原來是插旗遊戲
pulic List<int[]> getFlaggedCells() {
List<int[]> flaggedCells = new ArrayList<int[]>();
for (int[] cell: gameBoard)
if (cell[STATUS_VALUE]== FLAGGED)
flaggedCells.add(cell);
return flaggedCells;
}
甚至可以創造類別Cell,並在類別中設計有意圖的函式(isFlagged),取代整數陣列
pulic List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<Cell>();
for (Cell cell: gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells;
}
Do
(一)產生有意義的區別
(二)使用可以念得出來的名稱
(三)使用可被搜尋的名字
for(int j=0 j<34; j++){
s += (t[j]*4)/5;
}
較佳的範例:
int realDaysPerIdealDay = 4;
const int WORK_PER_WEEK = 5;
int sum = 0;
for(int j=0 j<NUMBER_OF_TASKS; j++){
int realTaskDays = taskEstimat[j]*realDaysPerIdealDay;
...
}
(四)每個概念使用一種字詞
為一抽象概念挑選一字詞,並持續使用,如同一程式庫中,DeviceManager和ProtocalController若無實質差異的話是不是都可改成controller或manager?
(五)使用解決方案/問題領域的命名
(六)加上有意義的上下文資訊,但不能無理由添加
(七) 類別的命名建議用名詞或名詞片語,如Customer、Account等。
(八) 方法的命名建議用動詞或動詞片語,如deletePage。
DON'T
(一)避免使用誤導性字詞
(二)避免編碼
(三)避免思維轉換
除了像是迴圈計數變數在約定俗成上會使用i、j、k。
(四)避免使用雙關語
像是add和append(附加)和insert(插入)在使用情境上不同,所以不能互相通用。
Ans: JAR (Java ARchive) 檔是 Java 平台上用於封裝多個檔案(通常是 Java 類和資源檔案)到單一壓縮檔案的格式;WAR (Web Application Archive) 檔是用於分發和部署 Java Web 應用程式的壓縮檔案;EAR (Enterprise Archive) 檔是用於分發和部署 Java EE(企業版)應用程式的壓縮檔案。
Ans: 簡單工廠又稱為靜態工廠模式,一般來說,同一工廠內所產生的類別會有一個共同的父類別(介面)。
假設有一冒險者(父類別)訓練營(簡單工廠),冒險者種類有弓箭手(實體產品)、鬥士(實體產品)。今天若要增加種類(如法師),就得要修改訓練營類別內的程式碼,在冒險者方法中增加分支,因此簡單工廠不能算是一個健全的設計模式。
不過在小型的軟體架構中很好用,實務上也常常會用到這個簡單的模式。
※資料來源:簡單工廠模式
簡單工廠:
public class TrainingCamp {
public static Adventurer trainAdventurer(String type){
switch(type){
case "archer" : {
System.out.println("訓練一個弓箭手");
return new Archer();
}
case "warrior": {
...
}
}
父類別:
// 冒險者(Product)
public interface Adventurer {
//告訴別人你是哪種冒險者
String getType();
}
// 弓箭手(ConcreteProduct)
public class Archer implements Adventurer {
@Override
public String getType() {
System.out.println("我是弓箭手");
return this.getClass().getSimpleName();
}
}
測試碼:
public class VillageTest {
@Test
public void test(){
//新手村訓練冒險者
Adventurer memberA = Village.trainAdventurer("archer");
//這邊用Junit來幫我們判斷訓練出來的冒險者是不是我們想要的
Assert.assertEquals(memberA.getType(), "Archer");
//ouput:我是弓箭手
}
}
Ans:為了改善簡單工廠模式需要直接修改工廠類別裡面的程式碼,破壞開放/封閉原則的問題,在工廠模式中,將工廠(Factory)提升為一種抽象的概念--介面(Interface)。
工廠介面只會規範實體工廠類別(Concrete Factory)應該返回哪種產品,實際上要如何製作產品則交給實體工廠來實作。
以前例來說,新手村現在建立了兩座訓練營,弓箭手訓練營、鬥士訓練營。如果想要修改弓箭手的訓練流程,就修改弓箭手訓練營裡面的程式碼。如果增加訓練種類,就多蓋一座訓練營。
※資料來源:抽象工廠模式
工廠介面與實作的差別:
/**
* 冒險者訓練營介面(Factory)-這邊只是一個概念或規範,要訓練什麼,怎麼訓練留給子類別實作
*/
public interface TrainingCamp {
//訓練冒險者的過程,訓練後請給我一個冒險者
public Adventurer trainAdventurer();
}
/**
* 弓箭手訓練營(ConcreteFactory)
*/
public class ArcherTrainingCamp implements TrainingCamp {
@Override
public Adventurer trainAdventurer() {
System.out.println("訓練一個弓箭手");
return new Archer();
}
}
Complex FUL = Complex.FromRealNumber(23.0)
Complex FUL = new Complex(23.0) //直接用建構子
Ans:因為工廠方法具備名稱可以明確描述物件的創建意圖和上下文、避免建構子多載的混淆工廠方法、允許在創建物件時執行額外的邏輯或檢查、可以返回不同型別的物件等優點。
又所謂建構子多載意指一個類別中定義多個建構子(Constructor),這些建構子的名稱相同,但參數的數量、類型或順序不同。
Ans:public在別的class或是main裡面也可以用。
在了解基本定義後,下一章要談的是函式。