Beyond 2.6

John Ralls jralls at ceridwen.us
Sat Feb 16 11:01:55 EST 2013


On Feb 16, 2013, at 5:25 AM, Geert Janssens <janssens-geert at telenet.be> wrote:

> On 16-02-13 14:06, Herbert Thoma wrote:
>> forgot CC list ...
>> 
>> Am 15.02.2013 21:06, schrieb John Ralls:
>>>>> Why hard to say? MVC isn't exactly cutting-edge design. It's been
>>>>> around since 1988 and 7 years later GoF thought it so well-understood
>>>>> that it's the "how to use patterns" example in the introduction.
>>>> Well, the point is that every time the user leaves a field you need to
>>>> parse all the input fields and process them in the controller/model as
>>>> part of the validation, even if the user hasn't asked to 'save' yet.
>>>> 
>>>> I guess it all depends on your controller APIs.  (In the RoR world this
>>>> is harder to do, because the view is in the browser, but the model and
>>>> controllers are on the server -- and there is no "verify this model" API
>>>> in the controller.  At least not directly.  The client-side-validations
>>>> gem adds some support for this).
>>> 
>>> We already do that for the account type listbox: We connect to a signal
>>> (don't know offhand which one) in the parent accounts GtkTreeView that tells
>>> us that the user has selected a parent account, retrieve that account, run
>>> xaccAccountGetCompatibleTypes() on it, and populate the account type listbox
>>> with the result.
>>> 
>>> That's a pretty standard way for UI View objects to communicate with their
>>> controller objects, though there are others. Wx has a specific "Validator"
>>> class that lets you register a callback to test control input as it happens.
>>> It also has a signals mechanism (which they rather confusingly call Events)
>>> to support other interactivity needs. Qt is well-known for its "signals and slots"
>>> feature, which I imagine is used for this purpose much like Gtk's signals are, but
>>> I've never written anything for Qt so I don't actually know.
>> Yes, you can use signals and slots this way. I personally like Qt very much. For me
>> it is the best GUI toolkit I have ever worked with (I worked with Motif, MFC,
>> GTK and Qt, but always only small projects or patches to GnuCash).
>> 
>> However, I would still be hesitant to use signals and slots in the engine. Earlier
>> in this thread it was stated that the engine depends heavily on Glib and that this
>> is bad for portability. Do we want to replace the Glib dependency with a Qt
>> dependency?
>> 
>>  Herbert.
>> 
> I have been silently following this thread and made the same reservation from the beginning for myself.
> 
> I don't have much experience with how this is done in general. It seems to me though that's a matter of defining the API's well.
> 
> The GUI is supposed to know if some fields have to be validated. There's no way around this. But the GUI code doesn't have to know what the validation entails exactly. The core engine on the other hand does know exactly what is allowed for a given object and what isn't. The key is that the core engine should make some functions available for testing this, returning in the most simple case a yes/no reply (value is valid for object or not). In a more advanced set up it can also return a message that can be displayed to the user to explain why the input isn't valid.
> 
> These functions are part of the core engine API and don't need to use any GUI framework related toolkit (like Qt, Glib, Gtk, WxWidgets stuff). We could keep the signal and the slots both in the GUI code, with the slots calling into the engine functions to do the real work.
> 
> Did I understand this correctly ?

Well, partly. You're lumping the View and Controller layers together in "GUI code". For the most part we don't write the View classes: They're provided by the framework (Qt, Gtk, whatever) and they emit the signals (Register is the exception). The Controller classes handle the signals (have slots in Qt-speak) and those handler functions then call whatever functions in the Model are needed to do the actual work. Controller classes should be as close to simple shims as possible with all of the real work done in the Model. That makes it much easier to support multiple GUI frameworks, a command-line interface (a Controller class with no View), and a comprehensive test suite (another Controller class with no view for integration tests; unit tests are intrusive to the class they're testing and so part of the Model).

It's easier to maintain separation of responsibilities if you keep the three layers in mind and are mindful of which layer the class that you're working on belongs to.

Regards,
John Ralls


More information about the gnucash-devel mailing list