Pergunta

I am creating a multiple wrappers/layers API in Java that go like this

  1. public class Layer1<T extends Layer1>
  2. public class Layer2<T extends Layer2> extends Layer1<Layer2>
  3. public class Layer3 extends Layer2<Layer3>

with methods like public T sees(){ return (T) this;} within each layer

What is the correct way for the above structure to work as to be able to maintain the original object's, we start the chain with, type throughout the call. Aka the following to be feasible: 3rdLayerObject.1stLayerMethod().2ndLayerMethod(); where the 1stLayer method call returns a 1st layer object(instead of subclass 3rd) and therefore calling a 2nd layer method returns an error.

Why the API is structured as such:

1st layer has only the methods that apply to all situations

2nd layer has client specific methods that either override the 1st wrapper's basic implementations or are entirely new

3rd layer has project specific methods that are mainly new methods used only by this project.

Of course, if you think the above structure is flawed and there is another pattern/structure to use to organize this more effectively I am open to any and all ideas.

Foi útil?

Solução

From this line only 3rdLayerObject.1stLayerMethod().2ndLayerMethod() I suspect that you may want to implement something like this:

class Layer1<T extends Layer1<T>> {
    public T layer1Method(){
        return (T)this;
    }
}

class Layer2<T extends Layer2<T>> extends Layer1<T>{
    public T layer2Method(){
        return (T)this;
    }

}

class Layer3<T extends Layer3<T>> extends Layer2<T>{
    public T layer3Method(){
        return (T)this;
    }

    public static final <U extends Layer3<U>> U newLayer3Instance(){
        return (U)new Layer3();
    }

}

So that you can perform this:

Layer3.newLayer3Instance().layer1Method().layer2Method();

I was struggling for long to get such a solution. Unfortunately in java, generics themselves are not enough. You need to add some magic also..

--- EDIT

Layer 4 would be:

class Layer4<T extends Layer4<T>> extends Layer3<T>{
    public T layer4Method(){
        System.out.println("layer4Method");
        return (T)this;
    }

    public static final <U extends Layer4<U>> U newLayer4Instance(){
        return (U)new Layer4();
    }

}

e.t.c...

Outras dicas

It does sound like ordinary inheritance. It also sounds like you think you've uncovered an ontological truth about the world in which this software lives. You have a core set of features, followed by a client specific implementation, followed by many projects at a particular client.

Sounds like a reasonable abstraction in light of your ontological commitment. Sounds like a reasonable way to organize your code.

What happens if you need want to share common code from a number of clients or projects within the same client, or even project related code across clients?

Those classes in your hierarchy won't be your units of code reuse anymore. You'll have to start moving the common functionality into other modules. That's where I would start thinking about the architecture, where the abstraction breaks down.

But maybe you never need to do the above.

Licenciado em: CC-BY-SA com atribuição
scroll top