2015-06-18 28 views
7

我有一個對象,它有幾個數組作爲字段。這是類大致是這樣的:獲得類似對象屬性的通用方法

public class Helper { 
    InsuranceInvoices[] insuranceInvoices; 
    InsuranceCollectiveInvoices[] insuranceCollectiveInvoices 
    BankInvoices[] bankInvoices; 
    BankCollectiveInvoices[] bankCollectiveInvoices; 
} 

所有發票類型都有一個共同的標記接口發票
我需要獲得所有的發票來調用其他方法。

Helper helperObject = new Helper(); 
// ... 

for (InsuranceInvoices invoice : helperObject.getInsuranceInvoices()) { 
    Integer customerId = invoice.getCustomerId(); 
    // ... 
} 
for (BankInvoices invoice : helperObject.getBankInvoices()) { 
    Integer customerId = invoice.getCustomerId(); 
    // ... 
} 

// repeat with all array fields 

問題是,所有的發票只有標記接口的共同點。方法getCustomerID()未由交互接口或類定義。這是一個由於給定的規範而不能改變的行爲。

for-each-loop內部的代碼重複是錯誤的。我必須在四個不同的數組中的所有發票對象上做同樣的事情。因此四個for-each-loops不必要地膨脹了代碼。

有沒有一種方法可以編寫一般(私有)方法?一個想法是:

private void generalMethod(Invoice[] invoiceArray){ 
    // ... 
} 

但是這將需要四個instanceof檢查,因爲該類發票不知道方法getCusomterId()。所以我什麼也得不到。該方法仍然包含重複。

我很感謝所有可能的解決方案來推廣這個問題!

+1

這樣,所有類實現'Invoice',並都實現'getCustomerId',但' getCustomerId'不在'Invoice'界面中?您必須使用反射才能按名稱訪問方法並調用它。此時,「發票」界面是無用的。 – njzk2

+0

是否getInsuranceInvoices','getBankInvoices' ...所有四個返回相同數量的發票? – Rajesh

+3

我有一個建議...將一個線索應用到使'發票'接口成爲標記接口的人而不是一個指定發票具有共同點的方法的人。 – Powerlord

回答

7

可能的解決方案來概括問題(從最責令最差):

使用包裝類

public class InvoiceWrapper { 
    private String customerID; 
    public String getCustomerID() { 
     return customerID; 
    } 
    public InvoiceWrapper(BankInvoices invoice) { 
     this.customerID = invoice.getCustomerID(); 
    } 
    public InvoiceWrapper(InsuranceInvoices invoice) { 
     this.customerID = invoice.getCustomerID(); 
    } 
    // other constructors 
} 

UPD如果我理解正確的,你需要做一些事情所有陣列中的ID。要使用InvoiceWrapper,還需要在Helper類中實現迭代器,這將遍歷數組並返回每個條目的包裝器。所以,你將擁有可以與4個數組一起工作的代碼。

使用強制轉換

public class CustomerIdHelper { 
    public static String getID(Invoice invoice) { 
     if (invoice instanceof InsuranceInvoices) { 
      return ((InsuranceInvoices) invoices).getCustomerID(); 
     } else if ... 
    } 
} 

通過反射調用的方法命名實例

public class CustomerIdHelper { 
    public static String getID(Invoice invoice) { 
     Method method = invoice.getClass().getDeclaredMethod("getCustomerId"); 
     return (String) method.invoke(invoice); 
    } 
} 
+0

謝謝你的建議!第一種方法是我沒有考慮到的。 但是,你能否向我解釋爲什麼你選擇Reflection方法是三者中最糟糕的? – DeMo

+1

@DeMo這是因爲如果有人刪除方法,你不會注意到它。在前兩個變體中,您將看到編譯錯誤。 – AdamSkywalker

2

它不漂亮,但你可以使用反射來查找getCustomerIdMethod然後invoke()它,比照Class.getDeclaredMethod()

private void generalMethod(Invoice[] invoiceArray){ 
    try { 
    for (Invoice invoice : invoiceArray) { 
     Method getCustomerId = invoice.getClass().getDeclaredMethod("getCustomerId"); 
     getCustomerId.invoke(invoice); 
    } 
    } catch (Exception e) { 
    // ... 
    } 
} 

請注意,這是未經測試。

2

如果您不允許通過向其添加自定義界面來更改正在處理的類。你可以做的最好的事情是用自定義的類來包裝它們,它具有所需的屬性。

這樣你將有一個類的所有'不那麼好'的代碼,將你不能觸及的類轉換成匹配適當和有用設計的漂亮類。

例如,您可以擁有延伸WrappedInsurace幷包含成員字段InsuranceInvoice的類WrappedInsuranceInvoice。如果你不需要保留原來的課程,那麼複製數據會更好。這樣你可以丟失數組並使用列表來代替。

相關問題