8

フィールドとしていくつかの配列を持つオブジェクトがあります。クラスはおおよそ次のようになります。

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

すべての請求書タイプには、相互マーカー インターフェイスInvoicesがあります。
請求書に対して別のメソッドを呼び出すには、すべての請求書を取得する必要があります。

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 内のコードの繰り返しは、私を悩ませているものです。4 つの異なる配列内のすべての請求書オブジェクトに対してまったく同じことを行う必要があります。したがって、4 つの for-each ループがコードを不必要に肥大化させます。

一般的な (プライベート) メソッドを作成する方法はありますか? 1つのアイデアは次のとおりです。

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

しかし、クラスInvoiceはメソッドgetCusomterId()を認識していないため、これには 4 つの instanceof チェックが必要になります。したがって、私は何も得られません。メソッドにはまだ繰り返しが含まれます。

この問題を一般化するためのあらゆる可能な解決策に感謝します!

4

3 に答える 3

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 を使用するには、ヘルパー クラスにイテレータを実装する必要もあります。これは、配列をウォークスルーし、各エントリのラッパーを返します。したがって、とにかく 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);
    }
}
于 2015-06-18T14:05:03.510 に答える