You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Mike Menzies <gl...@gmail.com> on 2013/10/07 22:26:26 UTC

JspHelper concept to improve MVC separation

Hello,

My name is Mike, and I work for a fairly large company that uses Struts 2
for most of its web apps. Some of these web apps are quite large, and one
in particular has grown into a monster. In my ongoing efforts to clean up
this project, I have developed what I like to call a JspHelper. Before I
explain exactly what that is, I'd like to provide you with some examples of
the problems that I set out to fix.

*Problem 1 - Monster JSPs*
During early development of this project, struts tags were highly
leveraged. I was not involved with the early phases of this project, so I
can't speak to why they were used so extensively.. but they were. Tons of
nested if tags that read var tags that were set in the JSP. Some of these
JSPs were very hard to follow.

Even though I am a fan of struts tags, I've come to realize that they
should not be overused. JSPs cannot be unit tested and JSPs are hard to
debug.

So cleaning up a JSP means shifting logic out, in most cases into the
action. An easy clean up could be something like this:

<s:if test="articles != null && articles.size > 0 && user.canViewArticles">

into

<s:if test="showArticleSection()">

It's instantly more readable, and the logic is in a testable Java class.
Following this approach creates a lot of methods in the action, which can
be a problem if you already have...

*Problem 2 - Bloated Action Classes*

When the project was small, it made a lot of sense to create
abstract/parent action classes to share code between actions. As time
passed, we just continued shoving any shared code in one of two "abstract"
classes... even if the code was only being shared between two out of the 20
actions.

The fix for this trend is to moved shared code into services, so we began
enforcing that practice. But this approach had its limitations. We use
Spring injection for all of our services, and some times a particular piece
of logic just required too much stateful input... it just made more sense
to leave it on the action where it had easy access to everything it needed,
as opposed to shoving it in a stateless service and having to pass in a ton
of arguments.

What we really needed was some best practices put in place for the creation
of stateful, non-Spring services.

*Enter JspHelperInceptor

*
It wasn't until after I created this inceptor that I realized it is almost
identical to the ModelDrivenInceptor. At which point, I wondered if that is
what I should actually be using.. but more on that later.

All this interceptor does is push an object onto the value stack. That's
it. Your action implements JspHelperAware which provides Object
getJspHelper(), and the intercept code reads almost line for line with the
ModelDrivenInterceptor.

The idea behind this JspHelper, which is just a POJO that you define, is to
provide a place where all (or most) of the data your JSP needs can be
found. This means that OGNL can find any public members or operations
faster, and also developers can trace back any OGNL expressions in the JSP
to it's corresponding Java code.

This approach places code in a shareable component. You can easily
aggregate one JSPHelper into another one, and then either provide wrapper
methods or simply push the aggregate helper onto the stack using the s:push
tag for direct access to it's members.

This approach makes the actions leaner, and provides a very clear cut view.
I find at times that the action tends to be both controller and view, when
really it should only act as the controller (IMO).

This technique is functionally very similar to ModelDriven, but it's used
slightly differently. I've used a JspHelper in combination with
ModelDriven, and I've found the JspHelper to be a good place to store
logic.. and leave the Model strictly as a business object.

*Conclusion
*
I have personally found this technique incredibly useful in cleaning up
code. You can shift all of the JSP exclusive logic and properties to the
helper without touching the JSP (the OGNL expressions remain the same).
Then after that initial step, you have a real handle on the exact input
your JSP needs, and the actual clean up process progresses faster and with
less errors. I'm still in the process of establishing some best practices,
but so far this approach is working for us.

I would like some honest feedback

Re: JspHelper concept to improve MVC separation

Posted by Mike Menzies <gl...@gmail.com>.
Ya, kinda... for how we use model driven we probably should be using the
scoped version, but that's not the case. We have an abstract action that
handles the validation/refreshing/storing of the model in the session. It's
overkill, but it's heavily unit tested and robust, so we continue using it.


On Mon, Oct 7, 2013 at 4:12 PM, Dave Newton <da...@gmail.com> wrote:

> You mean like ScopedModelDriven?
>
> I'm a big fan of presenters/decorators most of the time, although I'll
> admit I'm also lazy a lot and just use a "real" model and tags :/
>
> Dave
>
>
>
> On Mon, Oct 7, 2013 at 5:08 PM, Mike Menzies <gl...@gmail.com> wrote:
>
> > Hmm.. ya, that makes a lot of sense. I think I will try this approach
> going
> > forward. We sort of bastardize model-driven a little bit by having a
> layer
> > that stores and retrieves the model in the session on every request
> (among
> > other things)... which in most cases is not needed.
> >
> > You've given me some things to think about. Thanks Dave.
> >
> >
> > On Mon, Oct 7, 2013 at 4:00 PM, Dave Newton <da...@gmail.com>
> wrote:
> >
> > > "The" model? "The" model is whatever you want exposed to the view
> layer;
> > > there's nothing that states it has to be the lowest-level domain object
> > > available--it's just "that which you wish exposed to your rendering".
> > >
> > > I don't usually use the built-in validations (for a variety of reasons)
> > so
> > > I'd have to experiment with that to find what I liked.
> > >
> > > Dave
> > >
> > >
> > > On Mon, Oct 7, 2013 at 4:56 PM, Mike Menzies <gl...@gmail.com> wrote:
> > >
> > > > I can see that approach working well. You don't feel that it's
> misusing
> > > > ModelDriven... by not directly returning the model?  Also, if you are
> > > > validating your model, would adding @VisitorFieldValidator to the
> > domain
> > > > getter within the decorator work the same?
> > > >
> > > >
> > > > On Mon, Oct 7, 2013 at 3:43 PM, Dave Newton <da...@gmail.com>
> > > wrote:
> > > >
> > > > > Then I'm not sure I see the point; `ModelDriven` would do the same,
> > but
> > > > > you'd expose the decorator, not the underlying domain object. I
> tend
> > > > > towards the same pattern, but delegate directly to a domain model,
> > so I
> > > > can
> > > > > precisely control access (and document) at the view level.
> > > > >
> > > > > Dave
> > > > >
> > > > >
> > > > >
> > > > > On Mon, Oct 7, 2013 at 4:38 PM, Mike Menzies <gl...@gmail.com>
> > wrote:
> > > > >
> > > > > > Yes. That's pretty much exactly what it is.
> > > > > >
> > > > > >
> > > > > > On Mon, Oct 7, 2013 at 3:35 PM, Dave Newton <
> davelnewton@gmail.com
> > >
> > > > > wrote:
> > > > > >
> > > > > > > So it's a presenter/decorator?
> > > > > > >
> > > > > > > Dave
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > On Mon, Oct 7, 2013 at 4:26 PM, Mike Menzies <glopal@gmail.com
> >
> > > > wrote:
> > > > > > >
> > > > > > > > Hello,
> > > > > > > >
> > > > > > > > My name is Mike, and I work for a fairly large company that
> > uses
> > > > > > Struts 2
> > > > > > > > for most of its web apps. Some of these web apps are quite
> > large,
> > > > and
> > > > > > one
> > > > > > > > in particular has grown into a monster. In my ongoing efforts
> > to
> > > > > clean
> > > > > > up
> > > > > > > > this project, I have developed what I like to call a
> JspHelper.
> > > > > Before
> > > > > > I
> > > > > > > > explain exactly what that is, I'd like to provide you with
> some
> > > > > > examples
> > > > > > > of
> > > > > > > > the problems that I set out to fix.
> > > > > > > >
> > > > > > > > *Problem 1 - Monster JSPs*
> > > > > > > > During early development of this project, struts tags were
> > highly
> > > > > > > > leveraged. I was not involved with the early phases of this
> > > > project,
> > > > > > so I
> > > > > > > > can't speak to why they were used so extensively.. but they
> > were.
> > > > > Tons
> > > > > > of
> > > > > > > > nested if tags that read var tags that were set in the JSP.
> > Some
> > > of
> > > > > > these
> > > > > > > > JSPs were very hard to follow.
> > > > > > > >
> > > > > > > > Even though I am a fan of struts tags, I've come to realize
> > that
> > > > they
> > > > > > > > should not be overused. JSPs cannot be unit tested and JSPs
> are
> > > > hard
> > > > > to
> > > > > > > > debug.
> > > > > > > >
> > > > > > > > So cleaning up a JSP means shifting logic out, in most cases
> > into
> > > > the
> > > > > > > > action. An easy clean up could be something like this:
> > > > > > > >
> > > > > > > > <s:if test="articles != null && articles.size > 0 &&
> > > > > > > user.canViewArticles">
> > > > > > > >
> > > > > > > > into
> > > > > > > >
> > > > > > > > <s:if test="showArticleSection()">
> > > > > > > >
> > > > > > > > It's instantly more readable, and the logic is in a testable
> > Java
> > > > > > class.
> > > > > > > > Following this approach creates a lot of methods in the
> action,
> > > > which
> > > > > > can
> > > > > > > > be a problem if you already have...
> > > > > > > >
> > > > > > > > *Problem 2 - Bloated Action Classes*
> > > > > > > >
> > > > > > > > When the project was small, it made a lot of sense to create
> > > > > > > > abstract/parent action classes to share code between actions.
> > As
> > > > time
> > > > > > > > passed, we just continued shoving any shared code in one of
> two
> > > > > > > "abstract"
> > > > > > > > classes... even if the code was only being shared between two
> > out
> > > > of
> > > > > > the
> > > > > > > 20
> > > > > > > > actions.
> > > > > > > >
> > > > > > > > The fix for this trend is to moved shared code into services,
> > so
> > > we
> > > > > > began
> > > > > > > > enforcing that practice. But this approach had its
> limitations.
> > > We
> > > > > use
> > > > > > > > Spring injection for all of our services, and some times a
> > > > particular
> > > > > > > piece
> > > > > > > > of logic just required too much stateful input... it just
> made
> > > more
> > > > > > sense
> > > > > > > > to leave it on the action where it had easy access to
> > everything
> > > it
> > > > > > > needed,
> > > > > > > > as opposed to shoving it in a stateless service and having to
> > > pass
> > > > > in a
> > > > > > > ton
> > > > > > > > of arguments.
> > > > > > > >
> > > > > > > > What we really needed was some best practices put in place
> for
> > > the
> > > > > > > creation
> > > > > > > > of stateful, non-Spring services.
> > > > > > > >
> > > > > > > > *Enter JspHelperInceptor
> > > > > > > >
> > > > > > > > *
> > > > > > > > It wasn't until after I created this inceptor that I realized
> > it
> > > is
> > > > > > > almost
> > > > > > > > identical to the ModelDrivenInceptor. At which point, I
> > wondered
> > > if
> > > > > > that
> > > > > > > is
> > > > > > > > what I should actually be using.. but more on that later.
> > > > > > > >
> > > > > > > > All this interceptor does is push an object onto the value
> > stack.
> > > > > > That's
> > > > > > > > it. Your action implements JspHelperAware which provides
> Object
> > > > > > > > getJspHelper(), and the intercept code reads almost line for
> > line
> > > > > with
> > > > > > > the
> > > > > > > > ModelDrivenInterceptor.
> > > > > > > >
> > > > > > > > The idea behind this JspHelper, which is just a POJO that you
> > > > define,
> > > > > > is
> > > > > > > to
> > > > > > > > provide a place where all (or most) of the data your JSP
> needs
> > > can
> > > > be
> > > > > > > > found. This means that OGNL can find any public members or
> > > > operations
> > > > > > > > faster, and also developers can trace back any OGNL
> expressions
> > > in
> > > > > the
> > > > > > > JSP
> > > > > > > > to it's corresponding Java code.
> > > > > > > >
> > > > > > > > This approach places code in a shareable component. You can
> > > easily
> > > > > > > > aggregate one JSPHelper into another one, and then either
> > provide
> > > > > > wrapper
> > > > > > > > methods or simply push the aggregate helper onto the stack
> > using
> > > > the
> > > > > > > s:push
> > > > > > > > tag for direct access to it's members.
> > > > > > > >
> > > > > > > > This approach makes the actions leaner, and provides a very
> > clear
> > > > cut
> > > > > > > view.
> > > > > > > > I find at times that the action tends to be both controller
> and
> > > > view,
> > > > > > > when
> > > > > > > > really it should only act as the controller (IMO).
> > > > > > > >
> > > > > > > > This technique is functionally very similar to ModelDriven,
> but
> > > > it's
> > > > > > used
> > > > > > > > slightly differently. I've used a JspHelper in combination
> with
> > > > > > > > ModelDriven, and I've found the JspHelper to be a good place
> to
> > > > store
> > > > > > > > logic.. and leave the Model strictly as a business object.
> > > > > > > >
> > > > > > > > *Conclusion
> > > > > > > > *
> > > > > > > > I have personally found this technique incredibly useful in
> > > > cleaning
> > > > > up
> > > > > > > > code. You can shift all of the JSP exclusive logic and
> > properties
> > > > to
> > > > > > the
> > > > > > > > helper without touching the JSP (the OGNL expressions remain
> > the
> > > > > same).
> > > > > > > > Then after that initial step, you have a real handle on the
> > exact
> > > > > input
> > > > > > > > your JSP needs, and the actual clean up process progresses
> > faster
> > > > and
> > > > > > > with
> > > > > > > > less errors. I'm still in the process of establishing some
> best
> > > > > > > practices,
> > > > > > > > but so far this approach is working for us.
> > > > > > > >
> > > > > > > > I would like some honest feedback
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > --
> > > > > > > e: davelnewton@gmail.com
> > > > > > > m: 908-380-8699
> > > > > > > s: davelnewton_skype
> > > > > > > t: @dave_newton <https://twitter.com/dave_newton>
> > > > > > > b: Bucky Bits <http://buckybits.blogspot.com/>
> > > > > > > g: davelnewton <https://github.com/davelnewton>
> > > > > > > so: Dave Newton <
> > http://stackoverflow.com/users/438992/dave-newton
> > > >
> > > > > > >
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > e: davelnewton@gmail.com
> > > > > m: 908-380-8699
> > > > > s: davelnewton_skype
> > > > > t: @dave_newton <https://twitter.com/dave_newton>
> > > > > b: Bucky Bits <http://buckybits.blogspot.com/>
> > > > > g: davelnewton <https://github.com/davelnewton>
> > > > > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton
> >
> > > > >
> > > >
> > >
> > >
> > >
> > > --
> > > e: davelnewton@gmail.com
> > > m: 908-380-8699
> > > s: davelnewton_skype
> > > t: @dave_newton <https://twitter.com/dave_newton>
> > > b: Bucky Bits <http://buckybits.blogspot.com/>
> > > g: davelnewton <https://github.com/davelnewton>
> > > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
> > >
> >
>
>
>
> --
> e: davelnewton@gmail.com
> m: 908-380-8699
> s: davelnewton_skype
> t: @dave_newton <https://twitter.com/dave_newton>
> b: Bucky Bits <http://buckybits.blogspot.com/>
> g: davelnewton <https://github.com/davelnewton>
> so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
>

Re: JspHelper concept to improve MVC separation

Posted by Dave Newton <da...@gmail.com>.
You mean like ScopedModelDriven?

I'm a big fan of presenters/decorators most of the time, although I'll
admit I'm also lazy a lot and just use a "real" model and tags :/

Dave



On Mon, Oct 7, 2013 at 5:08 PM, Mike Menzies <gl...@gmail.com> wrote:

> Hmm.. ya, that makes a lot of sense. I think I will try this approach going
> forward. We sort of bastardize model-driven a little bit by having a layer
> that stores and retrieves the model in the session on every request (among
> other things)... which in most cases is not needed.
>
> You've given me some things to think about. Thanks Dave.
>
>
> On Mon, Oct 7, 2013 at 4:00 PM, Dave Newton <da...@gmail.com> wrote:
>
> > "The" model? "The" model is whatever you want exposed to the view layer;
> > there's nothing that states it has to be the lowest-level domain object
> > available--it's just "that which you wish exposed to your rendering".
> >
> > I don't usually use the built-in validations (for a variety of reasons)
> so
> > I'd have to experiment with that to find what I liked.
> >
> > Dave
> >
> >
> > On Mon, Oct 7, 2013 at 4:56 PM, Mike Menzies <gl...@gmail.com> wrote:
> >
> > > I can see that approach working well. You don't feel that it's misusing
> > > ModelDriven... by not directly returning the model?  Also, if you are
> > > validating your model, would adding @VisitorFieldValidator to the
> domain
> > > getter within the decorator work the same?
> > >
> > >
> > > On Mon, Oct 7, 2013 at 3:43 PM, Dave Newton <da...@gmail.com>
> > wrote:
> > >
> > > > Then I'm not sure I see the point; `ModelDriven` would do the same,
> but
> > > > you'd expose the decorator, not the underlying domain object. I tend
> > > > towards the same pattern, but delegate directly to a domain model,
> so I
> > > can
> > > > precisely control access (and document) at the view level.
> > > >
> > > > Dave
> > > >
> > > >
> > > >
> > > > On Mon, Oct 7, 2013 at 4:38 PM, Mike Menzies <gl...@gmail.com>
> wrote:
> > > >
> > > > > Yes. That's pretty much exactly what it is.
> > > > >
> > > > >
> > > > > On Mon, Oct 7, 2013 at 3:35 PM, Dave Newton <davelnewton@gmail.com
> >
> > > > wrote:
> > > > >
> > > > > > So it's a presenter/decorator?
> > > > > >
> > > > > > Dave
> > > > > >
> > > > > >
> > > > > >
> > > > > > On Mon, Oct 7, 2013 at 4:26 PM, Mike Menzies <gl...@gmail.com>
> > > wrote:
> > > > > >
> > > > > > > Hello,
> > > > > > >
> > > > > > > My name is Mike, and I work for a fairly large company that
> uses
> > > > > Struts 2
> > > > > > > for most of its web apps. Some of these web apps are quite
> large,
> > > and
> > > > > one
> > > > > > > in particular has grown into a monster. In my ongoing efforts
> to
> > > > clean
> > > > > up
> > > > > > > this project, I have developed what I like to call a JspHelper.
> > > > Before
> > > > > I
> > > > > > > explain exactly what that is, I'd like to provide you with some
> > > > > examples
> > > > > > of
> > > > > > > the problems that I set out to fix.
> > > > > > >
> > > > > > > *Problem 1 - Monster JSPs*
> > > > > > > During early development of this project, struts tags were
> highly
> > > > > > > leveraged. I was not involved with the early phases of this
> > > project,
> > > > > so I
> > > > > > > can't speak to why they were used so extensively.. but they
> were.
> > > > Tons
> > > > > of
> > > > > > > nested if tags that read var tags that were set in the JSP.
> Some
> > of
> > > > > these
> > > > > > > JSPs were very hard to follow.
> > > > > > >
> > > > > > > Even though I am a fan of struts tags, I've come to realize
> that
> > > they
> > > > > > > should not be overused. JSPs cannot be unit tested and JSPs are
> > > hard
> > > > to
> > > > > > > debug.
> > > > > > >
> > > > > > > So cleaning up a JSP means shifting logic out, in most cases
> into
> > > the
> > > > > > > action. An easy clean up could be something like this:
> > > > > > >
> > > > > > > <s:if test="articles != null && articles.size > 0 &&
> > > > > > user.canViewArticles">
> > > > > > >
> > > > > > > into
> > > > > > >
> > > > > > > <s:if test="showArticleSection()">
> > > > > > >
> > > > > > > It's instantly more readable, and the logic is in a testable
> Java
> > > > > class.
> > > > > > > Following this approach creates a lot of methods in the action,
> > > which
> > > > > can
> > > > > > > be a problem if you already have...
> > > > > > >
> > > > > > > *Problem 2 - Bloated Action Classes*
> > > > > > >
> > > > > > > When the project was small, it made a lot of sense to create
> > > > > > > abstract/parent action classes to share code between actions.
> As
> > > time
> > > > > > > passed, we just continued shoving any shared code in one of two
> > > > > > "abstract"
> > > > > > > classes... even if the code was only being shared between two
> out
> > > of
> > > > > the
> > > > > > 20
> > > > > > > actions.
> > > > > > >
> > > > > > > The fix for this trend is to moved shared code into services,
> so
> > we
> > > > > began
> > > > > > > enforcing that practice. But this approach had its limitations.
> > We
> > > > use
> > > > > > > Spring injection for all of our services, and some times a
> > > particular
> > > > > > piece
> > > > > > > of logic just required too much stateful input... it just made
> > more
> > > > > sense
> > > > > > > to leave it on the action where it had easy access to
> everything
> > it
> > > > > > needed,
> > > > > > > as opposed to shoving it in a stateless service and having to
> > pass
> > > > in a
> > > > > > ton
> > > > > > > of arguments.
> > > > > > >
> > > > > > > What we really needed was some best practices put in place for
> > the
> > > > > > creation
> > > > > > > of stateful, non-Spring services.
> > > > > > >
> > > > > > > *Enter JspHelperInceptor
> > > > > > >
> > > > > > > *
> > > > > > > It wasn't until after I created this inceptor that I realized
> it
> > is
> > > > > > almost
> > > > > > > identical to the ModelDrivenInceptor. At which point, I
> wondered
> > if
> > > > > that
> > > > > > is
> > > > > > > what I should actually be using.. but more on that later.
> > > > > > >
> > > > > > > All this interceptor does is push an object onto the value
> stack.
> > > > > That's
> > > > > > > it. Your action implements JspHelperAware which provides Object
> > > > > > > getJspHelper(), and the intercept code reads almost line for
> line
> > > > with
> > > > > > the
> > > > > > > ModelDrivenInterceptor.
> > > > > > >
> > > > > > > The idea behind this JspHelper, which is just a POJO that you
> > > define,
> > > > > is
> > > > > > to
> > > > > > > provide a place where all (or most) of the data your JSP needs
> > can
> > > be
> > > > > > > found. This means that OGNL can find any public members or
> > > operations
> > > > > > > faster, and also developers can trace back any OGNL expressions
> > in
> > > > the
> > > > > > JSP
> > > > > > > to it's corresponding Java code.
> > > > > > >
> > > > > > > This approach places code in a shareable component. You can
> > easily
> > > > > > > aggregate one JSPHelper into another one, and then either
> provide
> > > > > wrapper
> > > > > > > methods or simply push the aggregate helper onto the stack
> using
> > > the
> > > > > > s:push
> > > > > > > tag for direct access to it's members.
> > > > > > >
> > > > > > > This approach makes the actions leaner, and provides a very
> clear
> > > cut
> > > > > > view.
> > > > > > > I find at times that the action tends to be both controller and
> > > view,
> > > > > > when
> > > > > > > really it should only act as the controller (IMO).
> > > > > > >
> > > > > > > This technique is functionally very similar to ModelDriven, but
> > > it's
> > > > > used
> > > > > > > slightly differently. I've used a JspHelper in combination with
> > > > > > > ModelDriven, and I've found the JspHelper to be a good place to
> > > store
> > > > > > > logic.. and leave the Model strictly as a business object.
> > > > > > >
> > > > > > > *Conclusion
> > > > > > > *
> > > > > > > I have personally found this technique incredibly useful in
> > > cleaning
> > > > up
> > > > > > > code. You can shift all of the JSP exclusive logic and
> properties
> > > to
> > > > > the
> > > > > > > helper without touching the JSP (the OGNL expressions remain
> the
> > > > same).
> > > > > > > Then after that initial step, you have a real handle on the
> exact
> > > > input
> > > > > > > your JSP needs, and the actual clean up process progresses
> faster
> > > and
> > > > > > with
> > > > > > > less errors. I'm still in the process of establishing some best
> > > > > > practices,
> > > > > > > but so far this approach is working for us.
> > > > > > >
> > > > > > > I would like some honest feedback
> > > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > --
> > > > > > e: davelnewton@gmail.com
> > > > > > m: 908-380-8699
> > > > > > s: davelnewton_skype
> > > > > > t: @dave_newton <https://twitter.com/dave_newton>
> > > > > > b: Bucky Bits <http://buckybits.blogspot.com/>
> > > > > > g: davelnewton <https://github.com/davelnewton>
> > > > > > so: Dave Newton <
> http://stackoverflow.com/users/438992/dave-newton
> > >
> > > > > >
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > e: davelnewton@gmail.com
> > > > m: 908-380-8699
> > > > s: davelnewton_skype
> > > > t: @dave_newton <https://twitter.com/dave_newton>
> > > > b: Bucky Bits <http://buckybits.blogspot.com/>
> > > > g: davelnewton <https://github.com/davelnewton>
> > > > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
> > > >
> > >
> >
> >
> >
> > --
> > e: davelnewton@gmail.com
> > m: 908-380-8699
> > s: davelnewton_skype
> > t: @dave_newton <https://twitter.com/dave_newton>
> > b: Bucky Bits <http://buckybits.blogspot.com/>
> > g: davelnewton <https://github.com/davelnewton>
> > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
> >
>



-- 
e: davelnewton@gmail.com
m: 908-380-8699
s: davelnewton_skype
t: @dave_newton <https://twitter.com/dave_newton>
b: Bucky Bits <http://buckybits.blogspot.com/>
g: davelnewton <https://github.com/davelnewton>
so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>

Re: JspHelper concept to improve MVC separation

Posted by Mike Menzies <gl...@gmail.com>.
Hmm.. ya, that makes a lot of sense. I think I will try this approach going
forward. We sort of bastardize model-driven a little bit by having a layer
that stores and retrieves the model in the session on every request (among
other things)... which in most cases is not needed.

You've given me some things to think about. Thanks Dave.


On Mon, Oct 7, 2013 at 4:00 PM, Dave Newton <da...@gmail.com> wrote:

> "The" model? "The" model is whatever you want exposed to the view layer;
> there's nothing that states it has to be the lowest-level domain object
> available--it's just "that which you wish exposed to your rendering".
>
> I don't usually use the built-in validations (for a variety of reasons) so
> I'd have to experiment with that to find what I liked.
>
> Dave
>
>
> On Mon, Oct 7, 2013 at 4:56 PM, Mike Menzies <gl...@gmail.com> wrote:
>
> > I can see that approach working well. You don't feel that it's misusing
> > ModelDriven... by not directly returning the model?  Also, if you are
> > validating your model, would adding @VisitorFieldValidator to the domain
> > getter within the decorator work the same?
> >
> >
> > On Mon, Oct 7, 2013 at 3:43 PM, Dave Newton <da...@gmail.com>
> wrote:
> >
> > > Then I'm not sure I see the point; `ModelDriven` would do the same, but
> > > you'd expose the decorator, not the underlying domain object. I tend
> > > towards the same pattern, but delegate directly to a domain model, so I
> > can
> > > precisely control access (and document) at the view level.
> > >
> > > Dave
> > >
> > >
> > >
> > > On Mon, Oct 7, 2013 at 4:38 PM, Mike Menzies <gl...@gmail.com> wrote:
> > >
> > > > Yes. That's pretty much exactly what it is.
> > > >
> > > >
> > > > On Mon, Oct 7, 2013 at 3:35 PM, Dave Newton <da...@gmail.com>
> > > wrote:
> > > >
> > > > > So it's a presenter/decorator?
> > > > >
> > > > > Dave
> > > > >
> > > > >
> > > > >
> > > > > On Mon, Oct 7, 2013 at 4:26 PM, Mike Menzies <gl...@gmail.com>
> > wrote:
> > > > >
> > > > > > Hello,
> > > > > >
> > > > > > My name is Mike, and I work for a fairly large company that uses
> > > > Struts 2
> > > > > > for most of its web apps. Some of these web apps are quite large,
> > and
> > > > one
> > > > > > in particular has grown into a monster. In my ongoing efforts to
> > > clean
> > > > up
> > > > > > this project, I have developed what I like to call a JspHelper.
> > > Before
> > > > I
> > > > > > explain exactly what that is, I'd like to provide you with some
> > > > examples
> > > > > of
> > > > > > the problems that I set out to fix.
> > > > > >
> > > > > > *Problem 1 - Monster JSPs*
> > > > > > During early development of this project, struts tags were highly
> > > > > > leveraged. I was not involved with the early phases of this
> > project,
> > > > so I
> > > > > > can't speak to why they were used so extensively.. but they were.
> > > Tons
> > > > of
> > > > > > nested if tags that read var tags that were set in the JSP. Some
> of
> > > > these
> > > > > > JSPs were very hard to follow.
> > > > > >
> > > > > > Even though I am a fan of struts tags, I've come to realize that
> > they
> > > > > > should not be overused. JSPs cannot be unit tested and JSPs are
> > hard
> > > to
> > > > > > debug.
> > > > > >
> > > > > > So cleaning up a JSP means shifting logic out, in most cases into
> > the
> > > > > > action. An easy clean up could be something like this:
> > > > > >
> > > > > > <s:if test="articles != null && articles.size > 0 &&
> > > > > user.canViewArticles">
> > > > > >
> > > > > > into
> > > > > >
> > > > > > <s:if test="showArticleSection()">
> > > > > >
> > > > > > It's instantly more readable, and the logic is in a testable Java
> > > > class.
> > > > > > Following this approach creates a lot of methods in the action,
> > which
> > > > can
> > > > > > be a problem if you already have...
> > > > > >
> > > > > > *Problem 2 - Bloated Action Classes*
> > > > > >
> > > > > > When the project was small, it made a lot of sense to create
> > > > > > abstract/parent action classes to share code between actions. As
> > time
> > > > > > passed, we just continued shoving any shared code in one of two
> > > > > "abstract"
> > > > > > classes... even if the code was only being shared between two out
> > of
> > > > the
> > > > > 20
> > > > > > actions.
> > > > > >
> > > > > > The fix for this trend is to moved shared code into services, so
> we
> > > > began
> > > > > > enforcing that practice. But this approach had its limitations.
> We
> > > use
> > > > > > Spring injection for all of our services, and some times a
> > particular
> > > > > piece
> > > > > > of logic just required too much stateful input... it just made
> more
> > > > sense
> > > > > > to leave it on the action where it had easy access to everything
> it
> > > > > needed,
> > > > > > as opposed to shoving it in a stateless service and having to
> pass
> > > in a
> > > > > ton
> > > > > > of arguments.
> > > > > >
> > > > > > What we really needed was some best practices put in place for
> the
> > > > > creation
> > > > > > of stateful, non-Spring services.
> > > > > >
> > > > > > *Enter JspHelperInceptor
> > > > > >
> > > > > > *
> > > > > > It wasn't until after I created this inceptor that I realized it
> is
> > > > > almost
> > > > > > identical to the ModelDrivenInceptor. At which point, I wondered
> if
> > > > that
> > > > > is
> > > > > > what I should actually be using.. but more on that later.
> > > > > >
> > > > > > All this interceptor does is push an object onto the value stack.
> > > > That's
> > > > > > it. Your action implements JspHelperAware which provides Object
> > > > > > getJspHelper(), and the intercept code reads almost line for line
> > > with
> > > > > the
> > > > > > ModelDrivenInterceptor.
> > > > > >
> > > > > > The idea behind this JspHelper, which is just a POJO that you
> > define,
> > > > is
> > > > > to
> > > > > > provide a place where all (or most) of the data your JSP needs
> can
> > be
> > > > > > found. This means that OGNL can find any public members or
> > operations
> > > > > > faster, and also developers can trace back any OGNL expressions
> in
> > > the
> > > > > JSP
> > > > > > to it's corresponding Java code.
> > > > > >
> > > > > > This approach places code in a shareable component. You can
> easily
> > > > > > aggregate one JSPHelper into another one, and then either provide
> > > > wrapper
> > > > > > methods or simply push the aggregate helper onto the stack using
> > the
> > > > > s:push
> > > > > > tag for direct access to it's members.
> > > > > >
> > > > > > This approach makes the actions leaner, and provides a very clear
> > cut
> > > > > view.
> > > > > > I find at times that the action tends to be both controller and
> > view,
> > > > > when
> > > > > > really it should only act as the controller (IMO).
> > > > > >
> > > > > > This technique is functionally very similar to ModelDriven, but
> > it's
> > > > used
> > > > > > slightly differently. I've used a JspHelper in combination with
> > > > > > ModelDriven, and I've found the JspHelper to be a good place to
> > store
> > > > > > logic.. and leave the Model strictly as a business object.
> > > > > >
> > > > > > *Conclusion
> > > > > > *
> > > > > > I have personally found this technique incredibly useful in
> > cleaning
> > > up
> > > > > > code. You can shift all of the JSP exclusive logic and properties
> > to
> > > > the
> > > > > > helper without touching the JSP (the OGNL expressions remain the
> > > same).
> > > > > > Then after that initial step, you have a real handle on the exact
> > > input
> > > > > > your JSP needs, and the actual clean up process progresses faster
> > and
> > > > > with
> > > > > > less errors. I'm still in the process of establishing some best
> > > > > practices,
> > > > > > but so far this approach is working for us.
> > > > > >
> > > > > > I would like some honest feedback
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > e: davelnewton@gmail.com
> > > > > m: 908-380-8699
> > > > > s: davelnewton_skype
> > > > > t: @dave_newton <https://twitter.com/dave_newton>
> > > > > b: Bucky Bits <http://buckybits.blogspot.com/>
> > > > > g: davelnewton <https://github.com/davelnewton>
> > > > > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton
> >
> > > > >
> > > >
> > >
> > >
> > >
> > > --
> > > e: davelnewton@gmail.com
> > > m: 908-380-8699
> > > s: davelnewton_skype
> > > t: @dave_newton <https://twitter.com/dave_newton>
> > > b: Bucky Bits <http://buckybits.blogspot.com/>
> > > g: davelnewton <https://github.com/davelnewton>
> > > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
> > >
> >
>
>
>
> --
> e: davelnewton@gmail.com
> m: 908-380-8699
> s: davelnewton_skype
> t: @dave_newton <https://twitter.com/dave_newton>
> b: Bucky Bits <http://buckybits.blogspot.com/>
> g: davelnewton <https://github.com/davelnewton>
> so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
>

Re: JspHelper concept to improve MVC separation

Posted by Dave Newton <da...@gmail.com>.
"The" model? "The" model is whatever you want exposed to the view layer;
there's nothing that states it has to be the lowest-level domain object
available--it's just "that which you wish exposed to your rendering".

I don't usually use the built-in validations (for a variety of reasons) so
I'd have to experiment with that to find what I liked.

Dave


On Mon, Oct 7, 2013 at 4:56 PM, Mike Menzies <gl...@gmail.com> wrote:

> I can see that approach working well. You don't feel that it's misusing
> ModelDriven... by not directly returning the model?  Also, if you are
> validating your model, would adding @VisitorFieldValidator to the domain
> getter within the decorator work the same?
>
>
> On Mon, Oct 7, 2013 at 3:43 PM, Dave Newton <da...@gmail.com> wrote:
>
> > Then I'm not sure I see the point; `ModelDriven` would do the same, but
> > you'd expose the decorator, not the underlying domain object. I tend
> > towards the same pattern, but delegate directly to a domain model, so I
> can
> > precisely control access (and document) at the view level.
> >
> > Dave
> >
> >
> >
> > On Mon, Oct 7, 2013 at 4:38 PM, Mike Menzies <gl...@gmail.com> wrote:
> >
> > > Yes. That's pretty much exactly what it is.
> > >
> > >
> > > On Mon, Oct 7, 2013 at 3:35 PM, Dave Newton <da...@gmail.com>
> > wrote:
> > >
> > > > So it's a presenter/decorator?
> > > >
> > > > Dave
> > > >
> > > >
> > > >
> > > > On Mon, Oct 7, 2013 at 4:26 PM, Mike Menzies <gl...@gmail.com>
> wrote:
> > > >
> > > > > Hello,
> > > > >
> > > > > My name is Mike, and I work for a fairly large company that uses
> > > Struts 2
> > > > > for most of its web apps. Some of these web apps are quite large,
> and
> > > one
> > > > > in particular has grown into a monster. In my ongoing efforts to
> > clean
> > > up
> > > > > this project, I have developed what I like to call a JspHelper.
> > Before
> > > I
> > > > > explain exactly what that is, I'd like to provide you with some
> > > examples
> > > > of
> > > > > the problems that I set out to fix.
> > > > >
> > > > > *Problem 1 - Monster JSPs*
> > > > > During early development of this project, struts tags were highly
> > > > > leveraged. I was not involved with the early phases of this
> project,
> > > so I
> > > > > can't speak to why they were used so extensively.. but they were.
> > Tons
> > > of
> > > > > nested if tags that read var tags that were set in the JSP. Some of
> > > these
> > > > > JSPs were very hard to follow.
> > > > >
> > > > > Even though I am a fan of struts tags, I've come to realize that
> they
> > > > > should not be overused. JSPs cannot be unit tested and JSPs are
> hard
> > to
> > > > > debug.
> > > > >
> > > > > So cleaning up a JSP means shifting logic out, in most cases into
> the
> > > > > action. An easy clean up could be something like this:
> > > > >
> > > > > <s:if test="articles != null && articles.size > 0 &&
> > > > user.canViewArticles">
> > > > >
> > > > > into
> > > > >
> > > > > <s:if test="showArticleSection()">
> > > > >
> > > > > It's instantly more readable, and the logic is in a testable Java
> > > class.
> > > > > Following this approach creates a lot of methods in the action,
> which
> > > can
> > > > > be a problem if you already have...
> > > > >
> > > > > *Problem 2 - Bloated Action Classes*
> > > > >
> > > > > When the project was small, it made a lot of sense to create
> > > > > abstract/parent action classes to share code between actions. As
> time
> > > > > passed, we just continued shoving any shared code in one of two
> > > > "abstract"
> > > > > classes... even if the code was only being shared between two out
> of
> > > the
> > > > 20
> > > > > actions.
> > > > >
> > > > > The fix for this trend is to moved shared code into services, so we
> > > began
> > > > > enforcing that practice. But this approach had its limitations. We
> > use
> > > > > Spring injection for all of our services, and some times a
> particular
> > > > piece
> > > > > of logic just required too much stateful input... it just made more
> > > sense
> > > > > to leave it on the action where it had easy access to everything it
> > > > needed,
> > > > > as opposed to shoving it in a stateless service and having to pass
> > in a
> > > > ton
> > > > > of arguments.
> > > > >
> > > > > What we really needed was some best practices put in place for the
> > > > creation
> > > > > of stateful, non-Spring services.
> > > > >
> > > > > *Enter JspHelperInceptor
> > > > >
> > > > > *
> > > > > It wasn't until after I created this inceptor that I realized it is
> > > > almost
> > > > > identical to the ModelDrivenInceptor. At which point, I wondered if
> > > that
> > > > is
> > > > > what I should actually be using.. but more on that later.
> > > > >
> > > > > All this interceptor does is push an object onto the value stack.
> > > That's
> > > > > it. Your action implements JspHelperAware which provides Object
> > > > > getJspHelper(), and the intercept code reads almost line for line
> > with
> > > > the
> > > > > ModelDrivenInterceptor.
> > > > >
> > > > > The idea behind this JspHelper, which is just a POJO that you
> define,
> > > is
> > > > to
> > > > > provide a place where all (or most) of the data your JSP needs can
> be
> > > > > found. This means that OGNL can find any public members or
> operations
> > > > > faster, and also developers can trace back any OGNL expressions in
> > the
> > > > JSP
> > > > > to it's corresponding Java code.
> > > > >
> > > > > This approach places code in a shareable component. You can easily
> > > > > aggregate one JSPHelper into another one, and then either provide
> > > wrapper
> > > > > methods or simply push the aggregate helper onto the stack using
> the
> > > > s:push
> > > > > tag for direct access to it's members.
> > > > >
> > > > > This approach makes the actions leaner, and provides a very clear
> cut
> > > > view.
> > > > > I find at times that the action tends to be both controller and
> view,
> > > > when
> > > > > really it should only act as the controller (IMO).
> > > > >
> > > > > This technique is functionally very similar to ModelDriven, but
> it's
> > > used
> > > > > slightly differently. I've used a JspHelper in combination with
> > > > > ModelDriven, and I've found the JspHelper to be a good place to
> store
> > > > > logic.. and leave the Model strictly as a business object.
> > > > >
> > > > > *Conclusion
> > > > > *
> > > > > I have personally found this technique incredibly useful in
> cleaning
> > up
> > > > > code. You can shift all of the JSP exclusive logic and properties
> to
> > > the
> > > > > helper without touching the JSP (the OGNL expressions remain the
> > same).
> > > > > Then after that initial step, you have a real handle on the exact
> > input
> > > > > your JSP needs, and the actual clean up process progresses faster
> and
> > > > with
> > > > > less errors. I'm still in the process of establishing some best
> > > > practices,
> > > > > but so far this approach is working for us.
> > > > >
> > > > > I would like some honest feedback
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > e: davelnewton@gmail.com
> > > > m: 908-380-8699
> > > > s: davelnewton_skype
> > > > t: @dave_newton <https://twitter.com/dave_newton>
> > > > b: Bucky Bits <http://buckybits.blogspot.com/>
> > > > g: davelnewton <https://github.com/davelnewton>
> > > > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
> > > >
> > >
> >
> >
> >
> > --
> > e: davelnewton@gmail.com
> > m: 908-380-8699
> > s: davelnewton_skype
> > t: @dave_newton <https://twitter.com/dave_newton>
> > b: Bucky Bits <http://buckybits.blogspot.com/>
> > g: davelnewton <https://github.com/davelnewton>
> > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
> >
>



-- 
e: davelnewton@gmail.com
m: 908-380-8699
s: davelnewton_skype
t: @dave_newton <https://twitter.com/dave_newton>
b: Bucky Bits <http://buckybits.blogspot.com/>
g: davelnewton <https://github.com/davelnewton>
so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>

Re: JspHelper concept to improve MVC separation

Posted by Mike Menzies <gl...@gmail.com>.
I can see that approach working well. You don't feel that it's misusing
ModelDriven... by not directly returning the model?  Also, if you are
validating your model, would adding @VisitorFieldValidator to the domain
getter within the decorator work the same?


On Mon, Oct 7, 2013 at 3:43 PM, Dave Newton <da...@gmail.com> wrote:

> Then I'm not sure I see the point; `ModelDriven` would do the same, but
> you'd expose the decorator, not the underlying domain object. I tend
> towards the same pattern, but delegate directly to a domain model, so I can
> precisely control access (and document) at the view level.
>
> Dave
>
>
>
> On Mon, Oct 7, 2013 at 4:38 PM, Mike Menzies <gl...@gmail.com> wrote:
>
> > Yes. That's pretty much exactly what it is.
> >
> >
> > On Mon, Oct 7, 2013 at 3:35 PM, Dave Newton <da...@gmail.com>
> wrote:
> >
> > > So it's a presenter/decorator?
> > >
> > > Dave
> > >
> > >
> > >
> > > On Mon, Oct 7, 2013 at 4:26 PM, Mike Menzies <gl...@gmail.com> wrote:
> > >
> > > > Hello,
> > > >
> > > > My name is Mike, and I work for a fairly large company that uses
> > Struts 2
> > > > for most of its web apps. Some of these web apps are quite large, and
> > one
> > > > in particular has grown into a monster. In my ongoing efforts to
> clean
> > up
> > > > this project, I have developed what I like to call a JspHelper.
> Before
> > I
> > > > explain exactly what that is, I'd like to provide you with some
> > examples
> > > of
> > > > the problems that I set out to fix.
> > > >
> > > > *Problem 1 - Monster JSPs*
> > > > During early development of this project, struts tags were highly
> > > > leveraged. I was not involved with the early phases of this project,
> > so I
> > > > can't speak to why they were used so extensively.. but they were.
> Tons
> > of
> > > > nested if tags that read var tags that were set in the JSP. Some of
> > these
> > > > JSPs were very hard to follow.
> > > >
> > > > Even though I am a fan of struts tags, I've come to realize that they
> > > > should not be overused. JSPs cannot be unit tested and JSPs are hard
> to
> > > > debug.
> > > >
> > > > So cleaning up a JSP means shifting logic out, in most cases into the
> > > > action. An easy clean up could be something like this:
> > > >
> > > > <s:if test="articles != null && articles.size > 0 &&
> > > user.canViewArticles">
> > > >
> > > > into
> > > >
> > > > <s:if test="showArticleSection()">
> > > >
> > > > It's instantly more readable, and the logic is in a testable Java
> > class.
> > > > Following this approach creates a lot of methods in the action, which
> > can
> > > > be a problem if you already have...
> > > >
> > > > *Problem 2 - Bloated Action Classes*
> > > >
> > > > When the project was small, it made a lot of sense to create
> > > > abstract/parent action classes to share code between actions. As time
> > > > passed, we just continued shoving any shared code in one of two
> > > "abstract"
> > > > classes... even if the code was only being shared between two out of
> > the
> > > 20
> > > > actions.
> > > >
> > > > The fix for this trend is to moved shared code into services, so we
> > began
> > > > enforcing that practice. But this approach had its limitations. We
> use
> > > > Spring injection for all of our services, and some times a particular
> > > piece
> > > > of logic just required too much stateful input... it just made more
> > sense
> > > > to leave it on the action where it had easy access to everything it
> > > needed,
> > > > as opposed to shoving it in a stateless service and having to pass
> in a
> > > ton
> > > > of arguments.
> > > >
> > > > What we really needed was some best practices put in place for the
> > > creation
> > > > of stateful, non-Spring services.
> > > >
> > > > *Enter JspHelperInceptor
> > > >
> > > > *
> > > > It wasn't until after I created this inceptor that I realized it is
> > > almost
> > > > identical to the ModelDrivenInceptor. At which point, I wondered if
> > that
> > > is
> > > > what I should actually be using.. but more on that later.
> > > >
> > > > All this interceptor does is push an object onto the value stack.
> > That's
> > > > it. Your action implements JspHelperAware which provides Object
> > > > getJspHelper(), and the intercept code reads almost line for line
> with
> > > the
> > > > ModelDrivenInterceptor.
> > > >
> > > > The idea behind this JspHelper, which is just a POJO that you define,
> > is
> > > to
> > > > provide a place where all (or most) of the data your JSP needs can be
> > > > found. This means that OGNL can find any public members or operations
> > > > faster, and also developers can trace back any OGNL expressions in
> the
> > > JSP
> > > > to it's corresponding Java code.
> > > >
> > > > This approach places code in a shareable component. You can easily
> > > > aggregate one JSPHelper into another one, and then either provide
> > wrapper
> > > > methods or simply push the aggregate helper onto the stack using the
> > > s:push
> > > > tag for direct access to it's members.
> > > >
> > > > This approach makes the actions leaner, and provides a very clear cut
> > > view.
> > > > I find at times that the action tends to be both controller and view,
> > > when
> > > > really it should only act as the controller (IMO).
> > > >
> > > > This technique is functionally very similar to ModelDriven, but it's
> > used
> > > > slightly differently. I've used a JspHelper in combination with
> > > > ModelDriven, and I've found the JspHelper to be a good place to store
> > > > logic.. and leave the Model strictly as a business object.
> > > >
> > > > *Conclusion
> > > > *
> > > > I have personally found this technique incredibly useful in cleaning
> up
> > > > code. You can shift all of the JSP exclusive logic and properties to
> > the
> > > > helper without touching the JSP (the OGNL expressions remain the
> same).
> > > > Then after that initial step, you have a real handle on the exact
> input
> > > > your JSP needs, and the actual clean up process progresses faster and
> > > with
> > > > less errors. I'm still in the process of establishing some best
> > > practices,
> > > > but so far this approach is working for us.
> > > >
> > > > I would like some honest feedback
> > > >
> > >
> > >
> > >
> > > --
> > > e: davelnewton@gmail.com
> > > m: 908-380-8699
> > > s: davelnewton_skype
> > > t: @dave_newton <https://twitter.com/dave_newton>
> > > b: Bucky Bits <http://buckybits.blogspot.com/>
> > > g: davelnewton <https://github.com/davelnewton>
> > > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
> > >
> >
>
>
>
> --
> e: davelnewton@gmail.com
> m: 908-380-8699
> s: davelnewton_skype
> t: @dave_newton <https://twitter.com/dave_newton>
> b: Bucky Bits <http://buckybits.blogspot.com/>
> g: davelnewton <https://github.com/davelnewton>
> so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
>

Re: JspHelper concept to improve MVC separation

Posted by Dave Newton <da...@gmail.com>.
Then I'm not sure I see the point; `ModelDriven` would do the same, but
you'd expose the decorator, not the underlying domain object. I tend
towards the same pattern, but delegate directly to a domain model, so I can
precisely control access (and document) at the view level.

Dave



On Mon, Oct 7, 2013 at 4:38 PM, Mike Menzies <gl...@gmail.com> wrote:

> Yes. That's pretty much exactly what it is.
>
>
> On Mon, Oct 7, 2013 at 3:35 PM, Dave Newton <da...@gmail.com> wrote:
>
> > So it's a presenter/decorator?
> >
> > Dave
> >
> >
> >
> > On Mon, Oct 7, 2013 at 4:26 PM, Mike Menzies <gl...@gmail.com> wrote:
> >
> > > Hello,
> > >
> > > My name is Mike, and I work for a fairly large company that uses
> Struts 2
> > > for most of its web apps. Some of these web apps are quite large, and
> one
> > > in particular has grown into a monster. In my ongoing efforts to clean
> up
> > > this project, I have developed what I like to call a JspHelper. Before
> I
> > > explain exactly what that is, I'd like to provide you with some
> examples
> > of
> > > the problems that I set out to fix.
> > >
> > > *Problem 1 - Monster JSPs*
> > > During early development of this project, struts tags were highly
> > > leveraged. I was not involved with the early phases of this project,
> so I
> > > can't speak to why they were used so extensively.. but they were. Tons
> of
> > > nested if tags that read var tags that were set in the JSP. Some of
> these
> > > JSPs were very hard to follow.
> > >
> > > Even though I am a fan of struts tags, I've come to realize that they
> > > should not be overused. JSPs cannot be unit tested and JSPs are hard to
> > > debug.
> > >
> > > So cleaning up a JSP means shifting logic out, in most cases into the
> > > action. An easy clean up could be something like this:
> > >
> > > <s:if test="articles != null && articles.size > 0 &&
> > user.canViewArticles">
> > >
> > > into
> > >
> > > <s:if test="showArticleSection()">
> > >
> > > It's instantly more readable, and the logic is in a testable Java
> class.
> > > Following this approach creates a lot of methods in the action, which
> can
> > > be a problem if you already have...
> > >
> > > *Problem 2 - Bloated Action Classes*
> > >
> > > When the project was small, it made a lot of sense to create
> > > abstract/parent action classes to share code between actions. As time
> > > passed, we just continued shoving any shared code in one of two
> > "abstract"
> > > classes... even if the code was only being shared between two out of
> the
> > 20
> > > actions.
> > >
> > > The fix for this trend is to moved shared code into services, so we
> began
> > > enforcing that practice. But this approach had its limitations. We use
> > > Spring injection for all of our services, and some times a particular
> > piece
> > > of logic just required too much stateful input... it just made more
> sense
> > > to leave it on the action where it had easy access to everything it
> > needed,
> > > as opposed to shoving it in a stateless service and having to pass in a
> > ton
> > > of arguments.
> > >
> > > What we really needed was some best practices put in place for the
> > creation
> > > of stateful, non-Spring services.
> > >
> > > *Enter JspHelperInceptor
> > >
> > > *
> > > It wasn't until after I created this inceptor that I realized it is
> > almost
> > > identical to the ModelDrivenInceptor. At which point, I wondered if
> that
> > is
> > > what I should actually be using.. but more on that later.
> > >
> > > All this interceptor does is push an object onto the value stack.
> That's
> > > it. Your action implements JspHelperAware which provides Object
> > > getJspHelper(), and the intercept code reads almost line for line with
> > the
> > > ModelDrivenInterceptor.
> > >
> > > The idea behind this JspHelper, which is just a POJO that you define,
> is
> > to
> > > provide a place where all (or most) of the data your JSP needs can be
> > > found. This means that OGNL can find any public members or operations
> > > faster, and also developers can trace back any OGNL expressions in the
> > JSP
> > > to it's corresponding Java code.
> > >
> > > This approach places code in a shareable component. You can easily
> > > aggregate one JSPHelper into another one, and then either provide
> wrapper
> > > methods or simply push the aggregate helper onto the stack using the
> > s:push
> > > tag for direct access to it's members.
> > >
> > > This approach makes the actions leaner, and provides a very clear cut
> > view.
> > > I find at times that the action tends to be both controller and view,
> > when
> > > really it should only act as the controller (IMO).
> > >
> > > This technique is functionally very similar to ModelDriven, but it's
> used
> > > slightly differently. I've used a JspHelper in combination with
> > > ModelDriven, and I've found the JspHelper to be a good place to store
> > > logic.. and leave the Model strictly as a business object.
> > >
> > > *Conclusion
> > > *
> > > I have personally found this technique incredibly useful in cleaning up
> > > code. You can shift all of the JSP exclusive logic and properties to
> the
> > > helper without touching the JSP (the OGNL expressions remain the same).
> > > Then after that initial step, you have a real handle on the exact input
> > > your JSP needs, and the actual clean up process progresses faster and
> > with
> > > less errors. I'm still in the process of establishing some best
> > practices,
> > > but so far this approach is working for us.
> > >
> > > I would like some honest feedback
> > >
> >
> >
> >
> > --
> > e: davelnewton@gmail.com
> > m: 908-380-8699
> > s: davelnewton_skype
> > t: @dave_newton <https://twitter.com/dave_newton>
> > b: Bucky Bits <http://buckybits.blogspot.com/>
> > g: davelnewton <https://github.com/davelnewton>
> > so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
> >
>



-- 
e: davelnewton@gmail.com
m: 908-380-8699
s: davelnewton_skype
t: @dave_newton <https://twitter.com/dave_newton>
b: Bucky Bits <http://buckybits.blogspot.com/>
g: davelnewton <https://github.com/davelnewton>
so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>

Re: JspHelper concept to improve MVC separation

Posted by Mike Menzies <gl...@gmail.com>.
Yes. That's pretty much exactly what it is.


On Mon, Oct 7, 2013 at 3:35 PM, Dave Newton <da...@gmail.com> wrote:

> So it's a presenter/decorator?
>
> Dave
>
>
>
> On Mon, Oct 7, 2013 at 4:26 PM, Mike Menzies <gl...@gmail.com> wrote:
>
> > Hello,
> >
> > My name is Mike, and I work for a fairly large company that uses Struts 2
> > for most of its web apps. Some of these web apps are quite large, and one
> > in particular has grown into a monster. In my ongoing efforts to clean up
> > this project, I have developed what I like to call a JspHelper. Before I
> > explain exactly what that is, I'd like to provide you with some examples
> of
> > the problems that I set out to fix.
> >
> > *Problem 1 - Monster JSPs*
> > During early development of this project, struts tags were highly
> > leveraged. I was not involved with the early phases of this project, so I
> > can't speak to why they were used so extensively.. but they were. Tons of
> > nested if tags that read var tags that were set in the JSP. Some of these
> > JSPs were very hard to follow.
> >
> > Even though I am a fan of struts tags, I've come to realize that they
> > should not be overused. JSPs cannot be unit tested and JSPs are hard to
> > debug.
> >
> > So cleaning up a JSP means shifting logic out, in most cases into the
> > action. An easy clean up could be something like this:
> >
> > <s:if test="articles != null && articles.size > 0 &&
> user.canViewArticles">
> >
> > into
> >
> > <s:if test="showArticleSection()">
> >
> > It's instantly more readable, and the logic is in a testable Java class.
> > Following this approach creates a lot of methods in the action, which can
> > be a problem if you already have...
> >
> > *Problem 2 - Bloated Action Classes*
> >
> > When the project was small, it made a lot of sense to create
> > abstract/parent action classes to share code between actions. As time
> > passed, we just continued shoving any shared code in one of two
> "abstract"
> > classes... even if the code was only being shared between two out of the
> 20
> > actions.
> >
> > The fix for this trend is to moved shared code into services, so we began
> > enforcing that practice. But this approach had its limitations. We use
> > Spring injection for all of our services, and some times a particular
> piece
> > of logic just required too much stateful input... it just made more sense
> > to leave it on the action where it had easy access to everything it
> needed,
> > as opposed to shoving it in a stateless service and having to pass in a
> ton
> > of arguments.
> >
> > What we really needed was some best practices put in place for the
> creation
> > of stateful, non-Spring services.
> >
> > *Enter JspHelperInceptor
> >
> > *
> > It wasn't until after I created this inceptor that I realized it is
> almost
> > identical to the ModelDrivenInceptor. At which point, I wondered if that
> is
> > what I should actually be using.. but more on that later.
> >
> > All this interceptor does is push an object onto the value stack. That's
> > it. Your action implements JspHelperAware which provides Object
> > getJspHelper(), and the intercept code reads almost line for line with
> the
> > ModelDrivenInterceptor.
> >
> > The idea behind this JspHelper, which is just a POJO that you define, is
> to
> > provide a place where all (or most) of the data your JSP needs can be
> > found. This means that OGNL can find any public members or operations
> > faster, and also developers can trace back any OGNL expressions in the
> JSP
> > to it's corresponding Java code.
> >
> > This approach places code in a shareable component. You can easily
> > aggregate one JSPHelper into another one, and then either provide wrapper
> > methods or simply push the aggregate helper onto the stack using the
> s:push
> > tag for direct access to it's members.
> >
> > This approach makes the actions leaner, and provides a very clear cut
> view.
> > I find at times that the action tends to be both controller and view,
> when
> > really it should only act as the controller (IMO).
> >
> > This technique is functionally very similar to ModelDriven, but it's used
> > slightly differently. I've used a JspHelper in combination with
> > ModelDriven, and I've found the JspHelper to be a good place to store
> > logic.. and leave the Model strictly as a business object.
> >
> > *Conclusion
> > *
> > I have personally found this technique incredibly useful in cleaning up
> > code. You can shift all of the JSP exclusive logic and properties to the
> > helper without touching the JSP (the OGNL expressions remain the same).
> > Then after that initial step, you have a real handle on the exact input
> > your JSP needs, and the actual clean up process progresses faster and
> with
> > less errors. I'm still in the process of establishing some best
> practices,
> > but so far this approach is working for us.
> >
> > I would like some honest feedback
> >
>
>
>
> --
> e: davelnewton@gmail.com
> m: 908-380-8699
> s: davelnewton_skype
> t: @dave_newton <https://twitter.com/dave_newton>
> b: Bucky Bits <http://buckybits.blogspot.com/>
> g: davelnewton <https://github.com/davelnewton>
> so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>
>

Re: JspHelper concept to improve MVC separation

Posted by Dave Newton <da...@gmail.com>.
So it's a presenter/decorator?

Dave



On Mon, Oct 7, 2013 at 4:26 PM, Mike Menzies <gl...@gmail.com> wrote:

> Hello,
>
> My name is Mike, and I work for a fairly large company that uses Struts 2
> for most of its web apps. Some of these web apps are quite large, and one
> in particular has grown into a monster. In my ongoing efforts to clean up
> this project, I have developed what I like to call a JspHelper. Before I
> explain exactly what that is, I'd like to provide you with some examples of
> the problems that I set out to fix.
>
> *Problem 1 - Monster JSPs*
> During early development of this project, struts tags were highly
> leveraged. I was not involved with the early phases of this project, so I
> can't speak to why they were used so extensively.. but they were. Tons of
> nested if tags that read var tags that were set in the JSP. Some of these
> JSPs were very hard to follow.
>
> Even though I am a fan of struts tags, I've come to realize that they
> should not be overused. JSPs cannot be unit tested and JSPs are hard to
> debug.
>
> So cleaning up a JSP means shifting logic out, in most cases into the
> action. An easy clean up could be something like this:
>
> <s:if test="articles != null && articles.size > 0 && user.canViewArticles">
>
> into
>
> <s:if test="showArticleSection()">
>
> It's instantly more readable, and the logic is in a testable Java class.
> Following this approach creates a lot of methods in the action, which can
> be a problem if you already have...
>
> *Problem 2 - Bloated Action Classes*
>
> When the project was small, it made a lot of sense to create
> abstract/parent action classes to share code between actions. As time
> passed, we just continued shoving any shared code in one of two "abstract"
> classes... even if the code was only being shared between two out of the 20
> actions.
>
> The fix for this trend is to moved shared code into services, so we began
> enforcing that practice. But this approach had its limitations. We use
> Spring injection for all of our services, and some times a particular piece
> of logic just required too much stateful input... it just made more sense
> to leave it on the action where it had easy access to everything it needed,
> as opposed to shoving it in a stateless service and having to pass in a ton
> of arguments.
>
> What we really needed was some best practices put in place for the creation
> of stateful, non-Spring services.
>
> *Enter JspHelperInceptor
>
> *
> It wasn't until after I created this inceptor that I realized it is almost
> identical to the ModelDrivenInceptor. At which point, I wondered if that is
> what I should actually be using.. but more on that later.
>
> All this interceptor does is push an object onto the value stack. That's
> it. Your action implements JspHelperAware which provides Object
> getJspHelper(), and the intercept code reads almost line for line with the
> ModelDrivenInterceptor.
>
> The idea behind this JspHelper, which is just a POJO that you define, is to
> provide a place where all (or most) of the data your JSP needs can be
> found. This means that OGNL can find any public members or operations
> faster, and also developers can trace back any OGNL expressions in the JSP
> to it's corresponding Java code.
>
> This approach places code in a shareable component. You can easily
> aggregate one JSPHelper into another one, and then either provide wrapper
> methods or simply push the aggregate helper onto the stack using the s:push
> tag for direct access to it's members.
>
> This approach makes the actions leaner, and provides a very clear cut view.
> I find at times that the action tends to be both controller and view, when
> really it should only act as the controller (IMO).
>
> This technique is functionally very similar to ModelDriven, but it's used
> slightly differently. I've used a JspHelper in combination with
> ModelDriven, and I've found the JspHelper to be a good place to store
> logic.. and leave the Model strictly as a business object.
>
> *Conclusion
> *
> I have personally found this technique incredibly useful in cleaning up
> code. You can shift all of the JSP exclusive logic and properties to the
> helper without touching the JSP (the OGNL expressions remain the same).
> Then after that initial step, you have a real handle on the exact input
> your JSP needs, and the actual clean up process progresses faster and with
> less errors. I'm still in the process of establishing some best practices,
> but so far this approach is working for us.
>
> I would like some honest feedback
>



-- 
e: davelnewton@gmail.com
m: 908-380-8699
s: davelnewton_skype
t: @dave_newton <https://twitter.com/dave_newton>
b: Bucky Bits <http://buckybits.blogspot.com/>
g: davelnewton <https://github.com/davelnewton>
so: Dave Newton <http://stackoverflow.com/users/438992/dave-newton>