Re: Уменьшить Cognitive Complexity метода. рефакторинг.
От: jusf  
Дата: 20.09.18 06:10
Оценка:
Привет.
Можно сделать так:
    private void fillCvsColumnsValues(ExportOrderRequestDto request, ZoneId zoneId, DateTimeFormatter dateFormat,
                                      CsvBuilder csvBuilder, PageDto<IndexedDraftOrderDto> searchOrders) {

        ReportBuilder builder = new ReportBuilder(csvBuilder, request);

        for (IndexedDraftOrderDto o : searchOrders.getContent()) {

            builder.addNextColumnValue(ExportColumnEnum.ORDER_CODE, o::getOrderCode);

            builder.addNextColumnValue(ExportColumnEnum.STATUS, () ->
                    nonNull(o.getOrderState()) ? ORDER_STATE_DESC.get(o.getOrderState()) : "");

            builder.addNextColumnValue(ExportColumnEnum.CUSTOMER, () ->
                    nonNull(o.getCustomer()) ? o.getCustomer().getName() : "");

            builder.addNextColumnValue(ExportColumnEnum.ANIMAL_COUNT, o::getNumberOfAnimals);

            builder.addNextColumnValue(ExportColumnEnum.SAVED, () ->
                    formatDate(o.getSavedDate(), zoneId, dateFormat));

            builder.addNextColumnValue(ExportColumnEnum.PRODUCT, () ->
                    ofNullable(o.getProducts()).orElse(Collections.emptyList()).stream()
                            .map(IndexedProductDto::getProductName)
                            .collect(Collectors.toList()));

            builder.addNextColumnValue(ExportColumnEnum.MARKET, o::getMarket);

            builder.endRow();
        }
    }

    class ReportBuilder {
        private CsvBuilder csvBuilder;
        private ExportOrderRequestDto request;

        public ReportBuilder(CsvBuilder csvBuilder, ExportOrderRequestDto request) {
            this.csvBuilder = csvBuilder;
            this.request = request;
        }

        public <T> void addNextColumnValue(ExportColumnEnum exportColumn, Supplier<T> supplier) {
            if (request.getColumns().contains(exportColumn)) {
                csvBuilder.addNextColumnValue(supplier.get());
            }
        }

        public void endRow() {
            csvBuilder.endRow();
        }
    }
Re: Уменьшить Cognitive Complexity метода. рефакторинг.
От: omgOnoz  
Дата: 25.09.18 09:31
Оценка:
Здравствуйте, HAXT, Вы писали:

К самому коду есть претензии:

Сложность: все проверки if выполняются на каждой итерации цикла, хотя очевидно что достаточно их выполнить 1 раз (до цикла).

Стиль:
            if (request.getColumns().contains(ExportColumnEnum.STATUS)) {
                csvBuilder.addNextColumnValue(isNull(o.getOrderState()) ? "" : ORDER_STATE_DESC.get(o.getOrderState()));
            }

            if (request.getColumns().contains(ExportColumnEnum.CUSTOMER)) {
                String name = nonNull(o.getCustomer()) ? o.getCustomer().getName() : "";
                csvBuilder.addNextColumnValue(name);
            }


Что это вообще такое ORDER_STATE_DESC.get?


Для начала просится, что-то вроде chain consumer-а:

  private void fillCvsColumnsValues(ExportOrderRequestDto request, ZoneId zoneId, DateTimeFormatter dateFormat,
                                    CsvBuilder csvBuilder, PageDto<IndexedDraftOrderDto> searchOrders) {

    Consumer<IndexedDraftOrderDto> processor = t -> {};

    if (request.getColumns().contains(ExportColumnEnum.ORDER_CODE)) {
      processor = processor.andThen((o) -> csvBuilder.addNextColumnValue(o.getOrderCode()));
    }

    if (request.getColumns().contains(ExportColumnEnum.STATUS)) {
      processor = processor.andThen((o) -> csvBuilder.addNextColumnValue(isNull(o.getOrderState()) ? "" : ORDER_STATE_DESC.get(o.getOrderState())));
    }

    if (request.getColumns().contains(ExportColumnEnum.CUSTOMER)) {
      processor = processor.andThen((o) -> csvBuilder.addNextColumnValue(nonNull(o.getCustomer()) ? o.getCustomer().getName() : ""));
    }

    if (request.getColumns().contains(ExportColumnEnum.ANIMAL_COUNT)) {
      processor = processor.andThen((o) -> csvBuilder.addNextColumnValue(o.getNumberOfAnimals()));
    }

    if (request.getColumns().contains(ExportColumnEnum.SAVED)) {
      processor = processor.andThen((o) -> csvBuilder.addNextColumnValue(formatDate(o.getSavedDate(), zoneId, dateFormat)));
    }

    if (request.getColumns().contains(ExportColumnEnum.PRODUCT)) {
      processor = processor.andThen((o) -> {
        List<String> products = Optional.ofNullable(o.getProducts()).orElse(Collections.emptyList()).stream()
            .map(IndexedProductDto::getProductName)
            .collect(Collectors.toList());
        csvBuilder.addNextColumnValue(products);
      });
    }

    if (request.getColumns().contains(ExportColumnEnum.MARKET)) {
      processor = processor.andThen((o) -> csvBuilder.addNextColumnValue(o.getMarket()));
    }

    processor.andThen(o -> csvBuilder.endRow());

    Arrays.asList(searchOrders.getContent()).forEach(processor);
  }
Отредактировано 25.09.2018 9:36 omgOnoz . Предыдущая версия .
Re: Уменьшить Cognitive Complexity метода. рефакторинг.
От: anton_t Россия  
Дата: 02.10.18 11:04
Оценка:
Здравствуйте, HAXT, Вы писали:

HAX>Коллеги, подскажите пожалуйста способы, которыми можно уменьшить когнитивную сложность метода, средствами Java 8

HAX>Хотелось бы какое то элегантное решение, может быть предикатами или лямбдами переделать. Есть какие идеи ?

Как-то так:

 private void addColumn(ExportOrderRequestDto request, ExportColumnEnum column, Supplier<Object> supplier) {
            if (request.getColumns().contains(column)) {
                csvBuilder.addNextColumnValue(supplier.get());
            }   
 }
 
 private void fillCvsColumnsValues(ExportOrderRequestDto request, ZoneId zoneId, DateTimeFormatter dateFormat,
                                      CsvBuilder csvBuilder, PageDto<IndexedDraftOrderDto> searchOrders) {
        for (IndexedDraftOrderDto o : searchOrders.getContent()) {
            addColumn(request, ExportColumnEnum.ORDER_CODE, () -> o.getOrderCode());
            addColumn(request, ExportColumnEnum.STATUS, () -> o.getOrderState()) ? "" : ORDER_STATE_DESC.get(o.getOrderState()));
            addColumn(request, ExportColumnEnum.CUSTOMER, () -> o.getOrderState()) ? "" : ORDER_STATE_DESC.get(o.getOrderState()));
            addColumn(request, ExportColumnEnum.ANIMAL_COUNT, () -> o.getNumberOfAnimals());
            addColumn(request, ExportColumnEnum.SAVED, () -> formatDate(o.getSavedDate(), zoneId, dateFormat));
            addColumn(request, ExportColumnEnum.PRODUCT, () -> Optional.ofNullable(o.getProducts())
                                                    .orElse(Collections.emptyList()).stream()
                                                    .map(IndexedProductDto::getProductName).collect(Collectors.toList()));
            addColumn(request, ExportColumnEnum.MARKET, () -> o.getMarket());

            csvBuilder.endRow();
        }


Код не компилировал, да и доступа к твоим исходникам у меня нет, так что может понадобиться доработка.
Отредактировано 02.10.2018 16:51 anton_t . Предыдущая версия .
Re: Уменьшить Cognitive Complexity метода. рефакторинг.
От: alexey.a.semenov  
Дата: 30.11.18 13:35
Оценка:
Здравствуйте, HAXT, Вы писали:

HAX>Коллеги, подскажите пожалуйста способы, которыми можно уменьшить когнитивную сложность метода, средствами Java 8

HAX>Хотелось бы какое то элегантное решение, может быть предикатами или лямбдами переделать. Есть какие идеи ?

public interface ConverterContext {
    Object nullSafe(Long long);
    Object nullSafe(Date date);
    ...
}

public interface Column {
  Object valueFrom(IndexedDraftOrderDto data, ConverterContext context);
}

public enum ExportColumnEnum implements Column {
  ORDER_CODE {
      public Object valueFrom(IndexedDraftOrderDto data, ConverterContext context){
            return context.nullSafe(data.getOrderCode());
      }
  },
  SAVED {
     public Object valueFrom(IndexedDraftOrderDto data, ConverterContext context){
            return context.nullSafe(data.getSaved());
     }
  }, .... // other columns 
}

public class ExportOrderRequestDto {
    private List<ExportColumnEnum> columns;
}

public interface OutBuilder {
    OutBuilder append(Object value);
    OutBuilder endRow();       
}

private void fillCvsColumnsValues(List<? extends Column> columns, 
                      ConverterContext context
                                      OutBuilder builder, 
                                      PageDto<IndexedDraftOrderDto> orders) {
        for (final IndexedDraftOrderDto o : orders.getContent()) {

            for (final Column column: columns){
                  builder.append(column.valueFrom(o, context));
            }      

            builder.endRow();
        }
}
Re: Уменьшить Cognitive Complexity метода. рефакторинг.
От: kl Германия http://stardog.com
Дата: 30.11.18 17:19
Оценка:
Здравствуйте, HAXT, Вы писали:

HAX>Коллеги, подскажите пожалуйста способы, которыми можно уменьшить когнитивную сложность метода, средствами Java 8

HAX>Хотелось бы какое то элегантное решение, может быть предикатами или лямбдами переделать. Есть какие идеи ?

Оставляя за скобками красоту кода (тут уже много насоветовали), меня больше смущает вот это:
        for (IndexedDraftOrderDto o : searchOrders.getContent()) {

            if (request.getColumns().contains(ExportColumnEnum.ORDER_CODE)) {
                csvBuilder.addNextColumnValue(o.getOrderCode());
            }

Тут проверка
request.getColumns().contains(ExportColumnEnum.ORDER_CODE)
не зависит от "o", а выполняется на каждой итерации.
no fate but what we make
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.