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 <glo...@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 <davelnew...@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 <glo...@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 <davelnew...@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 <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> > > > > > > > > > > > > > > > -- > > 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>