0

I have a following class that shares the same "state" and performs CRUD actions. This operation is not repeatable/idempotent.

public class Client {
    private static String state;
    public Client(args){
        this.state = buildStateFromArgs();  // this value will not change
    }

    public void createUser();
    public User getUser();
    public User updateUser();
    public void deleteUser();

    public void createJob();
    public Job getJob();
    public Job updateJob();
    public void deleteJob();

    // other CRUD functions ....
}

I am thinking of refactoring it to something like

public class Client {
    public Client(args){
        this.state = buildStateFromArgs();
    }
    private static String state;
}

public class UserClient extends Client{
    public void createUser();
    public User getUser();
    public User updateUser();
    public void deleteUser();
}

But I am not sure what is the best approach to instatiate the child class. Suppose this is the current implementation,

Client client = new Client(args);
client.createUser();
client.createJob();

Should I simply just downcast?

Client client = new Client(args);
UserClient userClient = (UserClient) client;
userClient.createUser();
JobClient jobClient = (JobClient) client;
jobClient.createJob();

Or should I construct the child from parent?

Client client = new Client(args);
UserClient userClient = new UserClient(client);
userClient.createUser();
JobClient jobClient = new JobClient(client);
jobClient.createJob();

Or is there a better design pattern suited for this kind of problem?

6
  • Why don't you call super(args) from your UserClient constructor? Commented Oct 30, 2017 at 2:42
  • JobClient extends Client or UserClient? Commented Oct 30, 2017 at 2:45
  • Composition is always preferred over Inheritance in cases like this. Commented Oct 30, 2017 at 2:45
  • @ScaryWombat, I forgot to mention in my question that I cannot create the "state" parameter twice (it will be different every time buildStateFromArgs is called) and this value has to be shared across child instances Commented Oct 30, 2017 at 2:46
  • @everton, all the child classes will extend Client. Commented Oct 30, 2017 at 2:46

1 Answer 1

1

Given that UserClient is-a Client, I would take the following approach:

UserClient client = new UserClient();
client.createUser();

My reason for taking this approach is that user-specific functions should only exist on a UserClient and can therefore only be called from such.

Given the new information that the state must be shared across all clients, I'd probably use a static initializer:

class Client {
    private static String state;
    static {
        state = buildStateFromArgs(args);  // this value will not change
    }
}

This assumes that the args are available this point. If they are not, then you need to make buildStateFromArgs() a public, static function and call it before any sub-classes are instantiated:

Client.buildStateFromArgs(args);
UserClient client = new UserClient();
...
Sign up to request clarification or add additional context in comments.

4 Comments

I forgot to mention in my question that I cannot create the "state" parameter twice (it will be different every time buildStateFromArgs is called) and this value has to be shared across child instances.
@WaiYan OK, I've updated my answer to reflect that state is static, ie. shared.
one more question if you don't mind, is this approach thread-safe?
I would think so. The only caveat is you need to ensure the state is set before any thread creates a client (and potentially uses that state).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.