2015-10-13 3 views
2

У меня есть следующий код, где Binding.createStringBinding(...) часть будет повторяться много много раз, единственным отличием является метод, т.е. getA(), getB(), getC()Как написать способ повторного использования этого кода?

this.attributeA.bind(Bindings.createStringBinding(() -> { 
     if(webService.getLastValue() != null){ 
      return webService.getLastValue().getA(); 
     } else{ 
      return ""; 
     } 
    }, webService.lastValueProperty())); 

    this.attributeB.bind(Bindings.createStringBinding(() -> { 
     if(webService.getLastValue() != null){ 
      return webService.getLastValue().getB(); 
     } else{ 
      return ""; 
     } 
    }, webService.lastValueProperty())); 

Новое: Это часть кода, который я хочу сделать повторно используемым:

Bindings.createStringBinding(() -> { 
      if(webService.getLastValue() != null){ 
       return webService.getLastValue().getB(); 
      } else{ 
       return ""; 
      } 
     }, webService.lastValueProperty()) 

Как сделать это многоразовым? Возможно, это функция?

+0

прочее отличие есть 'этот. АтрибутА' или' B' или 'C', предположим, – sam

+0

есть путаница.Я немного изменил свой вопрос. – st202

+0

Какой тип 'webService.getLastValue()' return? –

ответ

4

Может быть что-то вроде этого:

private Binding createBinder(final Supplier<String> lambda) { 
    return Bindings.createStringBinding(() -> { 
     if(webService.getLastValue() != null){ 
      return lambda.get(); 
     } else{ 
      return ""; 
     } 
    } 
} 

называется как

this.attributeA.bind(createBinder(() -> webService.getLastValue().getA()), webService.lastValueProperty()); 
this.attributeB.bind(createBinder(() -> webService.getLastValue().getB()), webService.lastValueProperty()); 
+0

. Ошибка в параметре' lambda', 'Синтаксическая ошибка, вставка" ... VariableDeclaratorId "для завершения FormalParameterList' – st202

+0

Как я уже сказал, тип данных неверен, потому что я не мог его вспомнить. Я хотел, чтобы вы его нашли, потому что вы сами должны сами вкладывать какую-то работу. Однако я обновлю ответ. – Joshua

+0

Итак, с интерфейсом «Поставщик» мы передаем метод как параметр без отдельного создания интерфейса, упомянутого в этих ответах. Http://stackoverflow.com/questions/2186931/java-pass-method-as-parameter? – st202

1

небольшое изменение на @ ответ Иешуа. Здесь ObjectTest - это тип, возвращаемый webService.getLastValue().

private void makeBinding(StringProperty property, Function<ObjectTest, String> propertyAccessor) { 
    property.bind(Bindings.createStringBinding(() -> { 
     ObjectTest lastValue = webService.getLastValue(); 
     if (lastValue == null) { 
      return "" ; 
     } else return propertyAccessor.apply(lastValue); 
    }, webService.lastValueProperty())); 
} 

И теперь вы

makeBinding(attributeA, ObjectTest::getA); 
makeBinding(attributeB, ObjectTest::getB); 

и т.д.

+0

Почему у нас есть свойство в качестве параметра, если оно не используется в методе? И мои свойства - все 'ReadOnlyStringWrapper' – st202

+0

Извините, попался между двумя разными версиями того, что я намеревался. См. Обновление. 'ReadOnlyStringWrapper' является подклассом' StringProperty', поэтому это должно работать нормально. –

0

Давайте предположим, что attributeA и attributeB как реализовать интерфейс Property<String>, и что методы getA, getB и т.д. все возвращают String. Имея это в виду, вы можете сделать:

BiConsumer<Property<String>, Function<ObjectTest, String>> binder = 
    (property, getter) -> 
     property.bind(Bindings.createStringBinding(() -> { 
      if (webService.getLastValue() != null) { 
       return getter.apply(webService.getLastValue()); 
      } else { 
       return ""; 
      } 
     }, webService.lastValueProperty())); 

Этот код создает BiConsumer (который является потребителем, который принимает 2 аргумента).

Первый аргумент - это пример Property<String> (как предлагается комментарием @ James_D), который реализован attributeA и attributeB.

Второй аргумент - Function<ObjectTest, String>, который является функцией, которая принимает экземпляр ObjectTest и возвращает String. Здесь я использую его для представления общего метода получения по классу ObjectTest (точнее, ObjectTest::getA и ObjectTest::getB).

Если вы хотите, вы можете переписать `BiConsumer» в более java8 приятельски:

BiConsumer<Property<String>, Function<ObjectTest, String>> binder = 
    (property, getter) -> 
     property.bind(Bindings.createStringBinding(
      () -> Optional.ofNullable(webService.getLastValue()) 
       .map(getter).orElse(""), 
      webService.lastValueProperty())); 

Чтобы использовать его:

binder.accept(this.attributeA, ObjectTest::getA); 
binder.accept(this.attributeB, ObjectTest::getB); 

Код выше предполагает, что методы getA, getB, и т. д. верните String.

Возможно, вы захотите ознакомиться и с Optional и BiConsumer в javadocs.

+0

Я предполагаю, что данный интерфейс действительно ['Property '] (http://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/Property.html). (Мне нравится использование 'Optional' хотя.) –

+0

@James_D Я ничего не знаю о javafx, спасибо за ввод. –

Смежные вопросы