Factory class in Java - Android

4.6k Views Asked by At

I would like to create a factory class which creates some Dialogs (actually AlertDialog) with different characteristics depending from which class is called. For example, if I call the Factory.createDialog() from class A, it gives me an AlertDialog with some button text, from class B - the same button has a different text. My question is how should I implement the Factory:

Variant 1:

public class DialogFactory {
    public static Dialog createDialog(String className){
        if(class A){
            return DialogForClassA.buildDialog();
        }
        else if(class B){
            return DialogForClassB.buildDialog();
        }
        //else ...
    }
}

interface MyDialog {
    static Dialog buildDialog();
}

class DialogForClassA implements MyDialog{
    public static Dialog buildDialog(){
        //create dialog
        return dialog;
    }
}

class DialogForClassB implements MyDialog{
    public static Dialog buildDialog(){
        //create dialog
        return dialog;
    }
}


Variant 2:

public class DialogFactory {
    public static Dialog createDialog(String className){

        //Build the dialog common features
        //....

        //add the features that are different
        if(class A){
            //set button textA;
        }
        else if(class B){
            //set button textB;
        }
        //else ...

        return dialog;
    }
}

Also, please advise me if there is something wrong with the logic.
For example, is something wrong if the method buildDialog() is static in classes A and B?
Is there any better alternative?

4

There are 4 best solutions below

0
On

Actually I think the first variant is incorrect, you cannot really use static methods in interfaces, at least that way.

You may use a standard method in variant 1:

interface Dialog { public Dialog buildDialog(); }

public class DialogFactory { public static Dialog createDialog(String className){ if(class A){ dialog = new DialogForClassA(); } else if(class B){ dialog = new DialogForClassA(); } return dialog.buildDialog(); } }

But I don't see any advatage in declaring an interface method to build the dialog (unless you use RTTI, but this is another topic... BTW: You can still make use of Reflection in both variants if you need, and the two variants in that case will look identical!).

0
On

Variant 1 looks more flexible because if you want to change some dialog completely you must change only particular buildDialog method instead of createDialog in Variant 2, which can affect other dialogs.

But:

  1. you cannot declare static method in the interface (it has no sense).
  2. from your code in Variant 1, there is no need of the interface at all.
0
On

Both variants are good.

But I would prefer to use something like variant 1 since it's more organized, also, it allows you to do something more interesting, imagine all you dialog classes are in the same folder like "dialogs", instead of using all those ifs and elses you can use RTTI to get the class in the folder dialogs named className (use function Class.forName) and then call the method createDialog of this class.

This alternative allows you to everytime you want to add a new type of dialog, you only need to add the new class of that dialog in the dialogs folder. You won't need to touch the DialogFactory.

Also there's no problem with using static method (some people don't like it because it's not really OOP)

0
On

Personally I would not use the calling classes name as the criteria of what kind of dialog to create. Maybe change that to some constant? Anyway the factory could be simply:

class DialogFactory {
    static Dialog create(int kind) {
        switch (kind) {
            case DIALOG_KIND_SHORT:
                return ....
        }
    }
}

For more flexible alternative you could use Builder Pattern instead of one static factory method:http://en.m.wikipedia.org/wiki/Builder_pattern