Как избежать дублирования кода с двумя классами, имеющими одинаковые методы, но без общего интерфейса - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть много мест в моем коде, где у меня есть метод, который идентичен другому, за исключением того, что используемые ими объекты отличаются, как в примере ниже:

private void applyContractualFields(){
 PaymentChangeMaintenanceFieldsV214Type recentPcmFieldType = getData();

 if (recentPcmFieldType != null) {
    paymentChangeMaintenance.setContractualFieldsApplied(true);
    if (recentPcmFieldType.getAnnualInterestRate() != null) {
        paymentChangeMaintenance.setContractualInterestRate(
                recentPcmFieldType.getAnnualInterestRate());
    }
    if (recentPcmFieldType.getPIAmount() != null) {
        paymentChangeMaintenance
                .setContractualPIAmount(recentPcmFieldType.getPIAmount());
    }
    paymentChangeMaintenance.setCountyTax(recentPcmFieldType.getCountyTaxAmount());
 }
}

private void applyPaymentDataFromPcmFields() {
 PaymentChangeMaintenanceCommonFieldsV214Type recentPcmFieldType = getData();

 if (recentPcmFieldType != null) {
    paymentChangeMaintenance.setContractualFieldsApplied(true);
    if (recentPcmFieldType.getAnnualInterestRate() != null) {
        paymentChangeMaintenance.setContractualInterestRate(
                recentPcmFieldType.getAnnualInterestRate());
    }
    if (recentPcmFieldType.getPIAmount() != null) {
        paymentChangeMaintenance
                .setContractualPIAmount(recentPcmFieldType.getPIAmount());
    }
    paymentChangeMaintenance.setCountyTax(recentPcmFieldType.getCountyTaxAmount(
 ));
 }
}

Есть ли способ объединить эти два с помощью обобщений?Кроме того, PaymentChangeMaintenanceFieldsV214Type и PaymentChangeMaintenanceCommonFieldsV214Type являются автоматически сгенерированными классами из файла wsdl.

enter image description here

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Вы можете создать класс Wrapper, который может принимать PaymentChangeMaintenanceFieldsV214Type или PaymentChangeMaintenanceCommonFieldsV214Type (или A и B в тестовом коде здесь) и делегировать ваши вызовы базовым объектам.Каждый раз, когда вы получаете экземпляр A или B, вы создаете экземпляр Wrapper и используете его.Таким образом, дублирование кода ограничено: Wrapper:

import java.util.Random;

public class Main {

    private final Random rand = new Random();

    public static void main(final String[] args) {
        new Main().test();
    }

    void test(){
        for (int i = 0; i < 10 ; i++){
            Object obj = getData();          //obj can be either A or B
            Wrapper w = new Wrapper(obj);    //construct a Wrapper 
            System.out.println(w.getName()); //use it 
        }
    }

    Object getData(){  //generate objects for testing 
        return rand.nextBoolean() ? new A() : new B(); // returns A half the times
    }
}

class Wrapper {

    Object obj;
    Wrapper(Object obj){ //throw an exception if obj is not an A or B 
        this.obj = obj;
    }

    String getName(){
        return obj instanceof A ? ((A)obj).getName() : ((B)obj).getName() ;
    }
}

//two classes implementing the same method without having a common interface 
class A {

    String getName() { return getClass().getSimpleName(); }
}

class B {

    String getName() { return getClass().getSimpleName(); }
}

Создав подходящую оболочку, вы можете заставить свой метод принимать оба типа, изменив одну строку:

 MyWrapper recentPcmFieldType = new MyWrapper(getData());
0 голосов
/ 21 декабря 2018

Единственный способ, которым я вижу, - это использовать отражение.Вот пример, который должен работать в соответствии с переданным объектом.Однако вы должны обработать исключения, и было бы неплохо проверить, к какому классу относится передаваемый объект.

private <T> void applyContractualFields(T t) { 
    try {
        Class<?> c = t.getClass();
        Method getPIAmount = c.getDeclaredMethod("getPIAmount");
        Integer piAmount = (Integer) getPIAmount.invoke(t);
        if (piAmount != null) {
             paymentChangeMaintenance.setContractualPIAmount(piAmount);
        }

        /* the rest ... */

    } catch(Exception e) {
        e.printStackTrace();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...