Шаблон проектирования для выполнения запросов на разных "выходных уровнях"

Я анализирую строку как:

\read(customer) hello world


~> \method(arg, arg, ...)

в составную структуру данных, которая содержит от 1 до n аргументов, которые являются объектами requestLeaf, аргументы которых могут быть объектом requestLeaf (если это просто простой текст, который должен быть возвращен, как указано выше ("привет мир")) или другим объектом requestComposite (если происходит какое-то вычисление (например, read->customer), пока он снова не станет простым текстом.

requestComposite Object
(
  [requests:protected] => Array
      (
          [0] => commandRequest Object
              (
                  [methodName:protected] => read
                  [arguments:protected] => Array
                      (
                        [0] => commandRequest Object
                          (
                            [methodName:protected] => text
                            [arguments:protected] => customer
                          )
                      )
              )
          [1] => commandRequest Object
              (
                  [methodName:protected] => text
                  [arguments:protected] =>  hello world
              )
      )
)

Чего я хочу добиться, так это циклически проходить через весь композит, чтобы он отображал какой-то документ.

Аргументы или листы самого первого композита представляют корень или уровень 0 для печати в документе.
Я хочу использовать библиотеку для этого. Эта библиотека может обрабатывать печать текста, изображений и т. Д., Но не может ничего оценивать!

Все > Уровень 0 должен быть вычислен в другой библиотеке.
Эта библиотека может считывать значения элементов, выполнять математические вычисления и т. Д. И возвращать свое окончательное значение (исключительно строки) в корень для распечатки.
Все остальное печатается явно через, например, \img() или \text()

Там может быть

\read(x)

токен для поиска значения элемента X,
значение которого должно быть напечатано неявно, (без переноса его в другое \text())!

может быть токен \list() для циклического перебора его аргументов через указанный список членов, например:

\list(\read(x)))

X может быть другим Y

\list(\read(\read(y))).

Другими словами: я не могу знать, насколько глубокой будет структура.

Бывает, что я довольно новичок в разработке шаблонов и ОО в частности.
Я возился с шаблоном цепочки ответственности для "выполнения" прямо сейчас, где библиотека рендеринга / вывода и библиотека вычислений строят цепочку обработчиков.
Но мне несколько любопытно, действительно ли CoR полностью удовлетворяет мои потребности:

Как бы вы решили такую ​​проблему?

РЕДАКТИРОВАТЬ: МОЙ ПОДХОД КАК СЕЙЧАС

  1. перебирать композиты.
    прохождение объекта- посредника
    который содержит выходную библиотеку и библиотеку вычислений.

  2. если текущий лист является текстом
    проверить, является ли текущий корень
    если НЕТ, посетите библиотеку вычислений, чтобы оценить фактическое значение и передать его тому, кого это может касаться (например, \read(), \varput(), ...)
    если ДА, посетите выходную библиотеку, чтобы распечатать ее

Что мне приходит в голову, так это то, что мне нужно реализовать каждый метод requestMethod в обеих библиотеках, чтобы добиться автоматической корневой печати. т.е.
\ read () в выводе должен печатать текст в документе,
\ read () в библиотеке вычислений должен искать значение члена.

Я здесь все усложняю?

1 ответ

Решение

Продолжая комментарии, и предполагая, что вы построили составное дерево из вашего ввода, что вам нужно, что нельзя сделать следующим образом:

import java.util.ArrayList;
import java.util.List;
interface Component {
    void add(Component component);
    List<Component> children();
}
class Composite implements Component {
    @Override public void add(Component component) {
        children.add(component);
    }
    @Override public List<Component> children() {
        return children;
    }
    List<Component> children=new ArrayList<>();
}
class Leaf implements Component {
    @Override public void add(Component component) {
        throw new UnsupportedOperationException();
    }
    @Override public List<Component> children() {
        return null;
    }
}
public class So34886186 {
    static String indent(int n) {
        String s="";
        for(int i=0;i<n;i++)
            s+=" ";
        return s;
    }
    static void print(Component root,Component component,int indent) {
        if(component instanceof Leaf)
            if(component.equals(root))
                System.out.println(indent(indent)+"    root: leaf: "+component);
            else System.out.println(indent(indent)+"not root: leaf: "+component);
        else {
            if(component.equals(root)) {
                System.out.println(indent(indent)+"    root: composite: "+component+": (");
                for(Component component2:((Composite)component).children)
                    print(root,component2,indent+4);
                System.out.println(indent(indent)+")");
            } else {
                System.out.println(indent(indent)+"not root: composite: "+component+": (");
                for(Component component2:((Composite)component).children)
                    print(root,component2,indent+4);
                System.out.println(indent(indent)+")");
            }
        }
    }
    public static void main(String[] args) {
        Component root=new Composite();
        root.add(new Leaf());
        Component one=new Composite();
        root.add(one);
        one.add(new Leaf());
        Component two=new Composite();
        root.add(two);
        print(root,root,0);
    }
}
Другие вопросы по тегам