Seaside best practices

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Seaside best practices

Stephan Eggermont-3
On twitter, Van Von Vandelay asked me to elaborate on
best practices for Seaside, referring to my post of april 2012:
> Create a declarative description of the domain model;
>  Magritte provides a good starting point. You need better
>  descriptions for behavior, relationships, validation.

"You need better" should of course be read as: I have been
in a situation where I would have liked to have. The context
was a system with a domain model of somewhat over
100 domain classes and a similar number of
WAComponent subclasses. Deltawerken can be seen as
an extraction of the non-domain specific parts of that application.

Describing behavior

In NakedObjects (currently Apache Isis), actions are described.
Zero parameter actions are mapped to buttons for the (view of the) object.
One parameter actions are mapped to drag-and-drop of one object onto the
other. When there are multiple possibilities, a modal dialog is shown
to let the user select the appropriate action. Magritte doesn't focus on
describing these, but adding description subclasses (MAActionDescription) is easy.

Describing relationships

Currently, Magritte relationship descriptions only refer to the class of
acceptable objects, not to a source of acceptable objects. There is also
no way to describe inverse relationships, where on one side a to-one
relationship belongs to a to-many on the other class. Being able to
describe relationships with temporal patterns would be useful too.
There is nothing in Magritte that would it make difficult to add these
features.

Validation

Validating objects in Magritte can be complex because you often
need access to the underlying object, not the memento.
Unit tests can be used as a way to describe validations.

Stephan


_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Seaside best practices

Stephan Eggermont-3
(Stephan: I've asked Diego for some comments too. Here is the first part)

Lately I have worked with Magritte, and being one of the authors of Deltawerken, I probably should make a mail about the advantages and disadvantages of both libraries.

Magritte is a library that is really good in describing  an object. You can see it is created from a theoretical perspective, with a consistent and systematic way of implementing all functionality.

However this creates at some points difficult indirections. These indirections make the code (at some points) hard to understand. A good example is the code I added for my project to the root object:
descriptionContainer: aContainer
        <magritteContainer>
        ^ aContainer
                componentRenderer: QCFormRenderer;
                stringWriter: QCLabelWriter;
                yourself
This code is of course very compact, and for those proficient with Magritte, this code may be understandably. But most people will be confused by this code. Some explanation for those who want to follow:
        > it is intended to render the form in the way I want, with the styles I want. This means that I render divs instead of a table and have a different "toString" method when an object of mine is converted to a String.
        > This method is executed by the pragmabuilder, that builds the description. It sets 2 properties to the container, that override the default values for the container description. When rendering it asks for a component renderer to render the component, and thus will use the QCFormRenderer to do so. When asked to convert to string, it will use the stringWriter to do this.

Also a lot of features are implemented using "monkey patching". The most known is the asComponent, that is implemented in Object.
Personally I am not a fan of monkey patching, but using Magritte will force you into monkey patching the Magritte classes. You will need custom properties, if you want to do some more advanced stuff with Magritte. Inheriting is not really recommended, as you will need to inherit from all types to do so.


_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Seaside best practices (part 2)

DiegoLont
> Also a lot of features are implemented using "monkey patching". The most known is the asComponent, that is implemented in Object.
> Personally I am not a fan of monkey patching, but using Magritte will force you into monkey patching the Magritte classes. You will need custom properties, if you want to do some more advanced stuff with Magritte. Inheriting is not really recommended, as you will need to inherit from all types to do so.

These features allow for a very powerful way of modifying Magritte, without actually needing to change Magritte itself. For instance I have made groups "collapsable" and "ajax aware". When clicking on the title, it only displays the title. And on each change in the group, it re-renders the group, so that dependent values also update (*). I.e. when you change a customer, the list of possible addresses also changes. This is done by only adding a few methods:
First I have set a custom form renderer (see part 1) for all objects. In this form renderer I implemented the
        renderElement: aDescription
In this method I use quite a lot of other methods as well, since this one is a bit complex. First of all I check if it is a group, if so, I delay the rendering until the group is finished. In the group I generate a update script that re-renders the entire group when necessary and in the end I call the method:
        renderContentOn: ajaxScript:
This method did not exist, but I added this method to the MADescriptionComponent, and the MAElementComponent. It adds the ajaxScript as a parameter, allowing the different input types to couple this script on the correct event.

This way I stay compatible with future updates of Magritte (I did not change any code, I only added), and have added some advanced features.

Finally I would like to end with the remark that Magritte focusses on static descriptions. Although the update from Magritte 2 to Magritte 3 allows for descriptions that depend on the state of the object, the description is still very inflexible for changes. Current components are not updated when you change the description. And the description is not updated when you change the value in the memento.

(*) Note that this implies that you need to change the values in the memento on an update. This was not a trivial exercise._______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside