0

I am trying to understand the theory of what a factory pattern is, am I implementing it correctly here? if not what is wrong if correct what should I change?

Interface

public interface Person {
    public void setName(String name);
    public String getName();
    public void setAge(String age);
    public String getAge();
    public void setGender(String gender);
    public String getGender();
}

Male Object

public class Male implements Person
{
    public String name;
    public String age;
    public String gender;
    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return null;
    }

    @Override
    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String getAge() {
        return null;
    }

    @Override
    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String getGender() {
        return null;
    }
}

Female Object

public class Male implements Person
{
    public String name;
    public String age;
    public String gender;
    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return null;
    }

    @Override
    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String getAge() {
        return null;
    }

    @Override
    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String getGender() {
        return null;
    }
}

Object Factory

public class PersonFactory {

    public Person getPerson(String type) {
        if(type == "MALE") {
            return new Male();
        }
        else {
            return new Female();
        }
    }
    public Person getMale() {
        return new Male();
    }
    public Person getFemale() {
        return new Female();
    }
}

Main Method

public class main {
    public static void main(String[] args) {
        PersonFactory pf = new PersonFactory();
        Person adam = pf.getPerson("MALE");
    }
}

4 Answers4

3

Apart from the String comparison in PersonFactory and with proper implementation of getters in your factory members, seems a descent implementation.

And in your getPerson() logic can be modified as

 if (type == "MALE") {
        return getMale();
    } else {
        return getFemale();
 }
Community
  • 1
  • 1
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
1

Looks pretty good, but I'd go ahead and use the factory methods for your "String" method. In other words:

public Person getPerson(String type) {
    if(type == "MALE") {
        return getMale()
    }
    else {
        return getFemale();
    }
}

That way you only have to update the methods if you want to change things in one place, for example if you decide to do something special in the getFemale() or getMale()s.

Craig
  • 2,286
  • 3
  • 24
  • 37
1

You should use "MALE".equals(type) instead of type == "MALE". Otherwise your are doing good with factory pattern.

Kuldeep Singh
  • 199
  • 1
  • 11
0

I would implement another approach. The first thing, I would make gender as an enum:

public enum Gender {
    Male, Female
}

Note, that Male and Female classes share the same data and semantics to work with this data. I mean name, age and gender.

So, I would implement an abstract class that handles this data. Please note, that class fields should be private, not public.

public abstract class AbstractPerson implements Person {
    private String name;
    private String age; // maybe int ?
    private Gender gender;

    public  AbstractPerson() {

    }

    @override
    public void setName(String name) {
        this.name = name;
    }

    @override       
    public String getName() {
        return name;
    }

    @override       
    public void setAge(String age) {
        this.age = age;
    }

    @override
    public String getAge() {
        return age;
    }

    @override
    public Gender getGender() {
        return this.gender;
    }

    @override
    public void setGender(Gender gender) {
        this.gender = gender;
    }
}

And it is better to hide this implementation. So we hide it into the factory class:

public class PersonFactory {

    private static PersonFactory instance = new PersonFactory();

    public static PersonFactory getInstance() {
        return instance;
    }

    public Person getPerson(Gender gender) {
        return new AbstractPerson(gender);
    }

    public Person getMale() {
        return getPerson(Gender.Male);
    }

    public Person getFemale() {
        return getPerson(Gender.Female);
    }

    private PersonFactory {

    }

    private static class AbstractPerson implements Person {
        private String name;
        private String age; // maybe int ??
        private Gender gender;

        public  AbstractPerson(Gender gender) {
            this.gender = gender;
        }

        @override
        public void setName(String name) {
            this.name = name;
        }

        @override
        public String getName() {
            return name;
        }

        @override
        public void setAge(String age) {
            this.age = age;
        }

        @override
        public String getAge() {
            return age;
        }

        @override
        public void setGender(Gender gender) {
            this.gender = gender;
        }

        @override
        public Gender getGender() {
            return this.gender;
        }
    }   
}

And, use case for this factory:

PersonFactory factory = PersonFactory.getInstance();
Person malePerson = factory.getMale();
Person femalePerson = factory.getFemale();

UPDATE: 15 Sept, 2015

Please note, if you have many kinds of objects, to be produced by factory, then it is advised to have a general method like getPerson(Gender gender) I've just added above in the code.

  • to downvoters, please leave a comment to let me know, what is wrong with my answer. Thank you. –  Sep 15 '15 at 03:07
  • The purpose of a factory is defeated by adding separate methods for each product implementation. In this case, the user must implement his own factory logic to choose between `getMale()` and `getFemale()`. – jaco0646 Sep 15 '15 at 14:41
  • @jaco0646 yes, you are right for the general case, when we have many different kind of objects to be produced by the factory. This particular task was related only to male/female case, so I designed the factory with those methods. I've added update to my post. –  Sep 15 '15 at 14:42