簡體   English   中英

如何將 setter 方法傳遞給 Java 中方法的參數?

[英]How to pass a setter method to the argument to a method in Java?

關於重構方法以及如何在 Java 中將 setter 方法作為方法傳遞的快速問題。

我曾經有一個越來越大的遺留方法,遺留方法實際上只是更新客戶ID,我們通過什么方式(電子郵件,電話,傳真,推特等...)聯系了客戶,例如:

 final Map<Integer, Customer> customerID_and_customer_Map = getCustomerIDandCustomerContactedByXXXMap();

        for (final Integer customerId : getListOfCustomersContactedByTelephone()) {
            if (customerID_and_customer_Map.containsKey(customerId)) {
                final Customer customer = customerID_and_customer_Map.get(customerId);
                customer.setCustomerContactedByTelephone(true);
                customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
                customerID_and_customer_Map.put(customerId, customer);
            }
        }
        for (final Integer customerId : getListOfCustomersContactedByTwitter()) {
            if (customerID_and_customer_Map.containsKey(customerId)) {
                final Customer customer = customerID_and_customer_Map.get(customerId);
                customer.setPartnerContactedByTwitter(true);
                customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
                customerID_and_customer_Map.put(customerId, customer);
            }
        }

隨着時間的推移,我們只是為合作伙伴的每種新聯系方式添加 for 循環。 這個方法從兩個 for 循環開始,現在有大約 50 次。

final Map<Integer, Customer> customerID_and_customer_Map = getCustomerIDandCustomerContactedByXXXMap();
        for (final Integer customerId : getListOfCustomersContactedByTelephone()) {
            if (customerID_and_customer_Map.containsKey(customerId)) {
                final Customer customer = customerID_and_customer_Map.get(customerId);
                customer.setCustomerContactedByTelephone(true);
                customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
                customerID_and_customer_Map.put(customerId, customer);
            }
        }
        for (final Integer customerId : getListOfCustomersContactedByTwitter()) {
            if (customerID_and_customer_Map.containsKey(customerId)) {
                final Customer customer = customerID_and_customer_Map.get(customerId);
                customer.setPartnerContactedByTwitter(true);
                customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
                customerID_and_customer_Map.put(customerId, customer);
            }
        }
        for (final Integer customerId : getListOfCustomersContactedByEmail()) {
            if (customerID_and_customer_Map.containsKey(customerId)) {
                final Customer customer = customerID_and_customer_Map.get(customerId);
                customer.setPartnerContactedByEmail(true);
                customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
                customerID_and_customer_Map.put(customerId, customer);
            }
        }
//and lot more for loops for other ways, like fax, LinkedIn, pager, advertisement, etc etc etc

到今天為止,這個方法現在已經有一頁了!

我想重構這個塊,使代碼更干凈,並想出了這個。

    private static void magicMethod(Map<Integer, Customer> map, List<Integer> customersContactedByXXX) {
        for (final Integer customerId : customersContactedByXXX) {
            if (map.containsKey(customerId)) {
                final Customer customer = map.get(customerId);
//                customer.setPartnerContactedByXXX(true); <---- How to do this part?
                customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
                map.put(customerId, customer);
            }
        }
    }

但是,for 循環中的 setter 是有問題的部分。

如何以最有效的方式做到這一點? 或者也許有一種方法可以將 setter 作為方法的參數傳遞?

我知道首先應該有更好的方法來完成整個事情。 我的目標實際上是詢問如何將所有 for 循環重構為一個 for 循環。 請不要重構整個事情。

非常感謝您的幫助。

在 Java 8 中,也許是這樣的?

magicMethod(getCustomerIDandCustomerContactedByXXXMap(),  getListOfCustomersContactedByTwitter(), MyClass::contactedCustomerByTwitter);

private static void magicMethod(Map<Integer, Customer> map, List<Integer> customersContactedByXXX, Consumer<Customer> contactedConsumer) {
    for (final Integer customerId : customersContactedByXXX) {
        if (map.containsKey(customerId)) {
            final Customer customer = map.get(customerId);
            contactedConsumer.accept(customer);
            customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
            map.put(customerId, customer);
        }
    }
}

private static void contactedCustomerByTwitter(Customer customer) {
   customer.setPartnerContactedByTwitter(true);
}

在每個循環中,有一對方法是不同的:

for (final Integer customerId : getListOfCustomersContactedByTelephone()) {
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    if (customerID_and_customer_Map.containsKey(customerId)) {
        final Customer customer = customerID_and_customer_Map.get(customerId);
        customer.setCustomerContactedByTelephone(true);
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
        customerID_and_customer_Map.put(customerId, customer);
    }
}

所以你可以把這些“對”放在兩個列表中:

List<Supplier<List<Customer>>> customerListSuppliers = List.of(
   YourClass::getListOfCustomersContactedByTwitter,
   YourClass::getListOfCustomersContactedByTelephone,
   YourClass::getListOfCustomersContactedByEmail,
   ...
)

List<BiConsumer<Customer, Boolean>> customerSetters = List.of(
   Customer::setPartnerContactedByTwitter,
   Customer::setPartnerContactedByTelephone,
   Customer::setPartnerContactedByEmail,
   ...
)

如果您不使用 Java 9+,只需add這些方法引用add到兩個常規ArrayList

然后,循環遍歷兩個列表!

for (int i = 0 ; i < customerListSuppliers.size() ; i ++) {
    Supplier<List<Customer>> customerListSupplier = customerListSuppliers.get(i);
    BiConsumer<Customer, Boolean> customerSetter = customerSetters.get(i);
    for (final Integer customerId : customerListSupplier.get()) {
        if (customerID_and_customer_Map.containsKey(customerId)) {
            final Customer customer = customerID_and_customer_Map.get(customerId);
            customerSetter.accept(customer, true);
            customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
            customerID_and_customer_Map.put(customerId, customer);
        }
    }
}

其他幾點:

  • 我不認為你需要把客戶放回地圖。
  • 如果參數為true ,請考慮在setPartnerContactedByXXX自動將CustomerHasBeenContactedAtLeastBySomethingOnce設置為true
  • 考慮制作一個包含所有這些聯系方法的ContactMethod枚舉。 並使這些方法接受一個ContactMethod ,而不是每個聯系方法都有一個方法。

作為第一步,您可以將每個 for 循環移動到一個方法,例如

private updateCustomersContactedByTelephone() {
for (final Integer customerId : getListOfCustomersContactedByTelephone()) {
            if (customerID_and_customer_Map.containsKey(customerId)) {
                final Customer customer = customerID_and_customer_Map.get(customerId);
                customer.setCustomerContactedByTelephone(true);
                customer.setCustomerHasBeenContactedAtLeastBySomethingOnce(true);
                customerID_and_customer_Map.put(customerId, customer);
            }
        }
}

然后改為調用該方法。 然后尋找“類似的”更新並再次將它們組合在一個方法中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM