On 5/29/07, Vincent Massol <[email protected]> wrote:
Some more details on this topic:
* We should have a consistent naming. Either we use XObjects/XClass and then we have to use X in front of everything: XFarm, XWiki (funny), XSpace, XDocument, etc or we agree that the namespace is enough (org.xwiki.model) to indicate that these are all XWiki classes and we drop the X. This is my preference. When we write documentation we can refer to XObjects/XClass/ to separate them from Java Objects/ Class though.
I'm for the second option, with the minor objection that I don't like having an Object class. Name collision with the most used class in the Java world. But I can deal with this inconvenience.
* Here's a cardinality and dependency graph of main model classes:
(Farm) 1 --> * (Wiki) 1 --> * (Space) 1 --> * (Document) 1 --> * (Object) 1 --> * (Property)
There's also: (Document) 1 --> 0..1 (Class) 1 --> * (PropertyDefinition) 1 --> 1 (PropertyMeta) 1 --> * (PropertyDefinition) 1 --> * (primitives [string, int]) This is the current model, and it might need adjustments. For example, the PropertyMeta can only be defined in the Java world in this model, and we'd like to change this.
* I want to come back on something I said in the email below. I said the Model classes shouldn't depend on any other component. I don't think this is true anymore. The reason is that I think we need to model the cardinality defined above in the model classes. For example:
Farm: - addWiki(Wiki wiki) - removeWiki(String wikiName) - List getWikis() - Wiki getWiki(String wikiName)
Wiki: - addSpace(Space space) - removeSpace(String spaceName) - List getSpaces() - Space getSpace(String spaceName) - Farm getFarm()
Space: - addDocument(Document document) - removeDocument(String documentName) - List getDocuments() - Document getDocument(String documentName) - Wiki getWiki()
The same applies to Document and Object.
Now the interesting part is what happens for example when Space.getDocuments() is called? The user will expect that it returns the lists of documents in the space. This requires access to the storage component. Thus I now believe we should have the model classes have the storage component injected. The alternative is either to not have the above-defined methods in the model classes (which I think would be a pity) or have some external services to load the data in the model objects. But that's tricky because it would mean loading the whole object graph at once or doing some tricky transparent lazy loading. Thus my preference goes to adding a dependency to the storage component in the model classes.
Here's something I don't like in the current core: $xwiki.getDocument("Some.Doc").getObject("Some.Class", 13) When calling this, the document, along with all its attachments, objects, class, is completely restored from the database. If there are 500 objects, and I'm only interested in number 13, there's a complete waste of time and memory. We should consider this when deciding how do we retrieve stuff from the storage. Lazy types are not good, as they are storage dependent. Hibernate has this feature, but how about XML Database servers, or JCR? We'd probably have to write our own storage-dependent wrappers. On the other hand, I'd like *not* to have a storage dependency inside the model classes. The model should only contain data. Pros and cons of lazy loading data: Pros - We can reduce the amount of time/memory needed to load a document - There's no dependency on the storage inside the model Cons - We need an intermediate between storage and model (decorator?) - We might have to write the intermediate along with the storage, as not all storage systems support lazy loading. This is not as bad as it looks, because basically we're moving storage.load() from a model class to a decorator class, and the decorator can be storage-dependent. Can we use JPOX ( http://www.jpox.org/ ) as the decorator for some storage systems? Should we?
* Now we'll want to cache data instead of hitting the database every time. We could do this in several ways: using the database cache, using a delegating caching storage implementation or doing the caching in the model classes themselves using a caching service. I'm not sure here but a delegation at the level of the storage component sounds nicer to me at first glance.
+1 for the storage cache. The data model should not be concerned with caching.
WDYT?
Thanks -Vincent
On May 28, 2007, at 9:38 AM, Vincent Massol wrote:
Hi,
Starting from today I'm going to spend some time every week on the V2 Architecture/Redesign. Today I'd like to start at the heart of the topic with the domain model. Here's my proposal:
* Model classes are classes representing the XWiki model. The main classes are: - Farm - Wiki - Space - Document - XObject - XClass - (probably lots of others) * As you can see I'd like to introduce the Space and Farm objects * We create a model/ build module in trunks-devs/xwiki/model for storing model classes * Model classes cannot access other classes outside of the model/ module. They are meant to be used by components to provide services but they shouldn't provide services themselves. They can methods to manipulate their fields and they can call each other but they cannot call outside of their model. * We use the org.xwiki.model package for storing Model classes * These model classes are all user public (API)
WDYT?
Barring any negative feedback I'll start implementing this today and in the coming days. One question that remains unanswered in my mind is how do we integrate back these model classes into the V1 architecture. I think we should be able to retrofit the existing classes to use these classes by composition. For example the Document object could have 2 fields: one org.xwiki.model.Document and one org.xwiki.model.Space. The XWiki object could have 2 fields: Wiki and Farm, etc. I'm not sure how this would work out though. Any idea is welcome.
Thanks -Vincent
Sergiu -- http://purl.org/net/sergiu