• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

MVC: can the controller handle the TableModel directly ?

 
Ranch Hand
Posts: 74
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi

I just know the MVC model by reading about it, so when implementing it I have some issue: can the controller directly act on the TableModel?

Indeed I've in mine such a method:
public void searchVacancy(final VacancyTableModel vacancyTableModel,
final String nameSearch, final String locationSearch)

which ends up by doing
vacancyTableModel.setVacancies(vacancyService.search(criterions));

(my setVacancies in turn triggers fireTableDataChanged();).

Is it ok to do so ?

thanks in advance

best
nono
 
Rancher
Posts: 175
Clojure Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Norbert Lebenthal wrote:...can the controller directly act on the TableModel?

Indeed I've in mine such a method:

public void searchVacancy(final VacancyTableModel vacancyTableModel,
final String nameSearch, final String locationSearch)

which ends up by doing
vacancyTableModel.setVacancies(vacancyService.search(criterions));

(my setVacancies in turn triggers fireTableDataChanged();).

Is it ok to do so ?



In my implementation, each listener is constructed with a reference to its parent. That parent, typically the main view, includes the table and therefore its model and has a reference (by interface) to a controller.

On an event, the listener grabs the controller reference from the parent, uses the controller reference to acquire results, grabs a reference to the table model from the table via the parent, and sets those results on that model (using a method that then fires the change notification).

The flow of logic is therefore nearly the same in your implementation and mine. The only important differences I see are these:

  • I don't pass a reference to the table model into my controller's service method.
  • I perform the search on criteria separately (to leave room for any additional handling) rather than as an argument to the table model's setter.


  • Letting the main controller know about a table model in the view seems like too close a coupling to me. In my impl, action listeners invoke the controller (which hits the domain model via service classes) and then pass its results into the little models underlying the view components.

    Likewise, seeking results from the data tier and passing them to the view in a single line may be efficient, but also seems a bit too confident and lispy.

    I'd be interested to hear whether others share my affection for decoupling junctures.
     
    Norbert Lebenthal
    Ranch Hand
    Posts: 74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Interesting post, thanks a lot. I could easily change my code this way, since it makes sense and isn't hard to do, but let's see what the others say.
     
    Bartender
    Posts: 2292
    3
    Eclipse IDE Spring Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Howdy, champions!

    Well, here are my thoughts about this discussion:

    I think that letting the controller directly act on the TableModel sort of breaks a little bit the MVC proposal. I agree with my good buddy David when he says that "letting the main controller know about a table model in the view seems like too close a coupling". It is the main window's resposibility to deal with the table model, updating it properly.

    It is important to always remember that each class must not do more than it should. So, if the controller acts directly on the table model, then it is doing more than it should. The TableModel must only contain the data being displayed (and important: the TableModel is different from the Model of the MVC, since this model is in the View and the Model of the MVC is the layer that contains the intelligence of your system). In a desktop application, we can see an ActionListener as being the controller. In this case, what you can do is ask the main window to update the data being displayed, and the main window acts on the TableModel. For instance:



    David Byron wrote:On an event, the listener grabs the controller reference from the parent, uses the controller reference to acquire results, grabs a reference to the table model from the table via the parent, and sets those results on that model (using a method that then fires the change notification).



    Hum... a listener that grabs a reference to the controller? How is this controller of yours? Also, the listener then gets a reference to the TableModel? Well, it would be better to ask the main window to update the TableModel's data. I'd say that this would lead to a more cohesive design.
     
    David Byron
    Rancher
    Posts: 175
    Clojure Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Roberto Perillo wrote:(and important: the TableModel is different from the Model of the MVC, since this model is in the View and the Model of the MVC is the layer that contains the intelligence of your system)



    I think this point is worth emphasizing.

    In a Swing app, there's a potential for confusion about where the MVC triad resides. I like to think of it this way: there's a main manifestation of MVC at the macroscopic level, and there are many MVC arrangements at the microscopic level.

    Macro: The presentation code in its entirety is the View, the classes that mediate between that View and the abstraction representing the data tier are the Controller, and the domain objects (perhaps guarded by other structures) constitute the Model.

    Micro: Individual widgets in the View also often follow the MVC pattern, with tables backed by table models, text areas backed by documents, and the jcombobox backed by some sort of labyrinth. In each of these micro cases, the view is the widget, the model holds the state for that widget, and the controller consists of whatever listeners or actions respond to a user's gestures by changing model's state and refreshing the view.

    Intersection: Sometimes, to do their job, the controllers at the micro level must consult those at the macro level.

    Thinking about MVC in this pluralistic way helps to reduce confusion. It's not the only way to think about it, nor necessarily the best way, but I find it useful.
     
    David Byron
    Rancher
    Posts: 175
    Clojure Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Roberto Perillo wrote:

    David Byron wrote:On an event, the listener grabs the controller reference from the parent, uses the controller reference to acquire results, grabs a reference to the table model from the table via the parent, and sets those results on that model (using a method that then fires the change notification).


    Hum... a listener that grabs a reference to the controller? How is this controller of yours?


    In my impl, the view knows of a controller (by interface) and the controller knows of a way to address the model (by interface).

    A: The listener simply is the controller.
    B: The listener asks its parent, the view, to use the controller.
    C: The listener asks its parent, the view, for a controller and then uses it.

    You're suggesting that A is better than B or C. Perhaps you're right. I chose C because it seemed more cohesive to me to keep wranglin' code isolated in wranglers. That may be more abstraction than is needed, but I find it comforting.

    Also, the listener then gets a reference to the TableModel? Well, it would be better to ask the main window to update the TableModel's data. I'd say that this would lead to a more cohesive design.



    A: The listener asks its parent, the view, to update the model.
    B: The listener asks its parent, the view, for the model and then updates it.

    Again, you're suggesting that A is better than B, and perhaps you're right. But I chose B because having the view's listeners do some of this scutwork seemed as reasonable to me as having the view's listeners tell the window itself to do that work while they watch. ;)
     
    Sheriff
    Posts: 11604
    178
    Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I'll give my view on this (which is simply how I implemented it):

    I have a controller class which has a reference to my business service (which can be either local or network implementation depending on the mode). This controller has a few methods (find, book) which invoke methods from the business service. Also possible business exceptions are handled in these methods and a specific controller exception is thrown. The find-method of my controller will create a new instance of MyCustomTableModel class).
    My main client window (which represents the View in the MVC pattern) has a reference to the controller and when a user for example hits the Search-button, the appropriate method on the controller is invoked and the MyCustomTableModel instance is passed to my JTable. End of story

    Main advantages of this approach are always the same big words: simplicity, code maintainability and extensibility. More specific:
  • by using only one specific controller exception you have to handle just 1 exception in your client window (instead of a whole bunch of exceptions), which results in easier to read code. When you need to introduce a new business exception (e.g. CustomerFirstHasToPayHisBalanceDue) you only have to change your controller class (which makes sense, because your view does not need to know which business exceptions exist and how they should be handled)
  • when using a new TableModel instance every time, the old ones will become eligible for garbage collection and you don't have to think about first clearing the old list before adding the new items or invoking fireTableDataChanged-method, simply pass the new instance to your JTable and it takes care of everything (no extra charge )


  • Kind regards,
    Roel
     
    Norbert Lebenthal
    Ranch Hand
    Posts: 74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    hi

    thanks all for your interesting answers

    I checked again the SCJD book, and they say the main intent of MVC is for the view to never directly access the Model, so giving a VacancyTableModel to it doesn't feel like too crazy. On the other hand, decoupling and reuse purpose of the MVC controller push for separation.

    I will check if I can go for an in between solution, having the Controller returning a list and building a fresh table model directly from it.

    EDIT: and how do you handle exceptions in the controller ? Personally I've a ErrorDisplay.raiseError(String), which is a static method, to handle display of all errors. As such I could use it directly in the controller. Yet again I guess this might be subject of disagreement.
     
    Roel De Nijs
    Sheriff
    Posts: 11604
    178
    Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Norbert Lebenthal wrote:and how do you handle exceptions in the controller ?


    My controller catches all business exceptions and throws a specific exception with a user-readible message. This controller exception is caught in the main client window and the message is shown.
     
    Roberto Perillo
    Bartender
    Posts: 2292
    3
    Eclipse IDE Spring Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Norbert Lebenthal wrote:and how do you handle exceptions in the controller ?



    Well, when using the approach I proposed above, you can do something like this:

     
    Norbert Lebenthal
    Ranch Hand
    Posts: 74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator


    Well, in the end you tackle them view side, and not controller side, which makes sense (handling of them could be pretty different depending on the UI). I'll do so as well.
     
    Roberto Perillo
    Bartender
    Posts: 2292
    3
    Eclipse IDE Spring Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Norbert Lebenthal wrote:Well, in the end you tackle them view side...



    Well, I'd just change "view side" by "presentation side". The controller is part of the presentation layer. Please take a look at the Front Controller and the Application Controller patterns (which are the most popular types of controller).
     
    David Byron
    Rancher
    Posts: 175
    Clojure Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Roberto Perillo wrote:The controller is part of the presentation layer.


    I'd say that when we're discussing MVC, and we say that the C is part of the V, we're definitely veering away from pure MVC and toward a variant (namely, the Model-Delegate pattern).

    My preference is to construe the C as a facility discrete from the V, so I have a separate controller class, and I don't allow my listeners to address my model or services directly.
     
    Roberto Perillo
    Bartender
    Posts: 2292
    3
    Eclipse IDE Spring Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    David Byron wrote:I'd say that when we're discussing MVC, and we say that the C is part of the V, we're definitely veering away from pure MVC and toward a variant (namely, the Model-Delegate pattern).



    I never said that C is part of V, but C is part of the presentation layer. One simple example of this is the Front Controller pattern, whose role, in a web application, is always played by a Servlet, which is part of the presentation layer. In a web application, the presentation layer is frequently referred to as web tier, where you find things like JSPs, Servlets, Taglibs, Filters, etc.

    Presentation layer is one thing. View is part of the presentation layer. It may sound confusing, but it just depends on how you see things.
     
    reply
      Bookmark Topic Watch Topic
    • New Topic