重構勘誤表

以下是目前已知的《重構》一書中的錯誤。

第 24 版及以後版本中的錯誤

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 16 版至第 24 版中的錯誤

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 119 頁:在機制開始時,新增一個步驟:「檢查賦值的右側沒有副作用」。[已在第 24 版中更正]

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 165 頁:倒數第二個程式碼範例不正確,應該如下所示。

class MfDateSub extends Date {
  public MfDateSub nextDay()...
  public int dayOfYear()...
[已在第 24 版中更正]

第 165 頁:在最後一個程式碼範例中,class mfDate 應該改為 class MfDateWrap [已在第 24 版中更正]

第 166 頁:在倒數第二個程式碼範例中,class mfDate 應讀為 class MfDateWrap [已於第 24 次印刷中更正]

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁:約在三分之一處,equals 方法不正確。應讀為

        public boolean equals(Object arg) {
             if (this == arg) return true;
             if (! (arg instanceof MfDateWrap)) return false;
             MfDateWrap other = ((MfDateWrap) arg);
             return  (_original.equals(other._original));
         }
      
[已在第 24 版中更正]

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 15 次印刷中的錯誤

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 119 頁:在機制開始時,新增一個步驟:「檢查賦值的右側沒有副作用」。[已在第 24 版中更正]

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 153 頁:在第二段的第三行,「如 Lea 在部分中所討論的...」應讀為「如 Lea 部分中所討論的...」[已於第 16 次印刷中更正]

第 165 頁:倒數第二個程式碼範例不正確,應該如下所示。

class MfDateSub extends Date {
  public MfDateSub nextDay()...
  public int dayOfYear()...
[已在第 24 版中更正]

第 165 頁:在最後一個程式碼範例中,class mfDate 應該改為 class MfDateWrap [已在第 24 版中更正]

第 166 頁:在倒數第二個程式碼範例中,class mfDate 應讀為 class MfDateWrap [已於第 24 次印刷中更正]

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁:約在三分之一處,equals 方法不正確。應讀為

        public boolean equals(Object arg) {
             if (this == arg) return true;
             if (! (arg instanceof MfDateWrap)) return false;
             MfDateWrap other = ((MfDateWrap) arg);
             return  (_original.equals(other._original));
         }
      
[已在第 24 版中更正]

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 222 頁:在頁面底部,我將 getCode 方法設為私有。顯然,當 BloodGroup 的任何用戶端正在使用該方法時,我無法這麼做。因此,句子「我也可以將這些方法設為私有...」應改為「如果沒有用戶端使用數字代碼,我也可以將這些方法設為私有...」[已於第 16 次印刷中更正]

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 13 至 15 次印刷中的錯誤

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 83 頁:在推測性概括部分的第一段的第二個句子。「喔,我想我們需要有能力做到這件事...」應讀為「喔,我想我們需要有能力做到這件事...」[已於第 15 次印刷中更正]

第 98 頁:testReadAtEnd 方法不正確。我查看了我的原始檔,發現該方法寫成

 public
  void testReadAtEnd() throws IOException {
    int ch = -1234;
    for (int i = 0; i < 141; i++)
      ch = _input.read();
    assertEquals("read at end", -1, _input.read());
  }
  
慶幸的是,現在我可以自動插入原始碼![已於第 15 次印刷中更正]

第 115 頁:在第三行,「rerun」應為「return」[已於第 15 次印刷中更正]

第 119 頁:在機制開始時,新增一個步驟:「檢查賦值的右側沒有副作用」。[已在第 24 版中更正]

第 120 頁:最後一行,「...僅指派一次...」應讀為「...僅指派一次...」[已於第 15 次印刷中更正]

第 120 頁:在解決方案陳述中,「將所有對 temp 的參照替換為表達式」這句話應替換為「將所有對 temp 的參照替換為新的方法」[已於第 15 次印刷中更正]

第 128 頁:在動機的第一段中,表達式「for (int i=0; i<10; i++)」需要額外的括號來平衡前面的文字括號。[已於第 15 次印刷中更正]

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 153 頁:在第二段的第三行,「如 Lea 在部分中所討論的...」應讀為「如 Lea 部分中所討論的...」[已於第 16 次印刷中更正]

第 165 頁:倒數第二個程式碼範例不正確,應該如下所示。

class MfDateSub extends Date {
  public MfDateSub nextDay()...
  public int dayOfYear()...
[已在第 24 版中更正]

第 165 頁:在最後一個程式碼範例中,class mfDate 應該改為 class MfDateWrap [已在第 24 版中更正]

第 166 頁:在倒數第二個程式碼範例中,class mfDate 應讀為 class MfDateWrap [已於第 24 次印刷中更正]

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁:約在三分之一處,equals 方法不正確。應讀為

        public boolean equals(Object arg) {
             if (this == arg) return true;
             if (! (arg instanceof MfDateWrap)) return false;
             MfDateWrap other = ((MfDateWrap) arg);
             return  (_original.equals(other._original));
         }
      
[已在第 24 版中更正]

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 176 頁:在第二段(機制中的步驟)中,「變更取得方法」應讀為「變更設定方法」[已於第 15 次印刷中更正]

第 222 頁:在頁面底部,我將 getCode 方法設為私有。顯然,當 BloodGroup 的任何用戶端正在使用該方法時,我無法這麼做。因此,句子「我也可以將這些方法設為私有...」應改為「如果沒有用戶端使用數字代碼,我也可以將這些方法設為私有...」[已於第 16 次印刷中更正]

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 349 頁:第一段落應以一個閉合括號作結,以與第一行的括號相符。[已在第 15 次印刷中更正]

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 12 次印刷中的錯誤

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 83 頁:在推測性概括部分的第一段的第二個句子。「喔,我想我們需要有能力做到這件事...」應讀為「喔,我想我們需要有能力做到這件事...」[已於第 15 次印刷中更正]

第 98 頁:testReadAtEnd 方法不正確。我查看了我的原始檔,發現該方法寫成

 public
  void testReadAtEnd() throws IOException {
    int ch = -1234;
    for (int i = 0; i < 141; i++)
      ch = _input.read();
    assertEquals("read at end", -1, _input.read());
  }
  
慶幸的是,現在我可以自動插入原始碼![已於第 15 次印刷中更正]

第 115 頁:在第三行,「rerun」應為「return」[已於第 15 次印刷中更正]

第 119 頁:在機制開始時,新增一個步驟:「檢查賦值的右側沒有副作用」。[已在第 24 版中更正]

第 120 頁:最後一行,「...僅指派一次...」應讀為「...僅指派一次...」[已於第 15 次印刷中更正]

第 120 頁:在解決方案陳述中,「將所有對 temp 的參照替換為表達式」這句話應替換為「將所有對 temp 的參照替換為新的方法」[已於第 15 次印刷中更正]

第 121 頁:這是對先前錯誤的錯誤修正。在機制中的最後一行,重構「以內嵌暫存變數取代暫存變數」應寫成「內嵌暫存變數」。第 122 頁也有相同的問題。[已在第 13 次印刷中更正]

第 128 頁:在動機的第一段中,表達式「for (int i=0; i<10; i++)」需要額外的括號來平衡前面的文字括號。[已於第 15 次印刷中更正]

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 153 頁:在第二段的第三行,「如 Lea 在部分中所討論的...」應讀為「如 Lea 部分中所討論的...」[已於第 16 次印刷中更正]

第 165 頁:倒數第二個程式碼範例不正確,應該如下所示。

class MfDateSub extends Date {
  public MfDateSub nextDay()...
  public int dayOfYear()...
[已在第 24 版中更正]

第 165 頁:在最後一個程式碼範例中,class mfDate 應該改為 class MfDateWrap [已在第 24 版中更正]

第 166 頁:在倒數第二個程式碼範例中,class mfDate 應讀為 class MfDateWrap [已於第 24 次印刷中更正]

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁:約在三分之一處,equals 方法不正確。應讀為

        public boolean equals(Object arg) {
             if (this == arg) return true;
             if (! (arg instanceof MfDateWrap)) return false;
             MfDateWrap other = ((MfDateWrap) arg);
             return  (_original.equals(other._original));
         }
      
[已在第 24 版中更正]

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 176 頁:在第二段(機制中的步驟)中,「變更取得方法」應讀為「變更設定方法」[已於第 15 次印刷中更正]

第 222 頁:在頁面底部,我將 getCode 方法設為私有。顯然,當 BloodGroup 的任何用戶端正在使用該方法時,我無法這麼做。因此,句子「我也可以將這些方法設為私有...」應改為「如果沒有用戶端使用數字代碼,我也可以將這些方法設為私有...」[已於第 16 次印刷中更正]

第 225 頁:create 方法的第一次提及缺少 static 關鍵字。[已在第 13 次印刷中更正]

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 349 頁:第一段落應以一個閉合括號作結,以與第一行的括號相符。[已在第 15 次印刷中更正]

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 363 頁:此頁面中對重構的參照是與章節參照交叉參照,而非通常的頁面參照。更糟的是,Extract Class 的章節應為第 7 章。[已在第 13 次印刷中更正]

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 8 至 12 次印刷中的錯誤

第 2 頁:第一段落中的「並識別電影類型」應寫成「並識別電影類型」。[已在第 12 次印刷中更正]

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 40 頁:第 40 和 41 頁的程式碼範例中,對欄位 _name 的參照應改為 _title [已在第 12 次印刷中更正]

第 83 頁:在推測性概括部分的第一段的第二個句子。「喔,我想我們需要有能力做到這件事...」應讀為「喔,我想我們需要有能力做到這件事...」[已於第 15 次印刷中更正]

第 98 頁:testReadAtEnd 方法不正確。我查看了我的原始檔,發現該方法寫成

 public
  void testReadAtEnd() throws IOException {
    int ch = -1234;
    for (int i = 0; i < 141; i++)
      ch = _input.read();
    assertEquals("read at end", -1, _input.read());
  }
  
慶幸的是,現在我可以自動插入原始碼![已於第 15 次印刷中更正]

第 115 頁:在第三行,「rerun」應為「return」[已於第 15 次印刷中更正]

第 119 頁:在機制開始時,新增一個步驟:「檢查賦值的右側沒有副作用」。[已在第 24 版中更正]

第 120 頁:最後一行,「...僅指派一次...」應讀為「...僅指派一次...」[已於第 15 次印刷中更正]

第 120 頁:在解決方案陳述中,「將所有對 temp 的參照替換為表達式」這句話應替換為「將所有對 temp 的參照替換為新的方法」[已於第 15 次印刷中更正]

第 121 頁:這是對先前錯誤的錯誤修正。在機制中的最後一行,重構「以內嵌暫存變數取代暫存變數」應寫成「內嵌暫存變數」。第 122 頁也有相同的問題。[已在第 13 次印刷中更正]

第 128 頁:在動機的第一段中,表達式「for (int i=0; i<10; i++)」需要額外的括號來平衡前面的文字括號。[已於第 15 次印刷中更正]

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 153 頁:在第二段的第三行,「如 Lea 在部分中所討論的...」應讀為「如 Lea 部分中所討論的...」[已於第 16 次印刷中更正]

第 165 頁:倒數第二個程式碼範例不正確,應該如下所示。

class MfDateSub extends Date {
  public MfDateSub nextDay()...
  public int dayOfYear()...
[已在第 24 版中更正]

第 165 頁:在最後一個程式碼範例中,class mfDate 應該改為 class MfDateWrap [已在第 24 版中更正]

第 166 頁:在倒數第二個程式碼範例中,class mfDate 應讀為 class MfDateWrap [已於第 24 次印刷中更正]

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁:約在三分之一處,equals 方法不正確。應讀為

        public boolean equals(Object arg) {
             if (this == arg) return true;
             if (! (arg instanceof MfDateWrap)) return false;
             MfDateWrap other = ((MfDateWrap) arg);
             return  (_original.equals(other._original));
         }
      
[已在第 24 版中更正]

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 176 頁:在第二段(機制中的步驟)中,「變更取得方法」應讀為「變更設定方法」[已於第 15 次印刷中更正]

第 185 頁:第二段落中的「雙向異或」應寫成「位元異或」[已在第 12 次印刷中更正]

第 222 頁:在頁面底部,我將 getCode 方法設為私有。顯然,當 BloodGroup 的任何用戶端正在使用該方法時,我無法這麼做。因此,句子「我也可以將這些方法設為私有...」應改為「如果沒有用戶端使用數字代碼,我也可以將這些方法設為私有...」[已於第 16 次印刷中更正]

第 225 頁:create 方法的第一次提及缺少 static 關鍵字。[已在第 13 次印刷中更正]

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 349 頁:第一段落應以一個閉合括號作結,以與第一行的括號相符。[已在第 15 次印刷中更正]

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 363 頁:此頁面中對重構的參照是與章節參照交叉參照,而非通常的頁面參照。更糟的是,Extract Class 的章節應為第 7 章。[已在第 13 次印刷中更正]

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 5 至 8 次印刷中的錯誤

第 2 頁:第一段落中的「並識別電影類型」應寫成「並識別電影類型」。[已在第 12 次印刷中更正]

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 25 頁:圖 1.7 的標題「萃取前的順序圖...」應為「萃取後的順序圖...」[已在第 8 次印刷中更正]

第 40 頁:第 40 和 41 頁的程式碼範例中,對欄位 _name 的參照應改為 _title [已在第 12 次印刷中更正]

第 76 頁:「重複程式碼」中的第 3 段。「在兩個類別中,然後上拉欄位 (320)」應寫成「在兩個類別中,然後上拉方法 (322)」[已在第 8 次印刷中更正]

第 83 頁:在推測性概括部分的第一段的第二個句子。「喔,我想我們需要有能力做到這件事...」應讀為「喔,我想我們需要有能力做到這件事...」[已於第 15 次印刷中更正]

第 98 頁:testReadAtEnd 方法不正確。我查看了我的原始檔,發現該方法寫成

 public
  void testReadAtEnd() throws IOException {
    int ch = -1234;
    for (int i = 0; i < 141; i++)
      ch = _input.read();
    assertEquals("read at end", -1, _input.read());
  }
  
慶幸的是,現在我可以自動插入原始碼![已於第 15 次印刷中更正]

第 115 頁:在第三行,「rerun」應為「return」[已於第 15 次印刷中更正]

第 119 頁:在機制開始時,新增一個步驟:「檢查賦值的右側沒有副作用」。[已在第 24 版中更正]

第 120 頁:最後一行,「...僅指派一次...」應讀為「...僅指派一次...」[已於第 15 次印刷中更正]

第 120 頁:在解決方案陳述中,「將所有對 temp 的參照替換為表達式」這句話應替換為「將所有對 temp 的參照替換為新的方法」[已於第 15 次印刷中更正]

第 121 頁:在機制的最後一個步驟中,我說要使用以查詢取代暫存變數 (120),這應改為參照內嵌暫存變數 (119)。否則我會得到遞迴重構。第 122 頁的範例中問題持續,交叉參照應為內嵌暫存變數 (119)。這在第 8 次印刷中已錯誤修正(見下方)[已在第 8 次印刷中更正]

第 121 頁:這是對先前錯誤的錯誤修正。在機制中的最後一行,重構「以內嵌暫存變數取代暫存變數」應寫成「內嵌暫存變數」。第 122 頁也有相同的問題。[已在第 13 次印刷中更正]

第 128 頁:在動機的第一段中,表達式「for (int i=0; i<10; i++)」需要額外的括號來平衡前面的文字括號。[已於第 15 次印刷中更正]

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 153 頁:在第二段的第三行,「如 Lea 在部分中所討論的...」應讀為「如 Lea 部分中所討論的...」[已於第 16 次印刷中更正]

第 165 頁:倒數第二個程式碼範例不正確,應該如下所示。

class MfDateSub extends Date {
  public MfDateSub nextDay()...
  public int dayOfYear()...
[已在第 24 版中更正]

第 165 頁:在最後一個程式碼範例中,class mfDate 應該改為 class MfDateWrap [已在第 24 版中更正]

第 166 頁:在倒數第二個程式碼範例中,class mfDate 應讀為 class MfDateWrap [已於第 24 次印刷中更正]

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁:約在三分之一處,equals 方法不正確。應讀為

        public boolean equals(Object arg) {
             if (this == arg) return true;
             if (! (arg instanceof MfDateWrap)) return false;
             MfDateWrap other = ((MfDateWrap) arg);
             return  (_original.equals(other._original));
         }
      
[已在第 24 版中更正]

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 176 頁:在第二段(機制中的步驟)中,「變更取得方法」應讀為「變更設定方法」[已於第 15 次印刷中更正]

第 176 頁:在方法 numberOfOrdersFor 中,讀取 if (each.getCustomerName().equals(customer)) result++; 的行應讀取 if (each.getCustomer().equals(customer)) result++; [已在第 8 次印刷中更正]

第 177 頁:在方法 setCustomer 的第一個狀態中,讀取 _customer = new Customer (customer); 的行應讀取 _customer = new Customer (arg); [已在第 8 次印刷中更正]

第 185 頁:第二段落中的「雙向異或」應寫成「位元異或」[已在第 12 次印刷中更正]

第 219 頁:「在頁面中段左右的一個段落中,句子「...需要一個回傳程式碼的新方法」應寫成「...需要一個回傳新類別實例的新方法。」[已在第 8 次印刷中更正]

第 222 頁:在頁面底部,我將 getCode 方法設為私有。顯然,當 BloodGroup 的任何用戶端正在使用該方法時,我無法這麼做。因此,句子「我也可以將這些方法設為私有...」應改為「如果沒有用戶端使用數字代碼,我也可以將這些方法設為私有...」[已於第 16 次印刷中更正]

第 222 頁:「在刪除線的程式碼中,方法 "public int getBloodGroup() {" 應為 "public int getBloodGroupCode() {"(我剛剛重新命名它!)[已在第 8 次印刷中更正]

第 225 頁:create 方法的第一次提及缺少 static 關鍵字。[已在第 13 次印刷中更正]

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 285 頁:之前的程式碼包含一個比重構更嚴重的錯誤,因為斷言總是會執行。之前的程式碼應為

  void setValue (String name, int value) {
    if (name.equals("height")) {
      _height = value;
      return;
    }
    if (name.equals("width")) {
      _width = value;
      return;
    }
    Assert.shouldNeverReachHere();
  }
  
[已於第 8 次印刷中修正]

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 313 頁

這行程式碼

  Assert.isTrue("amount too large", amount > _balance); 
  

有誤,因為布林值的意義是相反的。較好的程式碼應為

  Assert.isTrue("sufficient funds", amount <= _balance);
  
[已於第 8 次印刷中修正]

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 324 頁:在頂端的程式碼範例中,程式碼行 double chargeAmount = charge (lastBillDate, date) 應為 double chargeAmount = chargeFor (lastBillDate, date)。(我讓方法名稱與圖示不一致。)[已於第 8 次印刷中修正]

第 328 頁:在動機段落中,「Pull Down Method」應為「Push Down Method」。(這就是我不為所有內容使用連結時會發生的事!)[已於第 8 次印刷中修正]

第 349 頁:第一段落應以一個閉合括號作結,以與第一行的括號相符。[已在第 15 次印刷中更正]

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 363 頁:此頁面中對重構的參照是與章節參照交叉參照,而非通常的頁面參照。更糟的是,Extract Class 的章節應為第 7 章。[已在第 13 次印刷中更正]

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 4 次印刷中的錯誤

第 xx 頁:「Joshua 建議程式碼草圖的想法」應為「Joshua Kerievsky 建議程式碼草圖的想法」[已於第 5 次印刷中修正]

第 2 頁:第一段落中的「並識別電影類型」應寫成「並識別電影類型」。[已在第 12 次印刷中更正]

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 25 頁:圖 1.7 的標題「萃取前的順序圖...」應為「萃取後的順序圖...」[已在第 8 次印刷中更正]

第 40 頁:第 40 和 41 頁的程式碼範例中,對欄位 _name 的參照應改為 _title [已在第 12 次印刷中更正]

第 76 頁:「重複程式碼」中的第 3 段。「在兩個類別中,然後上拉欄位 (320)」應寫成「在兩個類別中,然後上拉方法 (322)」[已在第 8 次印刷中更正]

第 83 頁:在推測性概括部分的第一段的第二個句子。「喔,我想我們需要有能力做到這件事...」應讀為「喔,我想我們需要有能力做到這件事...」[已於第 15 次印刷中更正]

第 98 頁:testReadAtEnd 方法不正確。我查看了我的原始檔,發現該方法寫成

 public
  void testReadAtEnd() throws IOException {
    int ch = -1234;
    for (int i = 0; i < 141; i++)
      ch = _input.read();
    assertEquals("read at end", -1, _input.read());
  }
  
慶幸的是,現在我可以自動插入原始碼![已於第 15 次印刷中更正]

第 115 頁:在第三行,「rerun」應為「return」[已於第 15 次印刷中更正]

第 119 頁:在機制開始時,新增一個步驟:「檢查賦值的右側沒有副作用」。[已在第 24 版中更正]

第 120 頁:最後一行,「...僅指派一次...」應讀為「...僅指派一次...」[已於第 15 次印刷中更正]

第 120 頁:在解決方案陳述中,「將所有對 temp 的參照替換為表達式」這句話應替換為「將所有對 temp 的參照替換為新的方法」[已於第 15 次印刷中更正]

第 121 頁:在機制的最後一個步驟中,我說要使用以查詢取代暫存變數 (120),這應改為參照內嵌暫存變數 (119)。否則我會得到遞迴重構。第 122 頁的範例中問題持續,交叉參照應為內嵌暫存變數 (119)。這在第 8 次印刷中已錯誤修正(見下方)[已在第 8 次印刷中更正]

第 121 頁:這是對先前錯誤的錯誤修正。在機制中的最後一行,重構「以內嵌暫存變數取代暫存變數」應寫成「內嵌暫存變數」。第 122 頁也有相同的問題。[已在第 13 次印刷中更正]

第 128 頁:在動機的第一段中,表達式「for (int i=0; i<10; i++)」需要額外的括號來平衡前面的文字括號。[已於第 15 次印刷中更正]

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 153 頁:在第二段的第三行,「如 Lea 在部分中所討論的...」應讀為「如 Lea 部分中所討論的...」[已於第 16 次印刷中更正]

第 165 頁:倒數第二個程式碼範例不正確,應該如下所示。

class MfDateSub extends Date {
  public MfDateSub nextDay()...
  public int dayOfYear()...
[已在第 24 版中更正]

第 165 頁:在最後一個程式碼範例中,class mfDate 應該改為 class MfDateWrap [已在第 24 版中更正]

第 166 頁:在倒數第二個程式碼範例中,class mfDate 應讀為 class MfDateWrap [已於第 24 次印刷中更正]

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁:約在三分之一處,equals 方法不正確。應讀為

        public boolean equals(Object arg) {
             if (this == arg) return true;
             if (! (arg instanceof MfDateWrap)) return false;
             MfDateWrap other = ((MfDateWrap) arg);
             return  (_original.equals(other._original));
         }
      
[已在第 24 版中更正]

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 176 頁:在第二段(機制中的步驟)中,「變更取得方法」應讀為「變更設定方法」[已於第 15 次印刷中更正]

第 176 頁:在方法 numberOfOrdersFor 中,讀取 if (each.getCustomerName().equals(customer)) result++; 的行應讀取 if (each.getCustomer().equals(customer)) result++; [已在第 8 次印刷中更正]

第 177 頁:在方法 setCustomer 的第一個狀態中,讀取 _customer = new Customer (customer); 的行應讀取 _customer = new Customer (arg); [已在第 8 次印刷中更正]

第 185 頁:第二段落中的「雙向異或」應寫成「位元異或」[已在第 12 次印刷中更正]

第 193 頁:「宣告 interval window 實作 Observable」應為「宣告 interval window 實作 Observer」[已於第 5 次印刷中修正]

第 219 頁:「在頁面中段左右的一個段落中,句子「...需要一個回傳程式碼的新方法」應寫成「...需要一個回傳新類別實例的新方法。」[已在第 8 次印刷中更正]

第 222 頁:在頁面底部,我將 getCode 方法設為私有。顯然,當 BloodGroup 的任何用戶端正在使用該方法時,我無法這麼做。因此,句子「我也可以將這些方法設為私有...」應改為「如果沒有用戶端使用數字代碼,我也可以將這些方法設為私有...」[已於第 16 次印刷中更正]

第 222 頁:「在刪除線的程式碼中,方法 "public int getBloodGroup() {" 應為 "public int getBloodGroupCode() {"(我剛剛重新命名它!)[已在第 8 次印刷中更正]

第 225 頁:create 方法的第一次提及缺少 static 關鍵字。[已在第 13 次印刷中更正]

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 261 頁:在 Ron 的故事中,第 4 段,「當然,只要您開始檢查...」應為「當然,只要您開始檢查...」[已於第 5 次印刷中修正]

第 285 頁:之前的程式碼包含一個比重構更嚴重的錯誤,因為斷言總是會執行。之前的程式碼應為

  void setValue (String name, int value) {
    if (name.equals("height")) {
      _height = value;
      return;
    }
    if (name.equals("width")) {
      _width = value;
      return;
    }
    Assert.shouldNeverReachHere();
  }
  
[已於第 8 次印刷中修正]

第 300 頁:在機制區段中,欄位應在處理結束時設為最終,而非開始時。[已於第 5 次印刷中修正]

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 307 頁:「小心 class.forName 的另一個原因是...」應為:「小心 Class.forName 的另一個原因是...」(Class 應為大寫 C)[已於第 5 次印刷中修正]

第 307 頁:「我可以使用不同的方法....」應為:「我可以使用不同的方法...」(拼字)[已於第 5 次印刷中修正]

第 311 頁:「如果例外已檢查,調整呼叫者...」應為:「如果例外檢查,調整呼叫者...」[已於第 5 次印刷中修正]

第 313 頁

這行程式碼

  Assert.isTrue("amount too large", amount > _balance); 
  

有誤,因為布林值的意義是相反的。較好的程式碼應為

  Assert.isTrue("sufficient funds", amount <= _balance);
  
[已於第 8 次印刷中修正]

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 324 頁:在頂端的程式碼範例中,程式碼行 double chargeAmount = charge (lastBillDate, date) 應為 double chargeAmount = chargeFor (lastBillDate, date)。(我讓方法名稱與圖示不一致。)[已於第 8 次印刷中修正]

第 328 頁:在動機段落中,「Pull Down Method」應為「Push Down Method」。(這就是我不為所有內容使用連結時會發生的事!)[已於第 8 次印刷中修正]

第 333 頁:「有些參數是勞動項目需要的,有些則不是」應為:「有些參數是需要的...」(遺漏字詞)[已於第 5 次印刷中修正]

第 346 頁:「每當我們看到兩個類似的函式」應為:「每當我們看到兩個類似的函式」(複數)[已於第 5 次印刷中修正]

第 346 頁:「statement 方法列印陳述式」應為:「statement 方法列印陳述式」(字型)[在第 5 次印刷中更正]

第 349 頁:第一段落應以一個閉合括號作結,以與第一行的括號相符。[已在第 15 次印刷中更正]

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 363 頁:此頁面中對重構的參照是與章節參照交叉參照,而非通常的頁面參照。更糟的是,Extract Class 的章節應為第 7 章。[已在第 13 次印刷中更正]

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 3 次印刷中的錯誤

第 xx 頁:「Joshua 建議程式碼草圖的想法」應為「Joshua Kerievsky 建議程式碼草圖的想法」[已於第 5 次印刷中修正]

第 2 頁:第一段落中的「並識別電影類型」應寫成「並識別電影類型」。[已在第 12 次印刷中更正]

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 25 頁:圖 1.7 的標題「萃取前的順序圖...」應為「萃取後的順序圖...」[已在第 8 次印刷中更正]

第 40 頁:第 40 和 41 頁的程式碼範例中,對欄位 _name 的參照應改為 _title [已在第 12 次印刷中更正]

第 76 頁:「重複程式碼」中的第 3 段。「在兩個類別中,然後上拉欄位 (320)」應寫成「在兩個類別中,然後上拉方法 (322)」[已在第 8 次印刷中更正]

第 83 頁:在推測性概括部分的第一段的第二個句子。「喔,我想我們需要有能力做到這件事...」應讀為「喔,我想我們需要有能力做到這件事...」[已於第 15 次印刷中更正]

第 98 頁:testReadAtEnd 方法不正確。我查看了我的原始檔,發現該方法寫成

 public
  void testReadAtEnd() throws IOException {
    int ch = -1234;
    for (int i = 0; i < 141; i++)
      ch = _input.read();
    assertEquals("read at end", -1, _input.read());
  }
  
慶幸的是,現在我可以自動插入原始碼![已於第 15 次印刷中更正]

第 115 頁:在第三行,「rerun」應為「return」[已於第 15 次印刷中更正]

第 119 頁:在機制開始時,新增一個步驟:「檢查賦值的右側沒有副作用」。[已在第 24 版中更正]

第 120 頁:最後一行,「...僅指派一次...」應讀為「...僅指派一次...」[已於第 15 次印刷中更正]

第 120 頁:在解決方案陳述中,「將所有對 temp 的參照替換為表達式」這句話應替換為「將所有對 temp 的參照替換為新的方法」[已於第 15 次印刷中更正]

第 121 頁:在機制的最後一個步驟中,我說要使用以查詢取代暫存變數 (120),這應改為參照內嵌暫存變數 (119)。否則我會得到遞迴重構。第 122 頁的範例中問題持續,交叉參照應為內嵌暫存變數 (119)。這在第 8 次印刷中已錯誤修正(見下方)[已在第 8 次印刷中更正]

第 121 頁:這是對先前錯誤的錯誤修正。在機制中的最後一行,重構「以內嵌暫存變數取代暫存變數」應寫成「內嵌暫存變數」。第 122 頁也有相同的問題。[已在第 13 次印刷中更正]

第 128 頁:在動機的第一段中,表達式「for (int i=0; i<10; i++)」需要額外的括號來平衡前面的文字括號。[已於第 15 次印刷中更正]

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 153 頁:在第二段的第三行,「如 Lea 在部分中所討論的...」應讀為「如 Lea 部分中所討論的...」[已於第 16 次印刷中更正]

第 165 頁:倒數第二個程式碼範例不正確,應該如下所示。

class MfDateSub extends Date {
  public MfDateSub nextDay()...
  public int dayOfYear()...
[已在第 24 版中更正]

第 165 頁:在最後一個程式碼範例中,class mfDate 應該改為 class MfDateWrap [已在第 24 版中更正]

第 166 頁:在倒數第二個程式碼範例中,class mfDate 應讀為 class MfDateWrap [已於第 24 次印刷中更正]

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁:約在三分之一處,equals 方法不正確。應讀為

        public boolean equals(Object arg) {
             if (this == arg) return true;
             if (! (arg instanceof MfDateWrap)) return false;
             MfDateWrap other = ((MfDateWrap) arg);
             return  (_original.equals(other._original));
         }
      
[已在第 24 版中更正]

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 176 頁:在第二段(機制中的步驟)中,「變更取得方法」應讀為「變更設定方法」[已於第 15 次印刷中更正]

第 176 頁:在方法 numberOfOrdersFor 中,讀取 if (each.getCustomerName().equals(customer)) result++; 的行應讀取 if (each.getCustomer().equals(customer)) result++; [已在第 8 次印刷中更正]

第 177 頁:在方法 setCustomer 的第一個狀態中,讀取 _customer = new Customer (customer); 的行應讀取 _customer = new Customer (arg); [已在第 8 次印刷中更正]

第 185 頁:第二段落中的「雙向異或」應寫成「位元異或」[已在第 12 次印刷中更正]

第 193 頁:「宣告 interval window 實作 Observable」應為「宣告 interval window 實作 Observer」[已於第 5 次印刷中修正]

第 219 頁:「在頁面中段左右的一個段落中,句子「...需要一個回傳程式碼的新方法」應寫成「...需要一個回傳新類別實例的新方法。」[已在第 8 次印刷中更正]

第 222 頁:在頁面底部,我將 getCode 方法設為私有。顯然,當 BloodGroup 的任何用戶端正在使用該方法時,我無法這麼做。因此,句子「我也可以將這些方法設為私有...」應改為「如果沒有用戶端使用數字代碼,我也可以將這些方法設為私有...」[已於第 16 次印刷中更正]

第 222 頁:「在刪除線的程式碼中,方法 "public int getBloodGroup() {" 應為 "public int getBloodGroupCode() {"(我剛剛重新命名它!)[已在第 8 次印刷中更正]

第 225 頁:create 方法的第一次提及缺少 static 關鍵字。[已在第 13 次印刷中更正]

第 241 頁:頁面底部的程式碼範例中,方法 isEligibleForDisability 應為 isNotEligibleForDisability [在第 4 次印刷中更正]

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 261 頁:在 Ron 的故事中,第 4 段,「當然,只要您開始檢查...」應為「當然,只要您開始檢查...」[已於第 5 次印刷中修正]

第 285 頁:之前的程式碼包含一個比重構更嚴重的錯誤,因為斷言總是會執行。之前的程式碼應為

  void setValue (String name, int value) {
    if (name.equals("height")) {
      _height = value;
      return;
    }
    if (name.equals("width")) {
      _width = value;
      return;
    }
    Assert.shouldNeverReachHere();
  }
  
[已於第 8 次印刷中修正]

第 300 頁:在機制區段中,欄位應在處理結束時設為最終,而非開始時。[已於第 5 次印刷中修正]

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 307 頁:「小心 class.forName 的另一個原因是...」應為:「小心 Class.forName 的另一個原因是...」(Class 應為大寫 C)[已於第 5 次印刷中修正]

第 307 頁:「我可以使用不同的方法....」應為:「我可以使用不同的方法...」(拼字)[已於第 5 次印刷中修正]

第 311 頁:「如果例外已檢查,調整呼叫者...」應為:「如果例外檢查,調整呼叫者...」[已於第 5 次印刷中修正]

第 313 頁

這行程式碼

  Assert.isTrue("amount too large", amount > _balance); 
  

有誤,因為布林值的意義是相反的。較好的程式碼應為

  Assert.isTrue("sufficient funds", amount <= _balance);
  
[已於第 8 次印刷中修正]

第 315 頁:問題陳述應為「您在呼叫者可以先檢查的條件上引發例外」(重構適用於所有例外,不只檢查過的例外)[在第 4 次印刷中更正]

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 324 頁:在頂端的程式碼範例中,程式碼行 double chargeAmount = charge (lastBillDate, date) 應為 double chargeAmount = chargeFor (lastBillDate, date)。(我讓方法名稱與圖示不一致。)[已於第 8 次印刷中修正]

第 328 頁:在動機段落中,「Pull Down Method」應為「Push Down Method」。(這就是我不為所有內容使用連結時會發生的事!)[已於第 8 次印刷中修正]

第 333 頁:「有些參數是勞動項目需要的,有些則不是」應為:「有些參數是需要的...」(遺漏字詞)[已於第 5 次印刷中修正]

第 346 頁:「每當我們看到兩個類似的函式」應為:「每當我們看到兩個類似的函式」(複數)[已於第 5 次印刷中修正]

第 346 頁:「statement 方法列印陳述式」應為:「statement 方法列印陳述式」(字型)[在第 5 次印刷中更正]

第 349 頁:第一段落應以一個閉合括號作結,以與第一行的括號相符。[已在第 15 次印刷中更正]

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 363 頁:此頁面中對重構的參照是與章節參照交叉參照,而非通常的頁面參照。更糟的是,Extract Class 的章節應為第 7 章。[已在第 13 次印刷中更正]

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 1 次到第 3 次印刷中的錯誤

第 xx 頁:「Joshua 建議程式碼草圖的想法」應為「Joshua Kerievsky 建議程式碼草圖的想法」[已於第 5 次印刷中修正]

第 2 頁:第一段落中的「並識別電影類型」應寫成「並識別電影類型」。[已在第 12 次印刷中更正]

第 12 頁

有人詢問有關 double 轉 int 的捨入運算的更多資訊。當您進行複合賦值時,就會發生這種情況。換句話說

  int foo=1;
  foo += 1.5;
  

編譯通過,因為它等同於

  int foo = 1;
  foo = (int) (foo + 1.5);
  

我尚未探究其背後的原因。(請參閱 Java 語言規範,第 15.26.2 節)

(無法在重印版中修復。)

第 25 頁:圖 1.7 的標題「萃取前的順序圖...」應為「萃取後的順序圖...」[已在第 8 次印刷中更正]

第 37 頁:「Class rental」應為「class Rental」(大小寫)且「class movie」應為「class Movie」(大小寫)[在第 3 次印刷中更正]

第 40 頁:第 40 和 41 頁的程式碼範例中,對欄位 _name 的參照應改為 _title [已在第 12 次印刷中更正]

第 48 頁:第二行:「class Rental...」應為:「class Movie...」[在第 3 次印刷中更正]

第 70 頁:史提夫·麥康奈的姓氏在兩個地方拼錯。[在第 3 次印刷中更正]

第 76 頁:「重複程式碼」中的第 3 段。「在兩個類別中,然後上拉欄位 (320)」應寫成「在兩個類別中,然後上拉方法 (322)」[已在第 8 次印刷中更正]

第 82 頁:句子「如果您在 switch 中新增一個子句,您必須找到所有這些 switch、陳述式並變更它們。」應移除第二個逗號。[在第 3 次印刷中更正]

第 83 頁:在推測性概括部分的第一段的第二個句子。「喔,我想我們需要有能力做到這件事...」應讀為「喔,我想我們需要有能力做到這件事...」[已於第 15 次印刷中更正]

第 85 頁:不適當的親密關係中的「以繼承取代委派(355)」應為「以委派取代繼承(352)」[在第 3 次印刷中更正]

第 92 頁:圖 4.1 中從 TestSuite 到 Test 的線應為關聯,而非概化(請參閱下方的圖表)。此外,套件名稱應為 junit.framework。[在第 3 次印刷中更正]

第 92 頁:範例的測試檔案中,喬治·黑德利的職業生涯總計實際上為 2190 次測試。[在第 3 次印刷中更正]

第 98 頁:testReadAtEnd 方法不正確。我查看了我的原始檔,發現該方法寫成

 public
  void testReadAtEnd() throws IOException {
    int ch = -1234;
    for (int i = 0; i < 141; i++)
      ch = _input.read();
    assertEquals("read at end", -1, _input.read());
  }
  
慶幸的是,現在我可以自動插入原始碼![已於第 15 次印刷中更正]

第 115 頁:第二個句子中,「oustanding」應為「outstanding」[在第 3 次印刷中更正]

第 115 頁:在第三行,「rerun」應為「return」[已於第 15 次印刷中更正]

第 119 頁:在機制開始時,新增一個步驟:「檢查賦值的右側沒有副作用」。[已在第 24 版中更正]

第 120 頁:最後一行,「...僅指派一次...」應讀為「...僅指派一次...」[已於第 15 次印刷中更正]

第 120 頁:在解決方案陳述中,「將所有對 temp 的參照替換為表達式」這句話應替換為「將所有對 temp 的參照替換為新的方法」[已於第 15 次印刷中更正]

第 121 頁:在機制的最後一個步驟中,我說要使用以查詢取代暫存變數 (120),這應改為參照內嵌暫存變數 (119)。否則我會得到遞迴重構。第 122 頁的範例中問題持續,交叉參照應為內嵌暫存變數 (119)。這在第 8 次印刷中已錯誤修正(見下方)[已在第 8 次印刷中更正]

第 121 頁:這是對先前錯誤的錯誤修正。在機制中的最後一行,重構「以內嵌暫存變數取代暫存變數」應寫成「內嵌暫存變數」。第 122 頁也有相同的問題。[已在第 13 次印刷中更正]

第 128 頁:在動機的第一段中,表達式「for (int i=0; i<10; i++)」需要額外的括號來平衡前面的文字括號。[已於第 15 次印刷中更正]

第 148 頁

在頂部的程式碼範例中,這一行

private double  _interestRate

應該改為

private double _interestRate

因為這段程式碼已在此處移除。

第 153 頁:在第二段的第三行,「如 Lea 在部分中所討論的...」應讀為「如 Lea 部分中所討論的...」[已於第 16 次印刷中更正]

第 165 頁:倒數第二個程式碼範例不正確,應該如下所示。

class MfDateSub extends Date {
  public MfDateSub nextDay()...
  public int dayOfYear()...
[已在第 24 版中更正]

第 165 頁:在最後一個程式碼範例中,class mfDate 應該改為 class MfDateWrap [已在第 24 版中更正]

第 166 頁:在倒數第二個程式碼範例中,class mfDate 應讀為 class MfDateWrap [已於第 24 次印刷中更正]

第 166 頁

在第六個程式碼範例中,這一行

class mfDate {

應該改為

class MfDateWrap {

第 166 頁

在第五個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateSub

第 167 頁:約在三分之一處,equals 方法不正確。應讀為

        public boolean equals(Object arg) {
             if (this == arg) return true;
             if (! (arg instanceof MfDateWrap)) return false;
             MfDateWrap other = ((MfDateWrap) arg);
             return  (_original.equals(other._original));
         }
      
[已在第 24 版中更正]

第 167 頁

在第四個程式碼範例中,這一行

class MfDate…

應該改為

class MfDateWrap…

第 176 頁:在第二段(機制中的步驟)中,「變更取得方法」應讀為「變更設定方法」[已於第 15 次印刷中更正]

第 176 頁:在方法 numberOfOrdersFor 中,讀取 if (each.getCustomerName().equals(customer)) result++; 的行應讀取 if (each.getCustomer().equals(customer)) result++; [已在第 8 次印刷中更正]

第 177 頁:在方法 setCustomer 的第一個狀態中,讀取 _customer = new Customer (customer); 的行應讀取 _customer = new Customer (arg); [已在第 8 次印刷中更正]

第 185 頁:第二段落中的「雙向異或」應寫成「位元異或」[已在第 12 次印刷中更正]

第 193 頁:「宣告 interval window 實作 Observable」應為「宣告 interval window 實作 Observer」[已於第 5 次印刷中修正]

第 219 頁:「在頁面中段左右的一個段落中,句子「...需要一個回傳程式碼的新方法」應寫成「...需要一個回傳新類別實例的新方法。」[已在第 8 次印刷中更正]

第 222 頁:在頁面底部,我將 getCode 方法設為私有。顯然,當 BloodGroup 的任何用戶端正在使用該方法時,我無法這麼做。因此,句子「我也可以將這些方法設為私有...」應改為「如果沒有用戶端使用數字代碼,我也可以將這些方法設為私有...」[已於第 16 次印刷中更正]

第 222 頁:「在刪除線的程式碼中,方法 "public int getBloodGroup() {" 應為 "public int getBloodGroupCode() {"(我剛剛重新命名它!)[已在第 8 次印刷中更正]

第 225 頁:create 方法的第一次提及缺少 static 關鍵字。[已在第 13 次印刷中更正]

第 241 頁:頁面底部的程式碼範例中,方法 isEligibleForDisability 應為 isNotEligibleForDisability [在第 4 次印刷中更正]

第 258 頁

在第一個程式碼範例中,這一行

return Employee.ENGINEER;

應該為

return EmployeeType.ENGINEER;

第 261 頁:在 Ron 的故事中,第 4 段,「當然,只要您開始檢查...」應為「當然,只要您開始檢查...」[已於第 5 次印刷中修正]

第 285 頁:之前的程式碼包含一個比重構更嚴重的錯誤,因為斷言總是會執行。之前的程式碼應為

  void setValue (String name, int value) {
    if (name.equals("height")) {
      _height = value;
      return;
    }
    if (name.equals("width")) {
      _width = value;
      return;
    }
    Assert.shouldNeverReachHere();
  }
  
[已於第 8 次印刷中修正]

第 300 頁:在機制區段中,欄位應在處理結束時設為最終,而非開始時。[已於第 5 次印刷中修正]

第 301 頁

範例有問題,請參閱 移除設定方法 中的討論。

(無法在重印版中修復。)

第 307 頁:「小心 class.forName 的另一個原因是...」應為:「小心 Class.forName 的另一個原因是...」(Class 應為大寫 C)[已於第 5 次印刷中修正]

第 307 頁:「我可以使用不同的方法....」應為:「我可以使用不同的方法...」(拼字)[已於第 5 次印刷中修正]

第 311 頁:「如果例外已檢查,調整呼叫者...」應為:「如果例外檢查,調整呼叫者...」[已於第 5 次印刷中修正]

第 313 頁

這行程式碼

  Assert.isTrue("amount too large", amount > _balance); 
  

有誤,因為布林值的意義是相反的。較好的程式碼應為

  Assert.isTrue("sufficient funds", amount <= _balance);
  
[已於第 8 次印刷中修正]

第 315 頁:問題陳述應為「您在呼叫者可以先檢查的條件上引發例外」(重構適用於所有例外,不只檢查過的例外)[在第 4 次印刷中更正]

第 316 頁

在範例的第一段中,文字「當客戶想要一個資源時,資源池會將它交出…」應該改為「當客戶想要一個資源時,管理員會將它交出…」

第 324 頁

在第一個程式碼範例中,這一行

void createBill(date Date) {

應該改為

void createBill(Date date) {

第 324 頁:在頂端的程式碼範例中,程式碼行 double chargeAmount = charge (lastBillDate, date) 應為 double chargeAmount = chargeFor (lastBillDate, date)。(我讓方法名稱與圖示不一致。)[已於第 8 次印刷中修正]

第 328 頁:在動機段落中,「Pull Down Method」應為「Push Down Method」。(這就是我不為所有內容使用連結時會發生的事!)[已於第 8 次印刷中修正]

第 333 頁:「有些參數是勞動項目需要的,有些則不是」應為:「有些參數是需要的...」(遺漏字詞)[已於第 5 次印刷中修正]

第 346 頁:「每當我們看到兩個類似的函式」應為:「每當我們看到兩個類似的函式」(複數)[已於第 5 次印刷中修正]

第 346 頁:「statement 方法列印陳述式」應為:「statement 方法列印陳述式」(字型)[在第 5 次印刷中更正]

第 349 頁:第一段落應以一個閉合括號作結,以與第一行的括號相符。[已在第 15 次印刷中更正]

第 351 頁:在 UML 圖表中,客戶端與報表之間的關係應該是相依關係,而不是關聯關係。

第 355 頁:「動機」區段的第一行,「...以繼承取代委派(355)」應為「以委派取代繼承(352)」[在第 3 次印刷中更正]

第 363 頁:此頁面中對重構的參照是與章節參照交叉參照,而非通常的頁面參照。更糟的是,Extract Class 的章節應為第 7 章。[已在第 13 次印刷中更正]

第 366 頁

第一次提到圖 12.6 時,實際上應該是圖 12.5

第 390 頁:「...vivc.edu」應為「uiuc.edu」[在第 3 次印刷中更正]

第 405 頁:右下角的最後一個方塊應為「Hello World」(而非「out」)[在第 3 次印刷中更正]

第 405 頁:程式的剖析樹應將「hello」(方法名稱)改為小寫。[在第 3 次印刷中更正]

第 414 頁:URL「compuserv」中對 JUnit 的參照應為「compuserve」[在第 3 次印刷中更正]

第 92 頁圖 4.1 的更正版本。

corrected figure 4.1


非常感謝 Mike Anderson、Alex Aptekman、Beth Egan Bradtke、Greg Cohoon、George Cowan、Bruce Crawford、John Dale、Nick Dallet、Dion Dock、Jutta Eckstein、Raimar Falke、Paul Haahr、Akira Hirasawa、John Hollister、Heinz Kabutz、Bernd Kahlbrandt、Adam Kiezun、Bart Koestner、Jung-joon Kim、Mark Kinzie、Hamish Lawson、Hwijae Lee、Jaeik Lee、Marc Lepage、Ron Lusk、Chuck McKinnon、Rory Molinari、Anthon van der Neut、Jonas Nyrup、Orjan Petersson、Jon Reid、Oliver Rode、Gavin Scott、Patricia Shanahan、Pradyumn Sharma、Joel Smith、Ellen Spertus、Dawie Strauss、Frank Tip、Madhavi Tolety 和 Bill Wake、Hirohide Yazaki 發現並告訴我這些錯誤