30

I am currently working on three Vaadin applications and I really feel like I miss something. I used to work with Spring MVC before, where architecture is clear and decoupled, you inject services to controllers and don't couple controller to UI and so on.

Now in Vaadin that's different story. So if there are any Vaadin specialists out there, let me ask you few questions:

Question 1:

  • Is it OK to inject services (or DAOs) directly to UI components?
  • Example: Component responsible for showing contacts in email application (ContactWidget, based on the VerticalLayout with Links) needs to display contacts. Is it OK to inject contactRepository directly to this UI element?

Question 2:

  • Reference to the main application is being passed to the HUGE amount of UI componenets, because lot of UI components need to access some global data or invoke global methods on main application class
  • Example: Popup component has Button that opens new Window, which should be child of the main window in application. Therefore popup component must have reference to main application.

Question 3:

  • Dependencies between UI components can get pretty wild. Probably nothing much to do here, but sometimes it doesn't feel like that this window depends on this list which depends on that popup ... you get the idea, it looks tightly coupled to me

I'd like to learn as much as possible about good design with Vaadin before my code turns to Spaghetti, so any suggestions, experience and best practices would be appreciated.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
Xorty
  • 18,367
  • 27
  • 104
  • 155

2 Answers2

16

We've had very good luck using the MVVM pattern (aka Fowler's PresentationModel). His docs are a bit old, but a good starting point.

After you've read that, my answers may make more sense

  1. No. Inject your services into your ViewModel. The ViewModel will be a Facade (and can encapsulate Adapters, Decorators, Caches and any other Patterns you decide you need)

  2. I didn't see a question here, but we do have a situation similar to what you're describing. We use Guava's EventBus to communicate between decoupled components. In this way, if you need to pop up a new window, you can: eventBus.post(new NewWindowRequest(theComponent)) And your main application can be subscribed to the same event, then pop up the window.

  3. MVVM and cautious use of EventBus can help. Also, Vaadin's BeanItem and ObjectProperty can be used to propagate changes, as they're part of Vaadin's built-in observer/data-binding pattern.

I recently did a presentation on MVC vs MVP vs MVVM. The example code may help you understand the shift from MVC to MVVM. It is written in JavaScript, but it is simple enough that I believe most anyone can follow it. I welcome any feedback you might have.

Dusty J
  • 721
  • 6
  • 12
  • Thanx Dusty. I eventually picked hand-made MVP (very light) and event propagation based on Guava's eventBus. I am quite happy with this decision even though it's surprising that there is no solid MVP framework (there are dozena of betas/alphas/experimentals though) for Vaadin. – Xorty Oct 09 '12 at 23:15
  • Yeah, well, despite being around for a long while, it doesn't have a big enough following to get the Engineer Love that other tech gets. Most of the people using it are looking for the simplest solution available, or if you're like us, don't have enough time to document what we're doing. Hand-built is a very good choice. The concepts are the important part, and most MVC/MVP/MVVM frameworks are just there to make sure you're coloring in the lines. If you have discipline, they usually aren't a requirement. – Dusty J Oct 12 '12 at 03:49
9

Vaadin is a great piece of software and you definitely should not end-up with Spaghetti code. Anyway, everything depends on you.

Answer 1

No, it isn't. Tight coupling is bad regardless of the framework being used. Your example(ContactWidget) describes a custom implementation of a list. It can be rendered as a table with or without additional information. I will use table example because it is more complex and more flexible as well (you can build entire application having advanced table component and proper data binding).

Vaadin defines advanced data model following well-known MVC pattern. There are three nested layers: container, item, property (properties viewers and editors are also defined). Vaadin book suggests good analogy: spreadsheet application. So container, item and property will correspond to table, row and cell. Easy to imagine -- easy to understand. Finally, ItemContainer will reveal it's nature and you'll understand this is the key contract for any good and flexible Vaadin-based architecture. I would suggest to look through Vaadin book, to get all other details:

You can also review container implementation behind any PagedTable addon to get even better understanding. Please also start with ArrayContainer https://vaadin.com/directory#addon/array-container, it will simplify a lot for you.

Answer 2

Passing main application reference does not seem to be a good solution. You did notice Application instance represents the session but it will be much better for you to define some sort of SessionContext contract (which still can be implemented by your application). A static method can be defined to provide transparent access to the relevant SessionContext instance. Under the hood it can use ThreadLocal variable http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html In such a way you will get rid of all parasitic parameters passing.

Answer 3

Design your hierarchy with a great care. Do not trigger repaint yourself, use Refresher instead. Keep an eye on the whole architecture.

Finally, Vaadin is simple to use, so feel free to do some tiny PoCs and demos before changing the main codebase.

As was suggest you can also try MVVM https://vaadin.com/directory#addon/bambi-mvvm

bernard paulus
  • 1,644
  • 1
  • 21
  • 33
Renat Gilmanov
  • 17,735
  • 5
  • 39
  • 56
  • 1
    Thanx for the answer, I checked out bambi-mvvm - looks very nice, but it's quite incomplete, untested and beta. Same for most MVVM/MVP Vaadin related stuff I found :( – Xorty Oct 09 '12 at 23:14
  • You are welcome. Vaadin is too young, or it is better to say relatively young :) Personally, I preferred to implement Container, Container.Indexed, ... myself to get paging and some other features. – Renat Gilmanov Oct 10 '12 at 20:16