Hi Matthieu,

>> I would wager that in most situations, this is the level of abstraction that 
>> is most useful for a developer or system operator (and definitely for an 
>> application assembler). The only time a package or class level is necessary 
>> is when actually making changes to the code.

> Let me disagree. 

Yes, please. :-)


> Guice is a technology we use but it is not mandatory, we could change
> this part of James tomorrow if we want, it's an implementation concern.

I completely agree with this statement. Just to show to what extent I agree, 
allow me to even add to your statement.

It could be Spring, OSGi, or whatever. It just happens to be Guice. Guice isn’t 
even the implementation, it is just the framework code that wraps the 
implementation, so I would argue that “Guice” is even lower-level and less 
important than what you are stating. I have no argument at all with this idea.

The only point of Guice, as far as I can tell, is to inject implementations 
into APIs. If it were in OSGi, it would be the service object. I am sure that 
the principle is much the same in most frameworks.

The reason I was dwelling on the Guice Components is because I am unable to 
figure out what the API of the domain model is, and the API interfaces should 
have a very clear 1:1 correspondence with the James model. (Actually, I usually 
tend to think that the API **is** the model, expressed in code.)

Since I am having a hard time with understanding the code base, I thought I 
could use the Guice Components as a proxy for the domain model. My thinking is 
that in general terms, given a domain concept, there will be one or more 
interfaces, and for each of these, there will be an implementation. For each of 
those, it will be wrapped as a Guice Module. So by understanding the Guice 
Modules, I should be able to work my way back to the domain model and 
eventually understand what is going on in the code.

So I thought it was a safe assumption to give me at least a starting point as 
to where to eat this elephant.

But reading below, I see that our ideas of what is API vs. implementation seem 
to be a little different...


> Basically, you have:
> 
> * `domain cores` (say managing emails and mailboxes, managing users)
> that implement the important domain logic

Ok, sounds good. If I could understand better what these “cores” are and where 
they are represented in the code, that would already give me a start.


> * `ports` that define some APIs required for `domain cores` (mailbox-
> api is a port)

Ok, this is interesting because it is exactly the opposite approach from what I 
am used to. :-)

I am used to designing the API first. Since the API is exposed to the outside, 
it usually requires a lot of thought. Then an implementation gets built that 
satisfies the API. Since the implementation is “private”, it can be changed or 
updated whenever necessary (or there can even be multiple implementations at 
once), so it doesn’t require quite as much thought as the API. Definitely the 
API should remain as stable as possible, as changing it affects all of its 
users.

It sounds from your description that the implementation (core) is done first, 
then the API is more of an afterthought.

Or did I misunderstand?

> * `adapters` that provides the implementation of a `port` (mailbox-
> cassandra)

But if mailbox is a “core” component implementation, that has an adapter, and 
also has multiple other implementations… Sorry, I’m a bit confused. Maybe an 
image would help?


> When we define a `port` API we provide a contract testsuite to check
> that the implementations will work well plugged-in.

Yeah… like I said, this is backwards from what I am used to. :-)

My fear is: if the API is just an afterthought that is placed over the 
implementation, how do you know if it was well designed?


> So to come back to the analysis: the right level of abstraction for
> James architecture is these three entities.

Those sounds like very abstract architectural entities to me, something like a 
“database table” or a “queue” or some other general construct. Or am I 
misunderstanding?

In my mind, if you were to say that they are just “categories” of actual James 
entities, perhaps that would make more sense to me. For example: “A Mailbox is 
a core entity in the James domain, and happens to be one of the core entities” 
makes sense to me, but it is the Mailbox that is the entity, not “a core” that 
is an entity. Does that make sense? Or again, am I completely misunderstanding 
what you are trying to say?


> Unfortunately, there's not way to visualize the hexagons from the code
> right now.

:-)

Ok, that should be our objective I guess, then. The code should match the 
domain model, so it should be easy to find our way around in the code.


> Finally, I see Guice module documentation as a problem: we usually
> document things that are supposed to last. Documentation reduces the
> ability to refactor things.

Yes, that makes sense. Really it should be the API that is documented, as 
normally (again from my experience) the API is the representation of the domain 
model in code.


> As Guice modules are technical classes, I would not like to be
> refrained from refactorings because of this documentation.

Completely agree!!


> It's why I think we have to find a way to document `ports` and
> `adapters` because they are definitely more stable.

I agree with this statement, notwithstanding the things above that I said I was 
having trouble understanding.

If you could give me a list of the cores, ports, and adapters, I’ll see what I 
can do with that, and perhaps make progress in my understanding of the code 
base.


Cheers,
=David



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org
For additional commands, e-mail: server-dev-h...@james.apache.org

Reply via email to