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 <glo...@gmail.com> wrote: > Yes. That's pretty much exactly what it is. > > > On Mon, Oct 7, 2013 at 3:35 PM, Dave Newton <davelnew...@gmail.com> wrote: > > > So it's a presenter/decorator? > > > > Dave > > > > > > > > On Mon, Oct 7, 2013 at 4:26 PM, Mike Menzies <glo...@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: davelnew...@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: davelnew...@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>