[英]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.