0

I am parsing a string like:

\read(customer) hello world


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

into a composite data structure that persists of 1 to n arguments, which are requestLeaf objects, which arguments can be a requestLeaf object (if it's just plain text, that should be returned like above ("hello world")) or another requestComposite object (if there is some computation going on(like read->customer) until it's just plain text again.

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
              )
      )
)

What I want to achieve is to loop through the whole composite so that it renders some kind of document.

The arguments or leafs of the very first composite are representing the root or Level 0 for printing to the document.
I want to use a Library for this. This library can handle printing text, images, etc. but cannot evaluate anything!

Everything > Level 0 should be computed in another library.
This library can read member values, do some math, etc. and return its final value (exclusively strings) to the root to be printed out.
Everything else is printed explicit via e.g. \img() or \text()

There may be a

\read(x)

token to lookup a member value X,
whichs value should be printed implicit, (without wrapping it into another \text())!

there may be a \list() token to loop its arguments through a specified member list like:

\list(\read(x)))

X could be another Y

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

In other words: I cannot know how deep the structure will be.

Happens that I'm fairly new to Design Patterns and OO in particular.
I am fiddling around with the Chain of Responsibility Pattern for "executing" right now, where the rendering/output library and the computation library are building the handler chain.
But I'm somewhat curious about if CoR really fullfills my needs:

How would you solve a problem like this?

EDIT: MY APPROACH AS FOR NOW

  1. to iterate through the composites.
    passing along a Mediator Object
    which contains the output library and the computation library.

  2. if current leaf is text
    check if current is the root
    if NO visit the computation library to evaluate the actual value and pass it to whom it may concern (e.g. \read(), \varput(), ...)
    if YES visit the output library to print it out

What comes to my mind is that I have to implement every requestMethod in both libraries to achieve the automatic root printing. i.e.
\read() in output should print text to the document,
\read() in the computation library should lookup a member value.

Am I overcomplicating things here?

Marcin Szymczak
  • 11,199
  • 5
  • 55
  • 63
lance
  • 65
  • 10
  • what are you trying to do that can not be done with just the plain old https://en.wikipedia.org/wiki/Composite_pattern? maybe you just have to run around the tree first a bit? – Ray Tayek Jan 19 '16 at 23:27
  • 1. My question could have been not quite explicit enough. I updated the problem description. 2. What is so confusing and unclear to me is: How would I determine the right handler for the different structure levels (if root ~> print to pdf, if not ~> return computed value to root, so it can be printed. – lance Jan 20 '16 at 09:50
  • This is what recursion is for. Method takes an input, does work on what bit is next, evaluates if it did the last bit or not. If YES, returns some value, if NO, strips the processed bit off the input, and passes the stripped input to itself. – dbugger Jan 20 '16 at 13:26
  • I know how to move into the structure and out again. I updated the question again with another, maybe better example. Everything evaluated should be returned to the root to be printed out, without wrapping another \text() around it. Anything else I want to print besides text, I will do explicit via e.g. \img(). – lance Jan 20 '16 at 19:26

1 Answers1

0

continuing from comments, and assuming that you have built your composite tree from your input, what do you need that can not be done like this:

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);
    }
}
Ray Tayek
  • 9,841
  • 8
  • 50
  • 90