PureMVC Architects Lounge

Announcements and General Discussion => General Discussion => Topic started by: coulix on November 11, 2009, 12:02:50

Title: Board Architecture, refactoring and planning
Post by: coulix on November 11, 2009, 12:02:50
Greetings Architects  ;D

I want to re-factorise some of my code (edoboard.com) as i am starting to feel the need for a better architecture and i realised i was doing many things badly even within the boundaries PureMVC (mixing mediator and proxy roles, not enough commands and so on.

Here is a simplified diagram of the current classes.
http://i34.tinypic.com/24fxuft.png (http://i34.tinypic.com/24fxuft.png)


On the view side i have Tabs, each Tab holding a Canvas where i can draw and manipulate shapes.

Therefore we have a BoardManagerMediator handling the following actions: close tab, add tab, duplicate tab. It also keeps reference to a proxy called BoardManagerProxy.

BoardManagerProxy keeps a list of BoardMediators (one boardMediator = one tab).
It also have attributes like 'currentBoardMediator' 'currentShape' 'selectedShapes' ...

1.Is it the good place to hold these  ?
2.What about the naming, does it make sense ?


When i add a shape the BoardMediator i s responsible for listening to the mouse down / move / up events. It looks in a toolbarProxy to see the current selected shape and starts drawing it on mouse down.

That is just  the instantiation of a Circle Shape and resizing its width/height on mouse move until a mouse up.

On mouse up the boardMediator pushes the shape to Shape list boardProxy, and send a Notification (with the new shape as the body) to the BoardManagerMediator.

The boardManagerMediator update the current Shape attribute on its boardManagerProxy. The shapeid counter (boardManagerProxy) is also incremented.

3. I definitely forgot a lot of things but is there any big architecture flaws so far ?

Each Shape needs a mediator and a Model (proxy) ?.

Sample of a simpleShapeModel


package com.roguedevelopment.objecthandles.example
import com.roguedevelopment.objecthandles.IMoveable;
import com.roguedevelopment.objecthandles.IResizeable;

public class SimpleDataModel implements IResizeable, IMoveable
[Bindable] public var x:Number = 10;
[Bindable] public var y:Number  = 10;
[Bindable] public var height:Number = 50;
[Bindable] public var width:Number = 50;
[Bindable] public var rotation:Number = 0;

Should the proxy hold the model ? Or should the model be also a proxy ?

Actually i need a minimalist mediator since all rotation/move stuff are handled by an external library (objecthandle).

My mediator will just keep a reference to the model and offers functions like update fill color, opacity etc. These functions will be called by the boardMediator. we do not want all shapes to listen for the update color notification and check if its for them.

So at the end my boardProxy will hold a list of ShapeMediator ?

Multi selection

I want to redo my multi selection to handle ctrl key to remove a shape from a selection and shift to add one. I was going to do it from the shape mediator.

The shape know when it receives a mouse down event with ctrl/shift key activated. That means all shapes listen for ctrl/shift key ?

It then fires an event like 'add_to_selection_group' which is catch by the boardMediator. The boardMediator send a addShapeToGroupCommand

Maybe it is at the boardMediatorManager level that we should look for the ctrl/shift key ?

Anyway our addShapeToGroupCommand will get a hand on the currentBoardMediator from boardManagerProxy and manipulate it to redraw the selection area, and update the boardManagerMediator proxy selectedShapes attribute.

That is way too long and maybe not very intelligible, but i have no occasion to share these design questions :)

Looking to have some good design i can be happy to look at.

Thanks !


Title: Re: Board Architecture, refactoring and planning
Post by: puremvc on November 13, 2009, 12:59:58
Hi Greg,

Sorry to take so long getting to this. Massive posts like this take quite a bit of time to respond to.

First, the 'BoardManagerMediator' seems overloaded, and the very name tells you this. Its a Mediator not a Manager. It shouldn't be creating and duplicating tabs in a view component, that should be happening inside the component itself. The Mediator's role is one of communication. The view component should encapsulate its internal workings. If the mediator needs to communicate to the view component that it should create a new tab, then the view component might expose a method that the mediator calls when a given notification is received. This hides the implementation of the component and makes it portable. The view component should stand alone, usable without PureMVC.

Next, if Shapes are view components, proxies should not be managing them. Proxies are for holding elements of the Domain Model, not the View. A proxy might hold the data that describes a shape, but not the shape itself. Use a Command to create a shape from the data and send it by notification to a mediator for addition to the view.

And things like dragging and multiple selection are strictly view stuff. Mediators don't need to participate in that. Again, think if the view component would work without its Mediator. Any class can supply it data, or view components to be added to its hierarchy, but if you're putting something like selection handling into the Mediator, then you have coupled the component to the framework too tightly; something we want to avoid.


Title: Re: Board Architecture, refactoring and planning
Post by: coulix on November 14, 2009, 10:42:17
Thank you for taking the time to answer my post !

It's quite interesting, let's take for now the current way copy paste work:  http://screenr.com/AvB

Application mediator listen for ctrl c/ctrl v
catch ctrl c and starts a copyShapesCommand
Command look into currentBoardProxy BoardProxy for selectedShapes arraycollection.
It clones those to copyShapes in currentBoardProxy

Look into currentBoardProxy for copyShapes
Get the bounded box coordinates around all shapes (w,y,width, height) on the current BoardView.
Activate copy shapes select skin
Push the current copyShapes to boardProxy selectedShapes.
Tellsthe BoardMediator to draw the multiselectArea on the boardView.

I guess i indeed coupled my BoardView and BoardMediator too much. The 'bounded select box' should be drawn by my view not the mediator !
Gonna do some re-factoring for next versions !

This board app is very good to plan a good architecture.


Title: Re: Board Architecture, refactoring and planning
Post by: coulix on November 14, 2009, 01:07:26
Can a view component be a dynamic canvas created at run time ?

Title: Re: Board Architecture, refactoring and planning
Post by: puremvc on November 14, 2009, 04:55:18
Certainly. Check out the Pipeworks and Modularity MultiCore demos. The children are created and added to the view hierarchy dynamically.


Title: Re: Board Architecture, refactoring and planning
Post by: coulix on November 17, 2009, 12:05:07
Thanks i made it dynamic all good.

An other ( ;D) question bothering me.

I have a boardview (canvas) with shapes drawn on it.
I keep drawn shapes in a boardProxy shapeList arrayCollection. They are just a copy of the real shapes attached to the canvas on the view.

Now, i draw a selectArea on the board ==> View action.
Then i detect the shapes inside this area: i look for all shapes from the boardProxy that have x,y,... matching the inner area of my selectArea surface ===> This happen in the mediator since i need to get the shapes from the proxy.
All shapes matching are added to selectedShape ArrayCollection in the boardProxy.

If i want to detect mouse down on the group selectArea surface i will have to do it in the mediator again. On click down i have to 'copy' all Selected Shapes positions for proper positionnement on mouveMove:

shape.x = originalePos.x + (dest.x - localClickPoint.x);               
shape.y = originalePos.y + (dest.y - localClickPoint.y);

So basically it is Visual but it requires boardProxy to get the List of Selected Shapes.

Should i have my onMultiSelectAreaMouseUP / DOWN / MOVE in my View taking a mouseEvent AND a shape Array Collection as an extra parameter ?

Should i keep those in the mediator ? Accessing and Manipulating the view components from getViewComp() ?

I am trying to give more responsibilities to my views, i was doing to much view work in the mediator.

Thank you for your time,


Title: Re: Board Architecture, refactoring and planning
Post by: puremvc on November 18, 2009, 09:17:30
You don't really want to keep visual objects in a Proxy. Its job is to represent the domain model, which might be the information about the shapes but not the shapes themselves.

When and where is this collection of shapes actually needed. The colleciton exists in the component, why must the shapes themselves be copied elsewhere?