On 5/29/07, Vincent Massol <vincent(a)massol.net> 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