[Cuis] Fwd: Fwd: Patterns

Juan Vuletich juan at jvuletich.org
Wed Nov 18 07:39:54 CST 2015


Hi Thierry,

(inline and abridged)
On 11/17/2015 3:59 PM, Thierry Goubier wrote:
> Hi Juan,
>
> Le 17/11/2015 18:36, Juan Vuletich a écrit :
>> Hi Thierry,
>>
> ...
>>> Now, I used to be pretty up to date on the literature and some of the
>>> criticism of the MVC model (especially the division between V and C)
>>> but my memory of that time is all fuzzy.
>>
>> Well, in my opinion View / Model separation is a great property of the
>> design of an application. Controller is more of a requirement of the
>> ST-80 MVC framework. In principle, I see no problem in merging
>> Controller into View. But, in Cuis, it can be argued that the Editor
>> hierarchy is essentially a hierarchy of Controllers, and that's ok if
>> the decomposition of responsibilities makes sense.
>>
>> In View / Model separation there are two restrictions that need to be
>> honored:
>> - The Model doesn't know about the possible Views. This means, for
>> instance, that it could provide all its services, and exercise all its
>> functionality, even if the GUI framework is completely absent. Model
>> code should never fail because of this. This is great for moving models
>> from and two different runtimes (client, server, gemstone, various
>> dialects, etc) and also for writing tests.
>> - Model behavior should not leak into Views. This means that if the
>> views are removed (maybe to be replaced by some others, in the same or
>> in another framework), Model should not lose state nor behavior. Model
>> must be complete by itself.
>> So, the idea is essentially to protect the integrity and consistency of
>> Models.
>
> I do agree with that objective, but, in practice, what I find as a 
> result is that an additional layer (model mediation or the M2 of MMVC) 
> helps immensely by:
>
> - regrouping certain model features which are introduced to satisfy 
> view requirements...
>
>   - For example a pure model can just have a copy or save to file 
> operation, but a view would like to have a feedback on the length of 
> the operation. In non gui mode, having the model expose that sort of 
> information is a needless waste of code and resources. This would 
> better be carried by a layer on top (which is still a model IMHO, 
> since it maintain a certain level of decoupling with a view).
>
> - Expose explicitely certain adaptations which are made for a specific 
> toolkit (they are in that model).
>
> - Allow for user-features oriented models to appear on top of the 
> pure, abstract model
>
>   - In a browser, one can imagine scoped models of the code as a 
> user-oriented feature that a disconnected mode doesn't need to integrate.
>
> Nothing really grandiose or earth-shattering, mind you. Just convenient.

I agree. Many times it is really useful to add another layer. At Caesar 
we called those "Model Extensions".

In many cases, it is possible to do this in a way that is agnostic of 
the actual GUI framework, meaning that it can be used for several GUI 
styles. If this is the case, then it is OK to bundle this with the real 
Model, as it doesn't leak GUI framework specifics.

It is also very desirable not to compromise the consistency of the real 
Model, i.e. not leaking Model specifics. Then, it is also possible to 
bundle this with the Views. (This is what we usually did at Caesar).

If none of this conditions are met, i.e., this "ModelExtension" includes 
Model responsibilities AND detailed GUI framework knowledge, then I'd 
say some refactoring is in order. So, this doesn't go against strict 
View / Model separation.

>>> What would you think of a drag and drop feedback which is dependent of
>>> the type of the model elements?
>>
>> Well, lets assume a Model with 2 collections of elements. To make it
>> sound a bit more concrete, lets call them Orders and Assets. And lets
>> assume that the UI has some place(s) from where the user can drag many
>> kinds of objects, like Orders, Assets, between others. Now, the user
>> drags an Asset and wants to drop it into the Orders list. Given that the
>> widget for the Orders list supports dropping, lets assume that its
>> 'dropActionSelector' is #addOrder:. This #addOrder: model method would
>> be called with an Asset. So, #addOrder: could answer false, to let
>> sender know that the addition was rejected (because it was not an
>> Order!). It makes sense to have the method in ListWidget that calls
>> 'dropSelector' check for the result, and if it is false, let the user
>> know that the drop was rejected, for instance, by keeping the dragged
>> object in the hand.
>
> Hum, I was more thinking of what I am dealing with at the moment, 
> which is a drop in the Orders list is a drop on a specific order item, 
> which has to tell:
>
> - during the drag, if a drop would be honored
> - after the drop, if it is accepted or rejected
> - and, if accepted, that specific order item changes state and is 
> shown as such (and may also change the number of order items, etc...)
>
> I found, when doing that, to have an intermediate model on top of my 
> Asset/Order object to mediate with the drag and drop API very usefull 
> (that is, what is displayed and dragged are Views on AssetModels which 
> are themselves observers of Assets).

This is OK as long as it doesn't leak Model responsibilities, then it 
can just be a Model Extension that goes with the GUI.

>
>>
>>>
>>>
>>>>     So the most elegant way I've used is the two models: a pure,
>>>>     abstract model, totally view independent. And a pragmatic, closer
>>>>     to the view / aware of the view, application model as an mediator.
>>>>
>>>>
>>>>
>>>>                     I think it is better for the View to start it all.
>>>>
>>>>
>>>>                 +1
>>>>
>>>>
>>>>             I prefer to model an Application concept in the target
>>>>             desktop environment if I want to model highly portable 
>>>> stuff.
>>>>
>>>>             That application concern can be folded into a dedicated
>>>>             view if that is the preferred convention in the target
>>>>             environment.
>>>>
>>>>             Regards,
>>>>
>>>>             Thierry
>>>>
>>>>
>>>>         I wonder how would this result in practice. Do you have some
>>>>         examples to share?
>>>>
>>>>
>>>>     I have a complex example, a system browser, would that fit?
>>>
>>>     Sure.
>>>
>>>
>>> Well, a short estimate on that particular application is that, linked
>>> with the pluggable morphs, 10 to 20% of the code in the application
>>> model is:
>>> - widget creation, setup, layout
>>> - dynamic morph addition / removal when activating certain functions
>>> on the model
>>> - workarounds the pluggable morphs api to:
>>>   - dynamically refresh parts of the inside of widgets
>>>   - disconnect then reconnect links between widgets so that the
>>> model-triggered update of one does not change the state of the other
>>> one (i.e. protect the model from unwanted view triggered updates when
>>> the model is changing part of its contents).
>>
>> "View model" is a bit a misleading name. I'd say all this belongs in the
>> Views world.
>
> As I said, it may be moved into the View world, in the sense that it 
> holds view-related concerns. But, at the same time, it has Model like 
> decoupling from the Views.

Yep (as I said above).

>
>> Besides, the method called to update Views after Model changes should
>> not modify the Model. In this way, there would be no extra Model events
>> triggered, and spurious updates would not occur. This might require
>> enhancing the Views framework, if not mature enough.
>
> I'll let you have a try at that :)

Of course. In my experience, these kinds of problems always made the 
framework evolve. Yes, it is important to be able to fix and enhance the 
frameworks you use!

>
>>>
>>> This application model uses mainly two widgets.
>>>
>>> I do have a long term plan to port that to Cuis, and I expect I will
>>> have to write that very same code somewhere (maybe more, maybe less).
>>>
>>> Regards,
>>>
>>> Thierry
>>
>> Hopefully, it will be less :)
>
> I'm certainly looking forward to it.
>
> Regards,
>
> Thierry
>

Thanks for the discussion Thierry. I think we essentially agree on the 
important parts here.

Cheers,
Juan Vuletich




More information about the Cuis mailing list