Why do you need to implement an interface as opposed to extend an abstract class when most of the methods are simple getters/setter pairs? This is a very common pattern in found in Servlets, Struts, WebWork, Srping and Hibernate, to name just a few. It allows people to progressively buy into an extension API, picking up complexity as needed.

If one wants maximum control, I still think things are very simple, and this is exactly why I don't like counting methods without going through what they are intended to do:


public class FooAllAtomicComponent implements AtomicComponent<Object> {

    public boolean isEagerInit() {
        return false;
    }

    public void init(Object instance) throws TargetException {

    }

    public void destroy(Object instance) throws TargetException {

    }

    public Object createInstance() throws ObjectCreationException {
        return null;
    }

public Object getServiceInstance(String name) throws TargetException {
        return null;
    }

    public List<Class<?>> getServiceInterfaces() {
        return null;
    }

    public void addInboundWire(InboundWire wire) {

    }

    public InboundWire getInboundWire(String serviceName) {
        return null;
    }

    public void addOutboundWire(OutboundWire wire) {

    }

public void addOutboundWires(Class<?> multiplicityClass, List<OutboundWire> wires) {

    }

    public Map<String, List<OutboundWire>> getOutboundWires() {
        return null;
    }

public TargetInvoker createTargetInvoker(String serviceName, Method operation) {
        return null;
    }

    public String getName() {
        return null;
    }

    public CompositeComponent getParent() {
        return null;
    }

    public Scope getScope() {
        return null;
    }

    public Object getServiceInstance() throws TargetException {
        return null;
    }

    public void prepare() {

    }

    public void publish(Event object) {

    }

    public void addListener(RuntimeEventListener listener) {

    }

public void addListener(EventFilter filter, RuntimeEventListener listener) {

    }

    public void removeListener(RuntimeEventListener listener) {

    }

    public int getLifecycleState() {
        return 0;
    }

    public void start() throws CoreRuntimeException {

    }

    public void stop() throws CoreRuntimeException {

    }

Going in order:

        - init/destroy initialize and destroy an instance
- createInstance(), getServiceInstance(String name) getServiceInterfaces(), createTargetInvoker() are the same as before - addInboundWire(InboundWire wire) adds an inbound wire to the component - addOutboundWire(OutboundWire wire), addOutboundWires(Class<?> multiplicityClass, List<OutboundWire> wires) provide the outbound wires to the component
        - getOutboundWires()  returns the outbound wire
        - getName() returns the component name
        - getParent()  returns the composite parent
        - getScope() returns the component scope

        - getServiceInstance() returns a default service instance
- prepare() is a callback to signal that the component has been configured and should "prepare" itself to receive invocations - publish(Event object), addListener(RuntimeEventListener listener), addListener(EventFilter filter, RuntimeEventListener listener), removeListener(RuntimeEventListener listener) provide listener services particularly useful to composites - getLifecycleState() returns the state of the component, e.g. initializing, etc.
        - start() and stop() are callbacks issued by the runtime

All of these methods deal directly with a component and are very easy to implement. I don't see the need to Balkanize the API. Which of these methods do you think can be broken out?

Jim



        
On Jun 21, 2006, at 2:08 AM, Jean-Sebastien Delfino wrote:

Jim Marino wrote:
I think you missed something. With core2, most people will extend from the helper abstract classes in the SPI extension package (this was also the case with the previous core). For example:

I didn't miss this class, as I said that's exactly what I'm trying to avoid. I want to implement the SPI interfaces without having to extend base implementation classes.


public class FooAtomicComponent extends AtomicComponentExtension<Object>{

public FooAtomicComponent(String name, CompositeComponent<?> parent, ScopeContainer scopeContainer, WireService wireService) {
        super(name, parent, scopeContainer, wireService);
    }

    public Object getServiceInstance() throws TargetException {
        return null;
    }

    public Object createInstance() throws ObjectCreationException {
        return null;
    }

public Object getServiceInstance(String name) throws TargetException {
        return null;
    }

    public List<Class<?>> getServiceInterfaces() {
        return null;
    }

public TargetInvoker createTargetInvoker(String serviceName, Method operation) {
        return null;
    }
}

I generally don't like to "count" methods without looking at what they do (e.g. some could just be setter/getter types). The above class contains 5 methods, which I believe are reasonable and we don't want to separate out. Invoker is very simple too:

- Two methods to invoke, one for "message" invocations, and one for raw payloads. Generally, the first will just pull the payload and invoke the second
- A setter/getter pair for whether the invocation is cacheable
- A boolean if the invoker can be optimized away and the target can be called through straight invocation without a proxy. Generally false.
- A clone method

The Spring and Groovy samples in the sandbox demonstrate both of these.

Jim



On Jun 21, 2006, at 1:37 AM, Jean-Sebastien Delfino wrote:

I'm trying to implement the sample ruby extension and running into some issues.

I'm implementing an AtomicComponentContext (with the code in the head stream) and also trying the equivalent AtomicComponent with some of the code in the sandbox. I want to be able to implement my extension class without having to depend on base Tuscany runtime implementation classes, so I'm just implementing the SPI interfaces.

Unless I missed something (and it's very possible since I don't understand all the pieces yet) here's what I found: - with the code in the head, my AtomicComponentContext needs to implement 15 methods;
- with the code in the sandbox, I have to implement 25 methods.

And this is just one class, I'm not even implementing the builders or invokers yet... I think that in both cases this is too much.

It looks like the experiment in the sandbox is attempting to provide a simpler programming model for these extensions by hiding some of the complexity in base implementation classes, but I think it will be better to define a set of independent interfaces and make some of them optional. In other words if my extension does not wish to implement one of the interfaces, then it just doesn't need to, and the runtime should assume some default behavior, instead of forcing me to implement all the 25 methods...

Another thought is to allow the contract to be implemented with multiple objects specialized in each aspect instead of one big object with 25 methods.

As I'm going through the implementation of the ruby component implementation extension, I'm trying to come up with a short list of requirements and methods that I think we really need to implement, and with that list I'd like us to prototype simpler SPI interfaces. If anybody is interested in helping, please feel free to jump in, it would really be great if we could do a binding extension in parallel, and also if the people who actually developed some of the existing extensions could come up with the requirements they've seen in terms of SPI and proposals to improve our extensibility story.

Thanks,

--Jean-Sebastien


-------------------------------------------------------------------- -
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--
Jean-Sebastien


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to