Использование тегов скриптов:
<script>...</script>
, содержащий ваш многострочный текст в тег head
; <script>
// pure javascript
var text = document.getElementById("mySoapMessage").innerHTML ;
// using JQuery's document ready for safety
$(document).ready(function() {
var text = $("#mySoapMessage").html();
});
</script>
<script id="mySoapMessage" type="text/plain">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="...">
<soapenv:Header/>
<soapenv:Body>
<typ:getConvocadosElement>
...
</typ:getConvocadosElement>
</soapenv:Body>
</soapenv:Envelope>
<!-- this comment will be present on your string -->
//uh-oh, javascript comments... SOAP request will fail
</script>
(1) Кажется, вы смешиваете разные аспекты - управляющий поток и логика домена .
element.ifExist(() -> { ... }).otherElementMethod();
^ ^
control flow method business logic method
(2) Неясно, как должны вести себя методы после метода потока управления (например, ifExist
, ifNotExist
). Если они всегда выполняются или вызывается только при условии (аналогично ifExist
)?
(3) Имя ifExist
подразумевает операцию терминала, поэтому возвращаться нечего - void
, Хорошим примером является void ifPresent(Consumer)
из Optional
.
Я бы написал полностью разделенный класс, не зависит от какого-либо конкретного класса и любого конкретного условия.
Интерфейс прост и состоит из двух методов бесконтактного управления потоком - ifTrue
и ifFalse
.
несколько способов создания объекта Condition
. Я написал статический заводский метод для вашего экземпляра (например, element
) и условие (например, Element::exist
).
public class Condition<E> {
private final Predicate<E> condition;
private final E operand;
private Boolean result;
private Condition(E operand, Predicate<E> condition) {
this.condition = condition;
this.operand = operand;
}
public static <E> Condition<E> of(E element, Predicate<E> condition) {
return new Condition<>(element, condition);
}
public Condition<E> ifTrue(Consumer<E> consumer) {
if (result == null)
result = condition.test(operand);
if (result)
consumer.accept(operand);
return this;
}
public Condition<E> ifFalse(Consumer<E> consumer) {
if (result == null)
result = condition.test(operand);
if (!result)
consumer.accept(operand);
return this;
}
public E getOperand() {
return operand;
}
}
Кроме того, мы можем интегрировать Condition
в Element
:
class Element {
...
public Condition<Element> formCondition(Predicate<Element> condition) {
return Condition.of(this, condition);
}
}
Я поощряю шаблон:
Element
; Condition
; Condition
; Element
, Element
. Получение Condition
с помощью Condition.of
:
Element element = new Element();
Condition.of(element, Element::exist)
.ifTrue(e -> { ... })
.ifFalse(e -> { ... })
.getOperand()
.otherElementMethod();
Получение Condition
на Element#formCondition
:
Element element = new Element();
element.formCondition(Element::exist)
.ifTrue(e -> { ... })
.ifFalse(e -> { ... })
.getOperand()
.otherElementMethod();
Для других методов тестирования идея остается той же.
Element element = new Element();
element.formCondition(Element::isVisible);
element.formCondition(Element::isEmpty);
element.formCondition(e -> e.hasAttribute(ATTRIBUTE));
Это хорошая причина переосмыслить код дизайн. Ни один из 2 фрагментов не замечателен.
Представьте, что вам нужно actionC
в e0.exist()
. Как изменить ссылку на метод Element::actionA
?
Он будет возвращен в лямбда:
e0.ifExist(e -> { e.actionA(); e.actionC(); });
, если вы не обернете actionA
и actionC
одним методом (что звучит ужасно):
e0.ifExist(Element::actionAAndC);
Теперь лямбда еще менее читаема, тогда if
был.
e0.ifExist(e -> {
e0.actionA();
e0.actionC();
});
Но сколько усилий мы сделаем для этого? И сколько усилий мы приложим для поддержания всего этого?
if(e0.exist()) {
e0.actionA();
e0.actionC();
}
Поскольку он почти не совпадает с необязательным, возможно, вы можете пересмотреть логику:
Java 8 имеет ограниченную выразительность:
Optional<Elem> element = ...
element.ifPresent(el -> System.out.println("Present " + el);
System.out.println(element.orElse(DEFAULT_ELEM));
Здесь map
может ограничивать представление элемента:
element.map(el -> el.mySpecialView()).ifPresent(System.out::println);
Java 9:
element.ifPresentOrElse(el -> System.out.println("Present " + el,
() -> System.out.println("Not present"));
В общем случае две ветви асимметричны.
exists
, вероятно, указывает на то, что Optional
будет более подходящим. И forEach
определенно ошибается, спасибо.
– Joop Eggen
16 April 2018 в 13:39
Он называется свободным интерфейсом '. Просто измените тип возвращаемого значения и return this;
, чтобы вы могли привязать методы:
public MyClass ifExist(Consumer<Element> consumer) {
if (exist()) {
consumer.accept(this);
}
return this;
}
public MyClass ifNotExist(Consumer<Element> consumer) {
if (!exist()) {
consumer.accept(this);
}
return this;
}
Вы могли бы получить немного более интересный и вернуть промежуточный тип:
interface Else<T>
{
public void otherwise(Consumer<T> consumer); // 'else' is a keyword
}
class DefaultElse<T> implements Else<T>
{
private final T item;
DefaultElse(final T item) { this.item = item; }
public void otherwise(Consumer<T> consumer)
{
consumer.accept(item);
}
}
class NoopElse<T> implements Else<T>
{
public void otherwise(Consumer<T> consumer) { }
}
public Else<MyClass> ifExist(Consumer<Element> consumer) {
if (exist()) {
consumer.accept(this);
return new NoopElse<>();
}
return new DefaultElse<>(this);
}
Образец использование:
element.ifExist(el -> {
//do something
})
.otherwise(el -> {
//do something else
});
if the exist condition is true, no need to check ifNotExist
– Eran
16 April 2018 в 12:28
Вы можете использовать один метод, который принимает двух пользователей:
public void ifExistOrElse(Consumer<Element> ifExist, Consumer<Element> orElse) {
if (exist()) {
ifExist.accept(this);
} else {
orElse.accept(this);
}
}
Затем вызовите его с помощью:
element.ifExistOrElse(
el -> {
// Do something
},
el -> {
// Do something else
});
(exist() ? ifExist : orElse).accept(this);
– Andrew Tobilko
16 April 2018 в 12:45
if
/ else
в первую очередь.)
– jpmc26
16 April 2018 в 21:50
Как некоторые предложения, у меня есть идея кэшировать логическое значение:
public class Element {
private Boolean exist;
public void ifExist(Consumer<Element> consumer) {
if (exist == null) {
exist = exist();
}
if (exist) {
consumer.accept(this);
}
}
public void ifNotExist(Consumer<Element> consumer) {
if (exist == null) {
exist = exist();
}
if (!exist) {
consumer.accept(this);
}
}
}
getOperand().otherElementMethod()
лучше, чем второе утверждениеelement.otherElementMethod()
после условного материала? – Michael 16 April 2018 в 22:09Function<E, Boolean>
, используйте Predicate – Michael 16 April 2018 в 22:10Predicate
- вы правы, спасибо – Andrew Tobilko 17 April 2018 в 08:33