8 Replies Latest reply: Mar 15, 2011 4:01 PM by jschellSomeoneStoleMyAlias RSS

    Design challenge: what pattern to force this into?

    845458
      hello,
      I have a small problem that I suspect may not be that uncommon, but I feel I do not have a good design for it. I have an abstract class with an abstract execute()-method. The concrete classes (around 10 of them) are building on each others result and the end-result is achieved when the last concrete class has executed. I beilieve it looks a bit like the Builder-pattern, but there are some issues that might not completely fit with the Builder.
      - all concrete classes need to execute
      - the order is fixed, i.e. class C loosely depends on the result from class B etc.

      any suggestions or insights are highly appreciated!

      abstract class A {
         Map map;
         abstract Map execute();
         void doSomeCommonStuff() {
            // do common stuff
         }
      }
      
      class B extends A {
         public B(Map map) {
            this.map = map;
         }
         Map execute() {
            // do map-stuff
         }
      }
      
      class C extends A {
         public C(Map map) {
            this.map = map;
         }
         Map execute() {
            // do map-stuff
         }
      }
      and the usage is something like
      Map map = new B(new HashMap()).execute();
      map = new C(map).execute();
      map = new D(map).execute();
      etc.
        • 1. Re: Design challenge: what pattern to force this into?
          796440
          Chain of Responsibility leaps to mind as a candidate, but I didn't read your post that closely or think about it that much, so be sure to research thoroughly before leaping on it.
          • 2. Re: Design challenge: what pattern to force this into?
            jschellSomeoneStoleMyAlias
            I beilieve it looks a bit like the Builder-pattern
            Not per your description.
            but I feel I do not have a good design for it
            I don't see anything wrong with how you laid it out.

            Do you have cases where not all 10 should run? Or cases where different combinations of the 10 run?
            • 3. Re: Design challenge: what pattern to force this into?
              YoungWinston
              user7898592 wrote:
              I beilieve it looks a bit like the Builder-pattern, but there are some issues that might not completely fit with the Builder.
              I'm not an expert on pattern names but it seems a bit that way to me too, especially if, as jschell says, you don't need to execute all your subclasses in order to get a result.

              However, I'm not quite sure why you think you need subclasses. If indeed they are simply different aspects of initialization of a single object (the Map; or your class A instance), could they not simply be different methods of an ABuilder class, viz:
              public class A {
                 private final Map map;
                 // any other variables
                 private A(ABuilder ab) {
                    // initialize the class from 'ab' contents
                 }
                 public Map execute() {
                    // do whatever execute does
                 }
              
                 public static class ABuilder {
                    private final Map map;
                    // any other variables
                    public ABuilder(Map map) {
                       this.map = map;
                    }
                    public ABuilder doB(...) { // update Builder Map }
                    public ABuilder doC(...) { // update Builder Map }
                    ...
                    // other Builder methods
                    ...
                    public A build() {
                       return new A(this);
                    }
                }
              }
              Then your construction and execution becomes something like:
              A instanceA = new ABuilder(new HashMap())
                 .doB(...).doC(...).doF(...).build();
              instanceA.execute();
              On the other hand, if they are all executables in their own right, each with its own portion of the Map to be added to A, what about adding an Executable interface that they all implement?
              'A' could simply then be another Executable rather than a superclass, and you could make the others actors to your ABuilder, eg:
              public <T extends Executable> ABuilder add(T toAdd) {
                 // update Builder Map with the contents of 'toAdd's
              }
              and your construction and execution would be something like:
              A instanceA = new ABuilder(new HashMap())
                 .add(B).add(C).add(F).build();
              instanceA.execute();
              With class names like A, B and C, it's difficult to follow exactly what you want to do, but that's how a Builder might work.

              PS: Your title is a bit iffy to me too. You shouldn't have to force something into a pattern; it should hopefully fit in naturally :-).

              Winston
              • 4. Re: Design challenge: what pattern to force this into?
                gimbal2
                Design pattern? The requirements seem to call for the usage of a queue.
                • 5. Re: Design challenge: what pattern to force this into?
                  YoungWinston
                  gimbal2 wrote:
                  Design pattern? The requirements seem to call for the usage of a queue.
                  Good point. Maybe OP (and I) are overthinking this.

                  Winston
                  • 6. Re: Design challenge: what pattern to force this into?
                    845458
                    thank you for all the good suggestions. You are probably right, the problem might not fit into any pattern at all, but the Chain of Responsibility seems like a hot candidate. I do not have any intention of forcing a pattern solution to this problem, I just thought it might be interesting if there was a relevant pattern. I will be thinking about your suggestions for a while.

                    additional info: the different classes might run several times, e.g. I might have to do A first, then B and then A again. And not all of them have to execute.
                    • 7. Re: Design challenge: what pattern to force this into?
                      YoungWinston
                      user7898592 wrote:
                      additional info: the different classes might run several times, e.g. I might have to do A first, then B and then A again. And not all of them have to execute.
                      In which case, I think you need to supply a bit more explanation. Every class in your example has an execute() method, but I'm still in the dark as to what it's doing.

                      Winston
                      • 8. Re: Design challenge: what pattern to force this into?
                        jschellSomeoneStoleMyAlias
                        user7898592 wrote:
                        additional info: the different classes might run several times, e.g. I might have to do A first, then B and then A again. And not all of them have to execute.
                        Far as I am concerned everything else you have posted is pointless versus what you just said.

                        How one creates instances is not a specific part of the Builder pattern. What is specific is that building varies.

                        Which is exactly what you said above.

                        In terms of running the items, which is what your first post seemed to be about, you need do nothing more than put the constructed items in a list and then sequentially run each in a loop.

                        The builder is what creates the instances and puts them in the list.