重构代码的好方法

时间:2017-12-04 16:18:26

标签: java spring hibernate spring-mvc spring-boot

我有几个DTO对象。

public class MovieRequest {}
public class OtherTitle extends MovieRequest {}
public class ReleaseDate extends MovieRequest {}

使用通用贡献(DTO对象)上载这些对象 public class ContributionNew<T extends MovieRequest> {}方法

void createOtherTitleContribution(
        final ContributionNew<OtherTitle> contribution,
        ...
);
void updateOtherTitleContribution(
        final ContributionUpdate<OtherTitle> contribution,
        ...
);
 void createReleaseDateContribution(
        final ContributionNew<ReleaseDate> contribution,
        ...
);
void updateReleaseDateContribution(
        final ContributionUpdate<ReleaseDate> contribution,
        ...
);

电影的信息更多,这些方法将重复约30次f。即createBoxOfficeContribution e.t.c 例如,更新贡献的方法如下所示

@Override
public void updateOtherTitleContribution(
        ContributionUpdate<OtherTitle> contribution,
        Long contributionId,
        Long userId
) throws ResourceNotFoundException {
    log.info("Called with contribution {}, contributionId {}, userId {}",
            contribution, contributionId, userId);

    final UserEntity user = this.findUser(userId);
    final ContributionEntity contributionEntity = this.findContribution(contributionId, EditStatus.WAITING, user, MovieField.OTHER_TITLE);

    this.validIds(contributionEntity.getIdsToAdd(), contribution.getElementsToAdd().keySet());
    this.validIds(contributionEntity.getIdsToUpdate().keySet(), contribution.getElementsToUpdate().keySet());
    this.validIds(contributionEntity.getIdsToDelete(), contribution.getIdsToDelete());

    this.cleanUpIdsToAdd(contributionEntity.getIdsToAdd(), contribution.getElementsToAdd().keySet(), contributionEntity.getMovie().getOtherTitles());
    this.cleanUpIdsToUpdate(contributionEntity.getIdsToUpdate(), contribution.getElementsToUpdate().keySet());
    this.cleanUpIdsToDelete(contributionEntity.getIdsToDelete(), contribution.getIdsToDelete());

    contribution.getElementsToAdd().forEach((key, value) -> {
        this.moviePersistenceService.updateOtherTitle(value, key, contributionEntity.getMovie());
    });
    contribution.getElementsToUpdate().forEach((key, value) -> {
        this.moviePersistenceService.updateOtherTitle(value, key, contributionEntity.getMovie());
    });
    contribution.getNewElementsToAdd()
            .forEach(otherTitle -> {
                final Long id = this.moviePersistenceService.createOtherTitle(otherTitle, contributionEntity.getMovie(), user);
                contributionEntity.getIdsToAdd().add(id);
            });

    contributionEntity.setSources(contribution.getSources());
    Optional.ofNullable(contribution.getComment()).ifPresent(contributionEntity::setUserComment);
}

如您所见,这些方法的唯一区别是调用方法

this.moviePersistenceService.updateOtherTitle(...)

方法updateReleaseDateContribution调用

this.moviePersistenceService.updateReleaseDate(...)

正如你所看到的差别只有几行,而旧方式当前代码将有几千行。您对通用通用方法有什么想法吗?怎么做得更好?

1 个答案:

答案 0 :(得分:0)

  • 您可以创建一个方法moviePersistenceService.update(MovieRequest req),在执行持久性部分之前检查req的类型。

  • 您还可以将函数(将执行持久性部分的函数)作为参数传递给updateOtherTitleContribution(选中How to pass a function as a parameter in Java?