On Tue, Dec 21, 2010 at 9:34 AM, Sandro Martini
<[email protected]> wrote:

> In any case, thank you very much.

I don't have energy to look into this right now, but I'll defer it
until after the New Year, when my family has gone back to Malaysia and
I have more spare time in the evenings and weekends.


> Uh, a last thing: you give me a link to QI4J, how to make an
> application (or something similar) ... I started to look at it better,
> and I think that's really interesting, only I have to understand
> better how I could use it in my work and in my experiments (maybe even
> with Pivot) ... why not in the near future ?

I am not sure what you are asking here...
"How" you can use Qi4j is a lot about "What" you want to do.

There are quite a few of underlying concepts in Qi4j, which then can
be utilized for higher level patterns, such as HATEOAS, Event Sourcing
and DCI.

But if you know about AOP at a high level, we have borrowed a lot of
ideas from there, but without letting go of type-safety nor straying
from Java syntax. AOP also have 'base object' to which you apply
advice via point-cuts. We find the base object unnecessary and that
point cut expressions are very awkward, fragile and unsafe. Instead
(in the area of AOP), we create interceptors which normally expressed
in the same interface. Example;

public interface Hello
{
    String sayHello();
}

We provide an implementation of this method (don't need to put the
implementation of the entire interface in the same class in Qi4j);

public class HelloMixin
     implements Hello
{
    public String sayHello()
    {
        return "Hello";
    }
}

And now assume this is a service, so we bind the implementation to the
interface;

@Mixins( HelloMixin.class )
public interface HelloService extends Hello, ServiceComposite
{}

Somewhere else in my code I can inject this Service, like so;

@Service private Hello hello;

and if I call
 hello.sayHello();
a "Hello" will return.

If I then want to add a concern that 'adds' a "World", I do this;

@Concerns( WorldConcern.class )
@Mixins( HelloMixin.class )
public interface HelloService extends Hello, ServiceComposite
{}

public class WorldConcern extends ConcernOf<Hello>
    implements Hello
{
    public String sayHello()
    {
        return next.sayHello() + " World!";
    }
}

and if I now run the same hello.sayHello() above, "Hello World!" will
be returned. The "next" is field member in the ConcernOf super class,
but that is simply an injected reference to the next object in the
interceptor chain (we call it invocation stack), in this case the
Mixin at the bottom.

Let's say that "World" shouldn't be static. So, I add an interface
containing a property with the phrase;

public interface Greeting
{
    @UseDefaults
    Property<String> phrase();
}

Note; Properties in Qi4j are explicit types, with set() and get()
methods, as well as can have additional meta Information++.
@UseDefaults is saying that initialize the property to the default
value (which by default is an empty string, but can be manipulated).

@Concerns( WorldConcern.class )
@Mixins( HelloMixin.class )
public interface HelloService extends Hello, Greeting, ServiceComposite
{}

And I change the concern to

public class WorldConcern extends ConcernOf<Hello>
    implements Hello
{
    @This
    private Greeting greeting;

    public String sayHello()
    {
        return next.sayHello() + " " + greeting.phrase().get();
    }
}


Now I can declare somewhere;

@Service Greeting greeting;

and do
    greeting.phrase().set( "Universe!" );


So that covers the basic AOP-like behavior. Additional to the above is
that you can have SideEffects which are executed after the method is
completed, and you can have Constraints that validates the method
arguments prior to the method call enters the composite.


On top of that we have built-in persistence, so that we explicitly
support Entity, Association and ManyAssociation as types. For
instance;

public interface PersonState
{
    @Optional
    Association<Person> currentSpouse();

    ManyAssociation<Person> children();
}

@Optional is required everywhere you explicitly allow 'null'. This
includes Property, Association, method arguments and managed
constructors.

Association is referencing another Entity, but Person is not declared
as an Entity.... yet. So we typically do

public interface PersonEntity extends PersonState, EntityComposite
{}

but often, we don't want the internal state to be exposed in the
public interfaces, so we can hide the state.

public interface Person
{
    void gotMarried( Person spouse );
    Person currentSpouse();
    List<Person> children();
}

@Mixins( { PersonMixin.class, MarriageMixin.class })
public PersonEntity extends Person, EntityComposite
{}

public abstract class PersonMixin
    implements Person
{
    @This private PersonState state;

    public Person currentSpouse()
    {
        return state.currentSpouse().get();
    }

    public List<Person> children()
    {
        return state.children().toList();
    }
}

public abstract class MarriageMixin
    implements Person
{
    public void gotMarried( Person newSpouse )
    {
        state.currentSpouse().set( newSpouse );
    }
}

So, here note that one mixin implements two methods and the other
implementing one, yet Qi4j's runtime will bind the whole thing
together.

These are entities, which are modified within a UnitOfWork, which is a
kind of transaction, with isolation, concurrent modification detection
and more. So, at the transaction boundary we create a new UnitOfWork,
and if we need anything from the entity store, we pick up the current
unit of work and do our operations. But since we can also have
"generic concerns" (implementing InvocationHandler) we can make that
once and for all, and use annotations to indicate the uses.

This will lead into a lot of Entity related features in Qi4j.
Associations can be aggregated, UseCase can be declared, a built-in
Query language (in Java), and application Structures.


I suggest that after you have some clue about the above, that you take
a look at http://www.qi4j.org/qi4j/introduction.html and then perhaps
at some of the tutorials http://www.qi4j.org/qi4j/146.html


Always available to answer any specific questions, but you can also
leverage the Qi4j mailing list (see CC)



Cheers
-- 
Niclas Hedhman, Software Developer
http://www.qi4j.org - New Energy for Java

I live here; http://tinyurl.com/3xugrbk
I work here; http://tinyurl.com/24svnvk
I relax here; http://tinyurl.com/2cgsug

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to