Skip to main content
Post Reopened by Jamal
added 4 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

What's a better way to model this? Networking layer module

These two classes are part of a networking layer module that I am building:

public abstract class BaseRequest {

    protected RequestCreator mCreator;

    public BaseRequest() {
        setupRequestCreator();
    }

    private setupRequestCreator() {
        mCreator = new RequestCreator.Builder()
            .headers(getHeaders())
            .parser(getParser())
            .build();
    }

    public abstract Headers getHeaders();
    public abstract Parser getParser();
}

public class UserRequest extends BaseRequest {

    private Headers mHeaders;
    private Request<User> mRequest;

    private interface UserService {
        @GET("/users/{id}")
        User getUser(String id);
    }

    public UserRequest(Headers headers) {
        mHeaders = headers;
        mRequest = mCreator.createRequest(UserService.class);
    }

    @Override
    public Headers getHeaders() {
        return mHeaders;
    }

    @Override
    public Parser getParser() {
        return null;
    }
}

The framework that I am using requires me to configure/build a RequestCreatorRequestCreator for each type of Request that I am going to use.

To make the process of adding new classes for different requests as pain-free as possible, I moved the building logic of the RequestCreatorRequestCreator in an abstract class so this. This way I'll only have to extend it and override some methods that indicate how the RequestCreatorRequestCreator should be configured - sort of a Template Methodtemplate method pattern.

The actual problem is this: when someone creates an instance of UserRequestUserRequest, super()super() gets called right before UserRequestUserRequest's member variables are set. What this means is that the RequestCreatorRequestCreator will already be built by the time mHeadersmHeaders are set. This is wrong because the buldingbuilding process needs a reference to mHeadersmHeaders in order for it to behave as intended.

One way to get around this is to leave BaseRequestBaseRequest's constructor empty and to call setupRequestCreator()setupRequestCreator() in the UserRequestUserRequest's constructor, but only after setting the instance variables first; thisfirst. This however feels "hacky" because other people will have to be aware of this when they are creating new subclasses.

I tried other workarounds too, but nothing felt quite right. I was hoping someone could provide me with a better solution.

What's a better way to model this?

These two classes are part of a networking layer module that I am building:

public abstract class BaseRequest {

    protected RequestCreator mCreator;

    public BaseRequest() {
        setupRequestCreator();
    }

    private setupRequestCreator() {
        mCreator = new RequestCreator.Builder()
            .headers(getHeaders())
            .parser(getParser())
            .build();
    }

    public abstract Headers getHeaders();
    public abstract Parser getParser();
}

public class UserRequest extends BaseRequest {

    private Headers mHeaders;
    private Request<User> mRequest;

    private interface UserService {
        @GET("/users/{id}")
        User getUser(String id);
    }

    public UserRequest(Headers headers) {
        mHeaders = headers;
        mRequest = mCreator.createRequest(UserService.class);
    }

    @Override
    public Headers getHeaders() {
        return mHeaders;
    }

    @Override
    public Parser getParser() {
        return null;
    }
}

The framework that I am using requires me to configure/build a RequestCreator for each type of Request that I am going to use.

To make the process of adding new classes for different requests as pain-free as possible I moved the building logic of the RequestCreator in an abstract class so this way I'll only have to extend it and override some methods that indicate how the RequestCreator should be configured - sort of a Template Method pattern.

The actual problem is this: when someone creates an instance of UserRequest, super() gets called right before UserRequest's member variables are set. What this means is that the RequestCreator will already be built by the time mHeaders are set. This is wrong because the bulding process needs a reference to mHeaders in order for it to behave as intended.

One way to get around this is to leave BaseRequest's constructor empty and to call setupRequestCreator() in the UserRequest's constructor, but only after setting the instance variables first; this however feels "hacky" because other people will have to be aware of this when they are creating new subclasses.

I tried other workarounds too, but nothing felt quite right. I was hoping someone could provide me with a better solution

Networking layer module

These two classes are part of a networking layer module that I am building:

public abstract class BaseRequest {

    protected RequestCreator mCreator;

    public BaseRequest() {
        setupRequestCreator();
    }

    private setupRequestCreator() {
        mCreator = new RequestCreator.Builder()
            .headers(getHeaders())
            .parser(getParser())
            .build();
    }

    public abstract Headers getHeaders();
    public abstract Parser getParser();
}

public class UserRequest extends BaseRequest {

    private Headers mHeaders;
    private Request<User> mRequest;

    private interface UserService {
        @GET("/users/{id}")
        User getUser(String id);
    }

    public UserRequest(Headers headers) {
        mHeaders = headers;
        mRequest = mCreator.createRequest(UserService.class);
    }

    @Override
    public Headers getHeaders() {
        return mHeaders;
    }

    @Override
    public Parser getParser() {
        return null;
    }
}

The framework that I am using requires me to configure/build a RequestCreator for each type of Request that I am going to use.

To make the process of adding new classes for different requests as pain-free as possible, I moved the building logic of the RequestCreator in an abstract class. This way I'll only have to extend it and override some methods that indicate how the RequestCreator should be configured - sort of a template method pattern.

The actual problem is this: when someone creates an instance of UserRequest, super() gets called right before UserRequest's member variables are set. What this means is that the RequestCreator will already be built by the time mHeaders are set. This is wrong because the building process needs a reference to mHeaders in order for it to behave as intended.

One way to get around this is to leave BaseRequest's constructor empty and to call setupRequestCreator() in the UserRequest's constructor, but only after setting the instance variables first. This however feels "hacky" because other people will have to be aware of this when they are creating new subclasses.

I tried other workarounds too, but nothing felt quite right. I was hoping someone could provide me with a better solution.

deleted 84 characters in body
Source Link

These two classes are part of a networking layer module that I am building:

public abstract class BaseRequest {

    privateprotected RequestCreator mCreator;

    public BaseRequest() {
        setupRequestCreator();
    }

    private setupRequestCreator() {
        mCreator = new RequestCreator.Builder()
            .headers(getHeaders())
            .parser(getParser())
            .build();
    }
 
    protected RequestCreator getCreator() {
        return mCreator;
    }

    public abstract Headers getHeaders();
    public abstract Parser getParser();
}

public class UserRequest extends BaseRequest {

    private Headers mHeaders;
    private Request<User> mRequest;

    private interface UserService {
        @GET("/users/{id}")
        User getUser(String id);
    }

    public UserRequest(Headers headers) {
        mHeaders = headers;
        mRequest = getCreator()mCreator.createRequest(UserService.class);
    }

    @Override
    public Headers getHeaders() {
        return mHeaders;
    }

    @Override
    public Parser getParser() {
        return null;
    }
}

The framework that I am using requires me to configure/build a RequestCreator for each type of Request that I am going to use.

To make the process of adding new classes for different requests as pain-free as possible I moved the building logic of the RequestCreator in an abstract class so this way I'll only have to extend it and override some methods that indicate how the RequestCreator should be configured - sort of a Template Method pattern.

The actual problem is this: when someone creates an instance of UserRequest, super() gets called right before UserRequest's member variables are set. What this means is that the RequestCreator will already be built by the time mHeaders are set. This is wrong because the bulding process needs a reference to mHeaders in order for it to behave as intended.

One way to get around this is to leave BaseRequest's constructor empty and to call setupRequestCreator() in the UserRequest's constructor, but only after setting the instance variables first; this however feels "hacky" because other people will have to be aware of this when they are creating new subclasses.

I tried other workarounds too, but nothing felt quite right. I was hoping someone could provide me with a better solution

These two classes are part of a networking layer module that I am building:

public abstract class BaseRequest {

    private RequestCreator mCreator;

    public BaseRequest() {
        setupRequestCreator();
    }

    private setupRequestCreator() {
        mCreator = new RequestCreator.Builder()
            .headers(getHeaders())
            .parser(getParser())
            .build();
    }
 
    protected RequestCreator getCreator() {
        return mCreator;
    }

    public abstract Headers getHeaders();
    public abstract Parser getParser();
}

public class UserRequest extends BaseRequest {

    private Headers mHeaders;
    private Request<User> mRequest;

    private interface UserService {
        @GET("/users/{id}")
        User getUser(String id);
    }

    public UserRequest(Headers headers) {
        mHeaders = headers;
        mRequest = getCreator().createRequest(UserService.class);
    }

    @Override
    public Headers getHeaders() {
        return mHeaders;
    }

    @Override
    public Parser getParser() {
        return null;
    }
}

The framework that I am using requires me to configure/build a RequestCreator for each type of Request that I am going to use.

To make the process of adding new classes for different requests as pain-free as possible I moved the building logic of the RequestCreator in an abstract class so this way I'll only have to extend it and override some methods that indicate how the RequestCreator should be configured - sort of a Template Method pattern.

The actual problem is this: when someone creates an instance of UserRequest, super() gets called right before UserRequest's member variables are set. What this means is that the RequestCreator will already be built by the time mHeaders are set. This is wrong because the bulding process needs a reference to mHeaders in order for it to behave as intended.

One way to get around this is to leave BaseRequest's constructor empty and to call setupRequestCreator() in the UserRequest's constructor, but only after setting the instance variables first; this however feels "hacky" because other people will have to be aware of this when they are creating new subclasses.

I tried other workarounds too, but nothing felt quite right. I was hoping someone could provide me with a better solution

These two classes are part of a networking layer module that I am building:

public abstract class BaseRequest {

    protected RequestCreator mCreator;

    public BaseRequest() {
        setupRequestCreator();
    }

    private setupRequestCreator() {
        mCreator = new RequestCreator.Builder()
            .headers(getHeaders())
            .parser(getParser())
            .build();
    }

    public abstract Headers getHeaders();
    public abstract Parser getParser();
}

public class UserRequest extends BaseRequest {

    private Headers mHeaders;
    private Request<User> mRequest;

    private interface UserService {
        @GET("/users/{id}")
        User getUser(String id);
    }

    public UserRequest(Headers headers) {
        mHeaders = headers;
        mRequest = mCreator.createRequest(UserService.class);
    }

    @Override
    public Headers getHeaders() {
        return mHeaders;
    }

    @Override
    public Parser getParser() {
        return null;
    }
}

The framework that I am using requires me to configure/build a RequestCreator for each type of Request that I am going to use.

To make the process of adding new classes for different requests as pain-free as possible I moved the building logic of the RequestCreator in an abstract class so this way I'll only have to extend it and override some methods that indicate how the RequestCreator should be configured - sort of a Template Method pattern.

The actual problem is this: when someone creates an instance of UserRequest, super() gets called right before UserRequest's member variables are set. What this means is that the RequestCreator will already be built by the time mHeaders are set. This is wrong because the bulding process needs a reference to mHeaders in order for it to behave as intended.

One way to get around this is to leave BaseRequest's constructor empty and to call setupRequestCreator() in the UserRequest's constructor, but only after setting the instance variables first; this however feels "hacky" because other people will have to be aware of this when they are creating new subclasses.

I tried other workarounds too, but nothing felt quite right. I was hoping someone could provide me with a better solution

added 380 characters in body
Source Link

These two classes are part of a networking layer module that I stripped out all the project-specific details and this is what's leftam building:

public abstract class FooBaseRequest {

    private CreatorRequestCreator mCreator;

    public FooBaseRequest() {
        setupCreatorsetupRequestCreator();
    }

    private setupCreatorsetupRequestCreator() {
        mCreator = new CreatorRequestCreator.Builder()
            .componentheaders(getSomeComponentgetHeaders())
            .parser(getParser())
            .build();
    }

    protected CreatorRequestCreator getCreator() {
        return mCreator;
    }

    public abstract ComponentHeaders getSomeComponentgetHeaders();
    public abstract Parser getParser();
}

public class BarUserRequest extends FooBaseRequest {

    private ComponentHeaders mComponent;mHeaders;
    private CreatedRequest<User> mCreated;mRequest;

    private interface UserService {
        @GET("/users/{id}")
        User getUser(String id);
    }

    public BarUserRequest(ComponentHeaders compheaders) {
        mComponentmHeaders = component;headers;
        mCreatedmRequest = getCreator().createcreateRequest(UserService.class);
    }

    @Override
    public ComponentHeaders getSomeComponentgetHeaders() {
        return mComponent;mHeaders;
    }

    @Override
    public Parser getParser() {
        return null;
    }
}

The project will containframework that I am using requires me to configure/build a few wrapper classesRequestCreator for a Created object. In order to get holdeach type of this objectRequest that I first needam going to build it's Creatoruse.

To make the process of adding new classes to the projectfor different requests as pain-free as possible I moved the building logic of the CreatorRequestCreator in an abstract class so this way I'll only have to extend it and override some methods that indicate how the CreatorRequestCreator should be constructedconfigured - sort of a Template Method pattern.

The actual problem is this: when someone creates an instance of BarUserRequest, super() gets called right before BarUserRequest's member variables are set. What this means is that the CreatorRequestCreator will already be built by the time mComponent ismHeaders are set. This is wrong because the bulding process needs a reference to mComponentmHeaders in order for it to behave wellas intended.

One way to get around this is to leave Foo'sBaseRequest's constructor empty and to call setupCreatorsetupRequestCreator() in the Bar'sUserRequest's constructor, but only after setting the instance variables first; this however feels "hacky" because other people will have to be aware of this when they are creating new subclasses.

I stripped out all the project-specific details and this is what's left:

public abstract class Foo {

    private Creator mCreator;

    public Foo() {
        setupCreator();
    }

    private setupCreator() {
        mCreator = new Creator.Builder()
            .component(getSomeComponent)
            .build();
    }

    protected Creator getCreator() {
        return mCreator;
    }

    public abstract Component getSomeComponent();
}

public class Bar extends Foo {

    private Component mComponent;
    private Created mCreated;

    public Bar(Component comp) {
        mComponent = component;
        mCreated = getCreator().create();
    }

    @Override
    public Component getSomeComponent() {
        return mComponent;
    }
}

The project will contain a few wrapper classes for a Created object. In order to get hold of this object I first need to build it's Creator.

To make the process of adding new classes to the project as pain-free as possible I moved the building logic of the Creator in an abstract class so this way I'll only have to extend it and override some methods that indicate how the Creator should be constructed - sort of a Template Method pattern.

The actual problem is this: when someone creates an instance of Bar, super() gets called right before Bar's member variables are set. What this means is that the Creator will already be built by the time mComponent is set. This is wrong because the bulding process needs a reference to mComponent in order for it to behave well.

One way to get around this is to leave Foo's constructor empty and to call setupCreator() in the Bar's constructor, but only after setting the instance variables first; this however feels "hacky" because other people will have to be aware of this when they are creating new subclasses.

These two classes are part of a networking layer module that I am building:

public abstract class BaseRequest {

    private RequestCreator mCreator;

    public BaseRequest() {
        setupRequestCreator();
    }

    private setupRequestCreator() {
        mCreator = new RequestCreator.Builder()
            .headers(getHeaders())
            .parser(getParser())
            .build();
    }

    protected RequestCreator getCreator() {
        return mCreator;
    }

    public abstract Headers getHeaders();
    public abstract Parser getParser();
}

public class UserRequest extends BaseRequest {

    private Headers mHeaders;
    private Request<User> mRequest;

    private interface UserService {
        @GET("/users/{id}")
        User getUser(String id);
    }

    public UserRequest(Headers headers) {
        mHeaders = headers;
        mRequest = getCreator().createRequest(UserService.class);
    }

    @Override
    public Headers getHeaders() {
        return mHeaders;
    }

    @Override
    public Parser getParser() {
        return null;
    }
}

The framework that I am using requires me to configure/build a RequestCreator for each type of Request that I am going to use.

To make the process of adding new classes for different requests as pain-free as possible I moved the building logic of the RequestCreator in an abstract class so this way I'll only have to extend it and override some methods that indicate how the RequestCreator should be configured - sort of a Template Method pattern.

The actual problem is this: when someone creates an instance of UserRequest, super() gets called right before UserRequest's member variables are set. What this means is that the RequestCreator will already be built by the time mHeaders are set. This is wrong because the bulding process needs a reference to mHeaders in order for it to behave as intended.

One way to get around this is to leave BaseRequest's constructor empty and to call setupRequestCreator() in the UserRequest's constructor, but only after setting the instance variables first; this however feels "hacky" because other people will have to be aware of this when they are creating new subclasses.

Post Closed as "Not suitable for this site" by Jamal
Source Link
Loading