LINUX.ORG.RU

Инициализация бина с заданными опциями

 , ,


0

2

Прошу совета как правильно сделать то, что мне нужно. Чую что что-то не так в написанном коде.

Итак. Изначально была необходимость в функции фильтрации. Фильтрация происходит разными способами, основные методы и зависимости описаны в абстрактном классе. Было что-то вроде:

public abstract class AbstractFilter implements Filter
{
   //beans definitions
   @Override
   public boolean filter(String color)
   {
      //implementation
   }
   public boolean isWarm(String color)
   {
      //implementation
   }
   public boolean isDark(String color)
   {
      //implementation
   }
   public boolean isNeon(String color)
   {
      //implementation
   }
}
И соответственно была куча классов типа:
public class WarmDarkFilter extends AbstractFilter
{
   @Override
   public boolean filter(String color)
   {
      return super.filter(color)&&isWarm(color)&&isDark(color);
   }
}
public class NeonBrightFilter extends AbstractFilter
{
   @Override
   public boolean filter(String color)
   {
      return super.filter(color)&&isNeon(color)&&!isDark(color);
   }
}
...

Когда пришла необходимость добавить еще пару классов в таком же стиле было принято решение отрефакторить и упростить эту структуру. Переделано так:

public class ColorFilter extends AbstractFilter
{
   private Function<String, Boolean> filteringFunction;

   ProductFilter(FilteringFunction filteringFunctionEnum)
   {
      this.filteringFunction = getFilteringFunction(filteringFunctionEnum);
   }

   @Override
   public boolean filter(String color)
   {
      return filteringFunction.apply(color);
   }

   private Function<String, Boolean> getFilteringFunction(final FilteringFunction filteringFunction)
   {
      Function<String, Boolean> function = null;
      if (WARM_DARK.equals(filteringFunction))
      {
         function = (String color) -> super.filter(color)&&isWarm(color)&&isDark(color);
      }
      else if (NEON_BRIGHT.equals(filteringFunction))
      {
         function = (String color) -> super.filter(color)&&isNeon(color)&&!isDark(color);
      }
...
      else
      {
         throw new BeanInitializationException("Filtering function can't be null");
      }
      return function;
   }

   public enum FilteringFunction
   {
      WARM_DARK, NEON_BRIGHT,...;
   }

Соответственно вместо объявления 100500 бинов теперь просто указывается нужная опция в конструкторе.

        <property name="colorFilter">
            <bean class = "com.lor.ColorFilter" parent="abstractFilter">
                <constructor-arg value="WARM_DARK"/>
            </bean>
        </property>

Как можно улучшить этот код? вернуться к подходу 100500 классов? Создать factoryMethod? Discuss please.

У тебя хоть какие-то переопределяются методы AbstractFilter кроме, непосредственно, метода boolean filter(String color)?

Не понимаю, что ты хочешь получить, короткую запись всего этого?

Deleted ()

Может тебе хочется что-то вроде:

@FunctionalInterface
interface ColorFilter {
    boolean filter(String color);
}

interface Check {
    static boolean isWarm(String color) {
        return true; // заменить на проверку цвета
    }

    static boolean isDark(String color) {
        return true; // заменить на проверку цвета
    }

    static boolean isNeon(String color) {
        return true; // заменить на проверку цвета
    }
}

enum PredefinedColorFilter implements ColorFilter {
    WARM_DARK(c -> Check.isDark(c) && Check.isWarm(c)),
    NEON_BRIGHT(c -> Check.isNeon(c) && !Check.isDark(c)),
    /* ну и так далее */;

    private final ColorFilter e;

    PredefinedColorFilter(ColorFilter e) {
        this.e = e;
    }

    @Override
    public boolean filter(String color) {
        return e.filter(color);
    }
}
с короткой записью всех проверок в enum?

Не догоняю.

Deleted ()
Последнее исправление: merhalak (всего исправлений: 1)

У вас смешались котлеты и мухи. Выделить isWarm, isDark, etc в отдельные Filter бины. Добавить поддержку отрицания (поддержку boolean not). И выделить ListFilter impl Filter который будет бегать по переданному списку фильтров.

Соответственно формировать итоговый фильтр через передачу bean ref в списке. Это позволит формировать большое кол-во логически законченных фильтров без прописывания java кода.

vtVitus ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.