2014-01-05 27 views
1

刪除常見的代碼我有類似的模式類似下面的函數類近10種功能從功能

SQLiteDatabase database = this.getWritableDatabase(); 

    try { 
      //Some different code , all other code(try,catch,finally) is same in all functions 
    } catch (SQLiteException e) { 
     Log.e(this.getClass().getName(), e.getMessage()); 
     return false; 
    } finally { 
     database.close(); 
    } 

} 

我想從所有功能(呵,catch,終於)去除常見的代碼,並將其移動到單身的地方 我該如何做到這一點?

+2

你寫了一個輔助方法。 – Maroun

+0

如果'try'中的代碼不同,那麼您將無法有效地重構它。更好的模式是將所有的數據庫交互放到一個單獨的類/方法集中,所以你幾乎不需要看它。 –

+1

@ChrisHayes:它可以使用接口(使用單一方法)重構,然後傳遞給輔助方法。 –

回答

3

有許多框架可以大大簡化您可以使用的數據庫交互,但是如果您想自己做事情,並且對使用Java方式執行此類操作感興趣,可以這樣做:

讓你的 「執行者」,例如:

public class Executor { 
    public static void runOperation(Operation operation) { 
    SQLiteDatabase database = this.getWritableDatabase(); 
    try { 
     operation.run(database); 
    } catch (SQLiteException e) { 
     Log.e(operation.getClass().getName(), e.getMessage()); 
     return false; 
    } finally { 
     database.close(); 
    } 
} 

現在你們每個人都想做的事情將是操作的10件事情:

public interface Operation { 
    void run(SQLiteDatabase database) throws SQLiteException; 
} 

這裏什麼特定的操作看起來像:

Operation increaseSalary = new Operation() { 
    public void run(SQLiteDatabase database) throws SQLiteException { 
    // .... write the new increased salary to the database 
    } 
}; 

而且你運行它:

. 
. 
Executor.runOperation(increaseSalary); 
. 
. 

您還可以使接口的匿名內部類的實現,但可以讓它少一點可讀。

. 
. 
Executor.runOperation(new Operation() { 
    public void run(SQLiteDatabase database) throws SQLiteException { 
    // put the increase salary database-code in here 
    } 
}); 
. 
. 

您可以查看經典設計模式列表,找出這是哪一個。

+1

我認爲你應該把'Operation.run(數據庫);'在'try'塊內......是不是這個意圖? – ADTC

+1

並且還聲明'拋出SQLiteException'。 – ADTC

+1

正確的你是兩個重要的,謝謝。修復了答案。 –

1

要進一步擴展Ray Toal's original answer,值得注意的是,使用匿名內部類將有助於避免爲每個操作創建單獨的類文件。所以具有10個左右函數的原始類可以保持相同的方式,除了被重構爲使用Executor模式。

此外,當使用Executor模式時,您必須注意在原始代碼中使用this。假設原來的功能如下:

public boolean operation1() { 
    SQLiteDatabase database = this.getWritableDatabase(); 

    try { 
     //Code for Operation 1 
     return true; 
    } catch (SQLiteException e) { 
     Log.e(this.getClass().getName(), e.getMessage()); 
     return false; 
    } finally { 
     database.close(); 
    } 

} 

public boolean operation2() { 
    SQLiteDatabase database = this.getWritableDatabase(); 

    try { 
     //Code for Operation 2 
     return true; 
    } catch (SQLiteException e) { 
     Log.e(this.getClass().getName(), e.getMessage()); 
     return false; 
    } finally { 
     database.close(); 
    } 

} 

隨着定義爲Executor類如下:

public class Executor { 
    public static boolean runOperation(SQLiteOpenHelper helper, Operation operation) { 
    SQLiteDatabase database = helper.getWritableDatabase(); 
    try { 
     operation.run(database); 
     return true; 
    } catch (SQLiteException e) { 
     Log.e(helper.getClass().getName(), e.getMessage()); 
     return false; 
    } finally { 
     database.close(); 
    } 
    } 
} 

並將其定義爲Operation界面如下:

public interface Operation { 
    public void run(SQLiteDatabase database) throws SQLiteException; 
} 

原來的功能現在重寫如下:

public boolean operation1() { 
    return Executor.runOperation(this, new Operation() { 
     public void run(SQLiteDatabase database) throws SQLiteException { 
     //Code for Operation 1 
     } 
    }); 
} 

public boolean operation2() { 
    return Executor.runOperation(this, new Operation() { 
     public void run(SQLiteDatabase database) throws SQLiteException { 
     //Code for Operation 2 
     } 
    }); 
} 

此擴展還糾正了Ray在其原始答案中忽略的錯誤。