类 的组合或继承具有几乎相似的实现但方法的输入和输出不同?

Composition or Inheritance for classes with almost similar implementations but different input and outputs for methods?

我有以下 classes,它们具有非常相似的方法实现。只有 classes 的方法输入和输出似乎是不同类型的。当我这样说时,听起来像是继承的情况,但是,输入和输出不同并且与两个 lambda 相关的事实让我想知道它们是否应该保持没有任何关系,因为不能认为一个 lambda代替另一个(成为继承的案例)。

我的第一个 class 如下所示。

public class JobPersistenceManager {
    private String jobIndexName;
    private JobLambda JobLambda;
    private MyDataPersistence myDataPersistence;
    private DataProcessorUtils dataProcessorUtils;
    private static final String JOB_ID = "jobId";
    private static final String JOB_NAME = "jobName";

    @Inject
    public JobPersistenceManager(@Named("jobIndexName") String jobIndexName,
                                 JobLambda JobLambda,
                                 MyDataPersistence myDataPersistence) {
        this.jobIndexName = jobIndexName;
        this.JobLambda = JobLambda;
        this.myDataPersistence = myDataPersistence;
        createIndexIfNotExists(this.jobIndexName);
    }

    public SearchDocumentResult searchJob(MyJobInput myJobInput) throws IOException {
        return myDataPersistence
                .searchDocument(this.jobIndexName,
                        dataProcessorUtils.transformObjectDataPayloadToMap(myJobInput));
    }

    public MyJobOutput invokeCreateJobLambdaAndIndexData(final MyJobInput myJobInput)
            throws IOException {
        String personRequestPayload = dataProcessorUtils.transformObjectDataInputJson(myJobInput);
        Map<String, String> createdJobOutput = this.JobLambda.invokeLambda(personRequestPayload);
        this.indexCreatedJob(myJobInput, createdPersonOutput);
        return MyJobOutput.builder().withJobID(createdJobOutput.get(JOB_ID))
                .withJobName(createdJobOutput.get(JOB_NAME)).build();
    }

    public int indexCreatedJob(final MyJobInput myJobInput,
                               final Map<String, String> createdJobOutput) throws IOException {
        myJobInput = modifyJobInput(myJobInput);
        String documentToIndex = dataProcessorUtils.transformObjectDataInputJson(myJobInput);
        return myDataPersistence.indexDocument(this.jobIndexName, documentToIndex);
    }

    private void createIndexIfNotExists(final String indexName) {
        if (!myDataPersistence.doesIndexExist(indexName)) {
            myDataPersistence.createIndex(CreateIndexInput.builder().indexName(indexName).build());
        }
    }
}

我的第二个 class 如下所示。

public class EmployeePersistenceManager {
    private EmployeeLambda employeeLambda;
    private MyTestDataPersistence myTestDataPersistence;
    private DataProcessorUtils dataProcessorUtils;
    private String employeeIndexName;
    private static final String PERSON_ID_KEY = "personId";
    private static final String PERSON_NAME_KEY = "personName";

    @Inject
    public EmployeePersistenceManager(@Named("employeeIndexName") String employeeIndexName,
                                    EmployeeLambda employeeLambda,
                                    MyTestDataPersistence myTestDataPersistence,
                                    DataProcessorUtils dataProcessorUtils) {
        this.employeeIndexName = employeeIndexName;
        this.employeeLambda = employeeLambda;
        this.myTestDataPersistence = myTestDataPersistence;
        this.dataProcessorUtils = dataProcessorUtils;
        createIndexIfNotExists(employeeIndexName);
    }

    public SearchDocumentResult searchPerson(EmployeeInput employeeInput) throws IOException {
        return myTestDataPersistence
                .searchDocument(employeeIndexName,
                        dataProcessorUtils.transformObjectDataPayloadToMap(employeeInput));
    }

    public EmployeeOutput invokeCreatePersonLambdaAndIndexData(final EmployeeInput employeeInput)
            throws IOException {
        String personRequestPayload = dataProcessorUtils.transformObjectDataInputJson(employeeInput);
        Map<String, String> createdPersonOutput = this.employeeLambda.invokeLambda(personRequestPayload);
        this.indexCreatedEmployee(employeeInput, createdPersonOutput);
        return EmployeeOutput.builder().withPersonId(createdPersonOutput.get(PERSON_ID_KEY))
                .withPersonName(createdPersonOutput.get(PERSON_NAME_KEY)).build();
    }

    public int indexCreatedEmployee(final EmployeeInput employeeInput,
                                  final Map<String, String> createdPersonOutput) throws IOException {
        employeeInput = modifyEmployeeInput(employeeInput);
        String documentToIndex = dataProcessorUtils.transformObjectDataInputJson(employeeInput);
        return myTestDataPersistence.indexDocument(this.employeeIndexName, documentToIndex);
    }

    public Map.Entry<String, Map<String, String>> invokeLambda(final String payload) {
        return new AbstractMap.SimpleEntry<>(payload, this.employeeLambda.invokeLambda(payload));
    }

    private void createIndexIfNotExists(final String indexName) {
        if (!myTestDataPersistence.doesIndexExist(indexName)) {
            myTestDataPersistence.createIndex(CreateIndexInput.builder().indexName(indexName).build());
        }
    }
}

如您所见,这些方法执行几乎相同的操作。只有 classes 中的 indexCreatedEmployeeindexCreatedJob 方法有处理输入的额外步骤。

我应该保持这些 class 之间没有任何关系,还是应该创建一个抽象持久性管理器 class 并执行以下操作。

createIndexIfNotExists移动到摘要class 创建抽象方法 search()invokeLambda()indexCreatedData() 方法并在每个 child class 中实现它们。数据类型 MyJobInputMyEmployeeInput 是没有任何关系的 POJO classes。所以我想我提到的这些方法会采用“Object”参数吗? EmployeeLambdaJobLambda 又是 class,它们之间没有任何关系。我对创建某种继承的另一个担忧是,不能使用 Employee Lambda 和 JobLambda inter-changeably。所以想知道他们是否应该继承相同的 parent class 只是因为他们都是 lambda classes.

或者还有其他方法可以解决这个问题吗?任何建议将不胜感激。非常感谢您。

按照昨天的承诺,这就是我要做的。

创建一个Lambda接口并让JobLambdaEmployeeLambda实现它

public interface Lambda {

    Map<String, String> invokeLambda(String payload);

}

public class JobLambda implements Lambda {
    //... your implementation
}

public class EmployeeLambda implements Lambda {
    //... your implementation   
}

DataPersistence

做同样的事情
public interface DataPersistence {

    boolean doesIndexExist(String indexName);

    void createIndex(CreateIndexInput createIndexInput);

    int indexDocument(String indexName, String documentToIndex);

    SearchDocumentResult searchDocument(String indexName, Map<String, String> payloadMap);

}

public class MyDataPersistence implements DataPersistence {
    //... your implementation
}

public class MyTestDataPersistence implements DataPersistence {
    //... your implementation
}

然后创建一个包含所有重复方法的父 class PersistenceManager,参数化为 input/output 的类型:

(注意:我没有完成所有内容,但我做了一些只是为了让你理解这个概念)

public class PersistenceManager<I, O> {
    protected static final String ID = "Id";
    protected static final String NAME = "Name";
    private String indexName;
    private Lambda lambda;
    private DataPersistence dataPersistence;
    private DataProcessorUtils dataProcessorUtils;

    public PersistenceManager(String indexName, Lambda lambda, DataPersistence dataPersistence, DataProcessorUtils dataProcessorUtils) {
        this.indexName = indexName;
        this.lambda = lambda;
        this.dataPersistence = dataPersistence;
        this.dataProcessorUtils = dataProcessorUtils;
        createIndexIfNotExists(indexName);
    }

    public SearchDocumentResult search(I input) {
        return dataPersistence.searchDocument(indexName, dataProcessorUtils.transformObjectDataPayloadToMap(input));
    }

    public O invokeCreateLambdaAndIndexData(final I input) {
        String requestPayload = dataProcessorUtils.transformObjectDataInputJson(input);
        Map<String, String> createdOutput = this.lambda.invokeLambda(requestPayload);
        //continue generalizing following the same logic
    }

    public int indexCreated(I input, Map<String, String> createdOutput) {
        //continue generalizing following the same logic
    }

    private void createIndexIfNotExists(final String indexName) {
        if (!dataPersistence.doesIndexExist(indexName)) {
            dataPersistence.createIndex(CreateIndexInput.builder().indexName(indexName).build());
        }
    }
}

此时,您可以通过简单地选择参数

来专门化您的 classes

...所有其余代码将在父 class.

中共享
public class JobPersistenceManager extends PersistenceManager<MyJobInput, MyJobOutput> {

    private static final String JOB_ID = "Job" + ID;
    private static final String JOB_NAME = "Job" + NAME;

    public JobPersistenceManager(String indexName, Lambda lambda, DataPersistence dataPersistence, DataProcessorUtils dataProcessorUtils) {
        super(indexName, lambda, dataPersistence, dataProcessorUtils);
    }
}

public class EmployeePersistenceManager extends PersistenceManager<MyEmployeeInput, MyEmployeeOutput> {

    private static final String EMPLOYEE_ID = "Employee" + ID;
    private static final String EMPLOYEE_NAME = "Employee" + NAME;

    public EmployeePersistenceManager(String indexName, Lambda lambda, DataPersistence dataPersistence, DataProcessorUtils dataProcessorUtils) {
        super(indexName, lambda, dataPersistence, dataProcessorUtils);
    }
}

... 并像这样使用它们:

PersistenceManager employeePersistenceManager = new EmployeePersistenceManager(...);
employeePersistenceManager.search(employeeInput); //<-- the code is in the base class