You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by David Geary <sa...@tri-lakesonline.net> on 2000/06/19 19:47:30 UTC

Router Proposal

I'm a bit uncomfortable with having actions forward control. I realize
that actions don't actually do the forwarding, but they decide where to
go.

Here's what makes me uncomfortable: It seems to me that routing is not
inherently an action's responsibility. Actions should be limited to
carrying out their specific action, nothing more and nothing less.

In my own Model 2 architecture, I had actions (which I called commands)
and routers. Even though actions are not directly responsible for
routing, actions and routers are tightly coupled; in my framework, each
action has a router, and routers are created with the Factory Method
design pattern, like this:

public abstract class CommandImpl implements Command {
 protected boolean success = false;
 protected Router router = null;

 // extending class must also implement perform() from Command
 protected abstract Router createRouter();

 public synchronized void route(HttpServlet servlet,
    HttpServletRequest req, HttpServletResponse res)
     throws IOException, ServletException {
  if(router == null)
   router = createRouter();

  router.route(servlet, req, res, this);
 }
 public boolean success() {
  return success; // false by default
 }
}

Extensions of CommandImpl must instantiate their router, like this:

public Router createRouter() {  // For a LogonCommand
 return new LogonRouter();
}

The controller servlet uses the commands like this:

public void service(HttpServletRequest req,
            HttpServletResponse res)
         throws IOException, ServletException {
  Command command = getCommand(req);
  command.perform(this, req, res);
  command.route(this, req, res);
 }

So why go to all the trouble to encapsulate routing? Because it
simplifies action classes and routing changes. Actions are once again
simple classes that carry out a specific action, as they were meant to
be. Also, it is much easier in a large application to change routing --
which is a common requirement during development -- because routing code
is not scattered throughout action classes. Routers are typically
grouped into a package, which makes routing modifications even easier.


david


Re: Router Proposal

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
David Geary wrote:

> I didn't know about the forwarding mechanism that Craig pointed out in
> response to my ActionForward Proposal. That mechanism eliminates my concerns
> entirely, and I must admit that I like the Struts forwarding mechanism
> better than my own routing machinery. :-)
>

I wish I could claim total credit for it, but the notion of configurable
forwarding to logical names was discussed several times in the JSP-INTEREST
mailing list messages about Model 2 (most particularly by Daniel Lopez and Kevin
Duffey).  In this particular case, I'm simply implementing the idea -- but it is
pretty elegant, huh?  :-)

>
> david
>

Craig


>
> David Geary wrote:
>
> > I'm a bit uncomfortable with having actions forward control. I realize
> > that actions don't actually do the forwarding, but they decide where to
> > go.
> >
> > Here's what makes me uncomfortable: It seems to me that routing is not
> > inherently an action's responsibility. Actions should be limited to
> > carrying out their specific action, nothing more and nothing less.
> >
> > In my own Model 2 architecture, I had actions (which I called commands)
> > and routers. Even though actions are not directly responsible for
> > routing, actions and routers are tightly coupled; in my framework, each
> > action has a router, and routers are created with the Factory Method
> > design pattern, like this:
> >
> > public abstract class CommandImpl implements Command {
> >  protected boolean success = false;
> >  protected Router router = null;
> >
> >  // extending class must also implement perform() from Command
> >  protected abstract Router createRouter();
> >
> >  public synchronized void route(HttpServlet servlet,
> >     HttpServletRequest req, HttpServletResponse res)
> >      throws IOException, ServletException {
> >   if(router == null)
> >    router = createRouter();
> >
> >   router.route(servlet, req, res, this);
> >  }
> >  public boolean success() {
> >   return success; // false by default
> >  }
> > }
> >
> > Extensions of CommandImpl must instantiate their router, like this:
> >
> > public Router createRouter() {  // For a LogonCommand
> >  return new LogonRouter();
> > }
> >
> > The controller servlet uses the commands like this:
> >
> > public void service(HttpServletRequest req,
> >             HttpServletResponse res)
> >          throws IOException, ServletException {
> >   Command command = getCommand(req);
> >   command.perform(this, req, res);
> >   command.route(this, req, res);
> >  }
> >
> > So why go to all the trouble to encapsulate routing? Because it
> > simplifies action classes and routing changes. Actions are once again
> > simple classes that carry out a specific action, as they were meant to
> > be. Also, it is much easier in a large application to change routing --
> > which is a common requirement during development -- because routing code
> > is not scattered throughout action classes. Routers are typically
> > grouped into a package, which makes routing modifications even easier.
> >
> > david


Re: Router Proposal

Posted by David Geary <sa...@tri-lakesonline.net>.
I didn't know about the forwarding mechanism that Craig pointed out in
response to my ActionForward Proposal. That mechanism eliminates my concerns
entirely, and I must admit that I like the Struts forwarding mechanism
better than my own routing machinery. :-)


david

David Geary wrote:

> I'm a bit uncomfortable with having actions forward control. I realize
> that actions don't actually do the forwarding, but they decide where to
> go.
>
> Here's what makes me uncomfortable: It seems to me that routing is not
> inherently an action's responsibility. Actions should be limited to
> carrying out their specific action, nothing more and nothing less.
>
> In my own Model 2 architecture, I had actions (which I called commands)
> and routers. Even though actions are not directly responsible for
> routing, actions and routers are tightly coupled; in my framework, each
> action has a router, and routers are created with the Factory Method
> design pattern, like this:
>
> public abstract class CommandImpl implements Command {
>  protected boolean success = false;
>  protected Router router = null;
>
>  // extending class must also implement perform() from Command
>  protected abstract Router createRouter();
>
>  public synchronized void route(HttpServlet servlet,
>     HttpServletRequest req, HttpServletResponse res)
>      throws IOException, ServletException {
>   if(router == null)
>    router = createRouter();
>
>   router.route(servlet, req, res, this);
>  }
>  public boolean success() {
>   return success; // false by default
>  }
> }
>
> Extensions of CommandImpl must instantiate their router, like this:
>
> public Router createRouter() {  // For a LogonCommand
>  return new LogonRouter();
> }
>
> The controller servlet uses the commands like this:
>
> public void service(HttpServletRequest req,
>             HttpServletResponse res)
>          throws IOException, ServletException {
>   Command command = getCommand(req);
>   command.perform(this, req, res);
>   command.route(this, req, res);
>  }
>
> So why go to all the trouble to encapsulate routing? Because it
> simplifies action classes and routing changes. Actions are once again
> simple classes that carry out a specific action, as they were meant to
> be. Also, it is much easier in a large application to change routing --
> which is a common requirement during development -- because routing code
> is not scattered throughout action classes. Routers are typically
> grouped into a package, which makes routing modifications even easier.
>
> david


Re: Router Proposal

Posted by jh...@inst.strykercorp.com.
On Mon, 19 Jun 2000, David Geary wrote:

> I'm a bit uncomfortable with having actions forward control. I realize
> that actions don't actually do the forwarding, but they decide where to
> go.
> 
> Here's what makes me uncomfortable: It seems to me that routing is not
> inherently an action's responsibility. Actions should be limited to
> carrying out their specific action, nothing more and nothing less.
> 
> In my own Model 2 architecture, I had actions (which I called commands)
> and routers. Even though actions are not directly responsible for
> routing, actions and routers are tightly coupled; in my framework, each
> action has a router, and routers are created with the Factory Method
> design pattern, like this:
> 
> public abstract class CommandImpl implements Command {
>  protected boolean success = false;
>  protected Router router = null;
> 
>  // extending class must also implement perform() from Command
>  protected abstract Router createRouter();
> 
>  public synchronized void route(HttpServlet servlet,
>     HttpServletRequest req, HttpServletResponse res)
>      throws IOException, ServletException {
>   if(router == null)
>    router = createRouter();
> 
>   router.route(servlet, req, res, this);
>  }
>  public boolean success() {
>   return success; // false by default
>  }
> }
> 
> Extensions of CommandImpl must instantiate their router, like this:
> 
> public Router createRouter() {  // For a LogonCommand
>  return new LogonRouter();
> }
> 
> The controller servlet uses the commands like this:
> 
> public void service(HttpServletRequest req,
>             HttpServletResponse res)
>          throws IOException, ServletException {
>   Command command = getCommand(req);
>   command.perform(this, req, res);
>   command.route(this, req, res);
>  }
> 
> So why go to all the trouble to encapsulate routing? Because it
> simplifies action classes and routing changes. Actions are once again
> simple classes that carry out a specific action, as they were meant to
> be. Also, it is much easier in a large application to change routing --
> which is a common requirement during development -- because routing code
> is not scattered throughout action classes. Routers are typically
> grouped into a package, which makes routing modifications even easier.

If your application needs that extra level of indirection, can you do it
all within an Action in the existing framework?  Something like:

public class MyAction implements Action {

   protected void doAction(...) {...}

   protected Router createRouter(...) {
      return new LogonRouter();
   }

    public ActionForward perform(...)
      throws IOException, ServletException {
        doAction(...);
        createRouter(...).route(...);
        return null;
    }
}

That way you can keep all of your routers separate.  I'm not sure the
extra indirect is warrented in the general case.

> david
>

-jh 

-- 
Jeff Hutchison <jh...@inst.strykercorp.com>
Stryker Instruments, Kalamazoo, MI