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 |
(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 |
> 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 |
Free forum by Nabble | Edit this page |