Search code examples
javaandroidcommand-pattern

Using the Command Pattern in Android in combination with an Http Request Handler to handle its result


My actual question is down towards the bottom of the page, and may not require you to look at all of my code.

So I think I want to employ the Command Pattern in my Android application. I have a class HttpRequestHandler which extends AsyncTask and thus has the doInBackground and onPostExecute methods. HttpRequestHandler takes a URL, and an HttpRequest type as parameters.

What I want to do is pass a method (in the form of an interface) to the HttpRequestHandler so that in the onPostExecute I can invoke that method and have it display the result gotten from the Http request in the given textview. This way I don't have to use a giant switch(case) in my onPostExecute

I need some help with the execution though. In this case, I have two separate classes that implement Command.

public interface Command{
    public void execute(JSONObject json);
}

public class DisplayResult implements Command{

    public TextView textview;

    public DisplayResult(TextView textview){
        this.textview = textview;
    }
    @Override
    public void execute(JSONObject output){
        textview.setText(output.getString("mystring")
    }
}

public class ConfirmPost implements Command{

    public ConfirmPost(){
    }
    @Override
    public void execute(JSONObject output){
        Log.d("Success! ","POST successfull");
    }
}

And the two calls to HTTPRequestHandler, one passing a DisplayResult and one passing a ConfirmPost class. public static void

TextView mytextview = (TextView) findViewById(R.id.mytextview);
new HttpRequestHandler(new DisplayResult(mytextview)).execute("myurl","GET");

new HttpRequestHandler(new ConfirmPost()).execute("myurl","POST");

Now it's in my HttpRequestHandler where I'm having the problem.

public class HttpRequestHandler extends AsyncTask<String, String, String>{
Command presenter;

    Public HttpRequestHandler(Object presenter){    
        this.presenter = (Command) presenter;
    }

    Public String doInBackground(String... uri){
       ...
    }

    Public onPostExecute(String result){
        presentation = new JSONObject(result);
        presenter.execute();
    }

Using Object as an argument type seems to me, simply by feeling, not to be best practice. I've never seen anyone use it like this, and the idea of having to cast the given object as Command rubs me the wrong way. Is there some way I can just make the class sort of trust that I'm giving it a Command object?

This is my first time using the Command Pattern, and I don't yet fully understand it. Be gentle.

UPDATE

It looks like I want to be using Generics here. I still don't really know how to execute that in a best practice manner though. What I have now is:

Command presenter; 

public <Command> HttpRequestHandler(Command presenter){
    this.presenter = (com.example.myproject.Command) presenter;
    //ugly!
}

And this works just fine I can seemingly pass it any old implementation of Command, I just can't seem to find any references online which have the same syntax or functionality. I've heard some mention of the factory pattern, but I have a feeling the Command Pattern doesn't rely on another pattern to be fully functional like this. Any direction would be appreciated.


Solution

  • Indeed it is a matter for Generics. Using Bounded Type Parameters and by having T extend Command, I can ensure that my parameter will be a subclass (in this case implementation) of Command

    The HttpRequestHandler should now look something like this

    public class HttpRequestHandler extends AsyncTask<String, String, String>{
    
        Command presenter;
    
        public <T extends Command> HttpRequestHandler(T presenter){
            this.presenter =  presenter;
        }
    
        presenter.execute("Success!");
    }
    

    No horrendous casting necessary.