Как сделать рефакторинг этого дублированного фрагмента кода оператора switch - PullRequest
0 голосов
/ 08 ноября 2019

Я кодирую какое-то приложение CRUD, страницу, показывающую данные из таблицы базы данных, и она должна соединиться с двумя очень похожими таблицами (эти две очень похожие таблицы не могут быть оптимизированы для одной таблицы по причине истории или слишком дорогого времени). Я оптимизирован с оператором switch и функциями Java 8, но Intellij IDEA выдает мне предупреждение о фрагменте дублированного кода между двумя операторами переключателя, что я не знаю, как это исправить.

Я НЕ прошу оптимизировать проектирование, но реорганизовать фрагмент дублированного кода и исправить это предупреждение.

У меня есть метод search для поиска данных из баз данных , и использования отдельной логики из другой таблицыTaxCustomerType enum:

    public PageUtils<IndividualTaxActorVO> search(TaxCustomerType type, IndividualTaxActorQuery query, UserDO principal) {
        //... ignore for conciseness
        Function<ActorCondition, Integer> counter;
        Function<ActorCondition, Collection<IndividualTaxActorVO>> searcher;
        switch (type) {
            case INDIVIDUAL: {
                counter = individualTaxActorDao::countIndividual;
                searcher = individualTaxActorDao::searchIndividual;
                break;
            }
            case CORPORATE: {
                counter = individualTaxActorDao::countCorporate;
                searcher = individualTaxActorDao::searchCorporate;
                break;
            }
            default:
                throw new RuntimeException("不能识别的个税客户类型:" + type);
        }
        int total = counter.apply(condition);
        if (total == 0) {
            return PageUtils.empty();
        }
        Collection<IndividualTaxActorVO> list = searcher.apply(condition);
        return new PageUtils<>(list, total);
    }

Также у меня есть метод link для вставки в таблицу и выполнения некоторых проверок, также используйте отдельную логику с помощью TaxCustomerType enum:

    public void link(TaxCustomerType type, String customerId, UserDO principal) {
        Function<String,IdAndTaxCodeAndDisabledOnly> findById;
        BiFunction<String,String,Integer> existsCounter;
        switch (type){
            case INDIVIDUAL: {
                findById = individualCustomerService::findTaxCodeAndDisabledById;
                existsCounter = individualTaxActorDao::countCorporateByCompanyIdAndTaxCode;
                break;
            }
            case CORPORATE: {
                findById = customerService::findTaxCodeAndDisabledById;
                existsCounter = individualTaxActorDao::countIndividualByCompanyIdAndTaxCode;
                break;
            }
            default:
                throw new RuntimeException("不能识别的个税客户类型:" + type);
        }
        IdAndTaxCodeAndDisabledOnly customer = findById.apply(customerId);
        if (customer == null) {
            throw new ApplicationRuntimeException(HttpStatus.NOT_FOUND, "客户不存在");
        }
        if(customer.isDisabled()){
            throw new ApplicationRuntimeException(HttpStatus.FAILED_DEPENDENCY,"客户已禁用");
        }
        int exists=existsCounter.apply(principal.getCompanyid(),customerId);
        if(exists>0){
            throw new ApplicationRuntimeException(HttpStatus.CONFLICT,"已是智能个税客户,不可重复添加。");
        }
        // insert into table ... ignore for conciseness
    }

Абсолютные строки фрагмента дублированного кода:

в search методе:

        switch (type) {
            case INDIVIDUAL: {
                counter = individualTaxActorDao::countIndividual;
                searcher = individualTaxActorDao::searchIndividual;
                break;
            }
            case CORPORATE: {
                counter = individualTaxActorDao::countCorporate;
                searcher = individualTaxActorDao::searchCorporate;
                break;
            }
            default:
                throw new RuntimeException("不能识别的个税客户类型:" + type);
        }

и в link методе:

        switch (type){
            case INDIVIDUAL: {
                findById = individualCustomerService::findTaxCodeAndDisabledById;
                existsCounter = individualTaxActorDao::countCorporateByCompanyIdAndTaxCode;
                break;
            }
            case CORPORATE: {
                findById = customerService::findTaxCodeAndDisabledById;
                existsCounter = individualTaxActorDao::countIndividualByCompanyIdAndTaxCode;
                break;
            }
            default:
                throw new RuntimeException("不能识别的个税客户类型:" + type);
        }

Я думаю, что двафрагмент кода имеет совершенно другую логику, но тот же шаблон switch, я не могу принять предупреждение IDE E, пожалуйста, помогите мне исправить это. *

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

Фрагменты кода, которые вы сравниваете, строго не являются дубликатами. Они похожи, но довольно отчетливы. Нет хорошего способа оптимизировать это с точки зрения читабельности (при условии, что вы хотите сохранить фундаментальную структуру с switch es).

Кроме того, ваши switch 'возвращают' два результата, оба оченьотличается по своим типам и значениям. Если бы это было иначе, вы бы смогли извлечь метод и вернуть Pair (библиотека Apache), равную Function с, но, поскольку Function с совершенно разные (один из них даже BiFunction),это невозможно.

Я бы придерживался вашего кода.

0 голосов
/ 08 ноября 2019

Идея от TreffnonX, я сделал класс-оболочку для "возвратных" функций.

private static class SearchFunctions{
        Function<ActorCondition, Integer> counter;
        Function<ActorCondition, Collection<IndividualTaxActorVO>> searcher;
        //ignore ...
}
private static class LinkFunctions{
        Function<String, IdAndTaxCodeAndDisabledOnly> findById;
        BiFunction<String, String, Integer> existsCounter;
}

И в search метод:

        switch (type) {
            case INDIVIDUAL: {
                functions=new SearchFunctions(individualTaxActorDao::countIndividual,
                        individualTaxActorDao::searchIndividual);
                break;
            }
            case CORPORATE: {
                functions=new SearchFunctions(individualTaxActorDao::countCorporate,
                        individualTaxActorDao::searchCorporate);
                break;
            }
            default:
                throw new RuntimeException("不能识别的个税客户类型:" + type);
        }

и в link метод:

        switch (type) {
            case INDIVIDUAL: {
                functions=new LinkFunctions(individualCustomerService::findTaxCodeAndDisabledById,
                        individualTaxActorDao::countCorporateByCompanyIdAndTaxCode);
                break;
            }
            case CORPORATE: {
                functions=new LinkFunctions(customerService::findTaxCodeAndDisabledById,
                        individualTaxActorDao::countIndividualByCompanyIdAndTaxCode);
                break;
            }
            default:
                throw new RuntimeException("不能识别的个税客户类型:" + type);
        }

Да, это работает! Никакого предупреждения о дублированном фрагменте кода сейчас!

Но я думаю, что это слишком дорого! Решение должно быть принято.

...