3

is is possible to do end up with something like this:

    ServiceChild (class) extends (or only partial implements) Service and overrides sayHello
    Service (interface) implements hello,goodbye

    Hello (has a mixin HelloMixin) has method sayHello
    Goodbye (has a mixin GoodbyeMixin) has method sayGoodbye

I've tried doing the above using the concern approach in ServiceChild

    public class ServiceChild extends ConcernOf<Service> implements Hello 
 {

    @Override
    public String sayHello() {
     return "Rulle Pharfar";
    }
 }

However using this approach only the Hello implementation are detected by java and not the rest of the stuff from the Service class. So is there any other approach that would work?

eskatos
  • 4,174
  • 2
  • 40
  • 42

2 Answers2

2

I'm not sure I understand what you are trying to do, but a concern should more be seen as a wrapper around the original implementation of the class it is a concern of. As the documentation states:

A concern is a stateless Fragment, shared between invocations, that acts as an interceptor of the call to the Mixin.

And would usually do this:

//Given interface MyStuff
@Mixins( MyStuff.Mixin.class )
@Concerns( MyStuffConcern.class )
public interface MyStuff
{
    public void doStuff();

    abstract class Mixin implements MyStuff
    {
       public void doStuff()
       {
          System.out.println( "Doing original stuff." );
       }
    }
}

public class MyStuffConcern extends ConcernOf<MyStuff>
   implements MyStuff
{
   public void doStuff()
   {
     // if I want to do anything before going down the call chain I'll do it here
     System.out.println( "Doing stuff before original." );

     // calling the next concern or actual implementation
     next.doStuff();

     // anything to do after calling down the call chain - here is the place for it
     System.out.println( "Doing stuff after original." );
   }
}

But nevertheless if you have a concern on a interface you should also implement said interface:

public abstract class ServiceChild extends ConcernOf<Service> implements Service
{
   public String sayHello()
   {
       return "Rulle Pharfar";
   }
}

Hope this helped.

arvidhuss
  • 21
  • 2
2

I also don't fully understand the question.

As Arvice says, Concerns are the equivalent of around-advice in AOP, with much more precise pointcut semantics. Although it is technically correct that a concern 'wraps' the underlying concerns/mixins, I prefer to not thinking of it as a 'wrapper' but an 'interceptor'. It is the incoming call that is handled. Conceptually slightly different, and it may not work for everyone.

It is also possible that both Concerns (stateless) and Mixins (stateful) implements only a subset of the methods in the interface they override, simply by making the class 'abstract'. Qi4j will fill in the missing (and unused) method calls. And any combination may be used.

Further, well implemented concerns should call the 'next', because they should be unaware of their actual uses. If the concerns are expected to take care of the method call. There must be a Mixin for each composite type method, or assembly will fail.

So in short; 1. A Mixin implementation may implement zero (a.k.a private mixins), one or more methods of the composite type interface. 2. A Concern may implement one or more methods of the composite type interface.

It is also interesting to note that when a class (mixin or concern) calls one of its own methods that are in the composite type interface, the call will not be intra-class, but call the composite from the outside, so the entire call stack is invoked, to ensure that an internal call and an external call are identical in results. Patterns exists if this needs to be bypassed.

Niclas Hedhman
  • 584
  • 4
  • 14