Page 1 of 3 123 LastLast
Results 1 to 10 of 23

Thread: Best design for reusing view logic?

  1. #1
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    668

    Default Best design for reusing view logic?

    I'm struggling with the best way to reuse my logic for creating view models, particularly when these models are non-trivial. For example, I have a view that expects certain model data to be present, let's say:

    - a list of Person objects
    - a boolean "editable" flag
    - a string message

    I have String constants for the names of these things in the model:
    Code:
    ViewConstants.MODEL_PEOPLE = "people";
    ViewConstants.MODEL_EDITABLE = "editable";
    ViewConstants.MODEL_MESSAGE = "message";
    When I need to create a ModelAndView, I do this:
    Code:
    Map model = new HashMap();
    model.put(ViewConstants.MODEL_PEOPLE, somePeople);
    model.put(ViewConstants.MODEL_EDITABLE, someBooleanObject);
    model.put(ViewConstants.MODEL_MESSAGE, someMessage);
    /* maybe some other stuff gets added to the model here, possibly
    * looked up by a service known to the controller */
    ModelAndView modelAndView = new ModelAndView("myView", model);
    However, I need to generate this type of "model and view" from multiple controllers (using different model objects in each case), so what's the best way to share this logic? Solutions I've come up with so far are:

    - having a method in one of the controllers that takes the model objects and returns the ModelAndView, but this means the other controllers have to have this controller injected into them as a dependency, which is ugly and also complicates unit testing, as I have to create and set up a lot more mock objects

    - subclassing ModelAndView to create say PersonModelAndView, whose constructor takes all the necessary model data and services as arguments (I just thought of this approach, so don't know the pros and cons yet)

    What do other people do in this situation? Is there a Spring best practice?

  2. #2
    Join Date
    Aug 2004
    Posts
    25

    Default

    Have you considered making one root controller that you extend? Then just include that code in a protected method in the root class that you extend for your own controllers.

  3. #3
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    668

    Default Extending custom controller class

    Thanks for the suggestion, but unfortunately it won't work in my case. One of my controllers that needs to reuse the model-and-view-generating code already extends Spring's MultiActionController and another extends Spring's SimpleFormController.

    Any other ideas, anyone?

  4. #4
    Join Date
    Aug 2004
    Posts
    25

    Default

    You could put a static method in a class (blech) or you could include a bean that contains the method in your controllers using dependency injection, then call that method from within your controllers.

  5. #5
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    668

    Default Think I'll subclass ModelAndView

    Hi rafeco,

    Thanks for the further suggestions. The latter is the same as the first suggestion in my original post.

    I've tried the second of my original two ideas (subclassing ModelAndView) and will keep doing that until someone comes up with a better idea.

    Is anyone else subclassing ModelAndView for this reason?

    P.S. Are you Rafe Colburn, whose books I've read?

  6. #6
    Join Date
    Oct 2004
    Location
    Rotterdam, Netherlands
    Posts
    90

    Default

    In case of Controllers extending AbstractFormController (i.e. SimpleFormController, AbstractWizardFormController), this kind of logic is best implemented by overriding the referenceData(HttpServletRequest request, Object command, Errors errors) method. See:

    http://static.springframework.org/sp...ler.html<br />

    I can't see how you could have a MultiActionController and be needing any referenceData. Can you describe your Use Case for this. Maybe you can factor out those Use Cases needing reference data and have them use the a Controller extending the AbstractFormController as well?

  7. #7
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    668

    Default

    OK, here's my use case (sorry for not making this clearer before):

    I have a view that displays a list of objects (let's say "Person" objects). This view always requires several model objects:

    - the list of objects to be displayed (the people)
    - the possible actions for each displayed item (this is dynamic in that it depends on the user's permissions, e.g. edit, delete, view, etc.)
    - the possible global actions (e.g. add a person, if the user has permission)
    - information about the parent of the listed objects (e.g. a PersonGroup)
    - the screen title (which is dynamic in that it depends on but is not solely derived from properties of the parent)

    Anyway, it's not important to this discussion what these data are, just that the view has a standard, non-trivial set of data that it expects to be provided with.

    I'd like a way of ensuring that any controller that needs to display this view can do so without repeating the same (lengthy) model-composing code. In other words, I'd like to write the code that generates the model once, then have each relevant controller call that central bit of code, passing in any values that can only be determined at runtime.

    Note that my shared list view is not a form, and therefore there is no concept of reference data. In fact its controller is a MultiActionController, not a SimpleFormController.

    Right now my solution is to extend ModelAndView and have a constructor that demands the relevant runtime data. The ModelAndView subclass then performs all the standard model-composing logic that is reusable. I was just wondering what other people do in this scenario and/or what Spring's best practice is.

  8. #8
    Join Date
    Oct 2004
    Location
    Rotterdam, Netherlands
    Posts
    90

    Default

    You can let your Service/Manager Classes take care of generating the Model at runtime. Have them return a Map that you can add to your ModelAndView using:



    Map model = myService.generateModel(RuntimeParam arg0, RuntimeParam arg1, RuntimeParam arg2);

  9. #9
    Join Date
    Oct 2004
    Location
    Rotterdam, Netherlands
    Posts
    90

    Default

    I prematurely submitted my previous post. This is what I suggest you try:

    Code:
    protected  ModelAndView handleRequestInternal&#40;HttpServletRequest request, HttpServletResponse response&#41; &#123;
    Map model = myService.generateModel&#40;RuntimeParam arg0, RuntimeParam arg1, RuntimeParam arg2&#41;;
    return new ModelAndView&#40;getSuccessView&#40;&#41;, "model", model&#41;;
    &#125;
    Rgrds, Thomas

  10. #10
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    668

    Default What about "separation of concerns"?

    Hi delnoij,

    I did consider that approach, but IMO the logic for deciding what model data goes into a view is controller logic, not business logic, therefore it should be in a web-tier class (a controller or a subclass of ModelAndView) rather than a service object.

    Andrew

Similar Threads

  1. Replies: 9
    Last Post: Nov 1st, 2005, 10:36 PM
  2. A design question
    By thenakedsingularity in forum Web
    Replies: 3
    Last Post: Oct 25th, 2005, 02:02 PM
  3. A design question
    By thenakedsingularity in forum Architecture
    Replies: 10
    Last Post: Oct 25th, 2005, 11:15 AM
  4. PageCompononentListener Hooks...JIRA issue?
    By amcauley in forum Swing
    Replies: 9
    Last Post: Apr 15th, 2005, 06:10 AM
  5. Content Provider vs View Model
    By Martin Kersten in forum Swing
    Replies: 21
    Last Post: Mar 10th, 2005, 02:25 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •