Search code examples
javaoopdesign-patternsfactoryfactory-pattern

Nice way of factory method pattern with inheritance


Suppose I have following class hierarchy:

class abstract Parent{}

class FirstChild extends Parent {}

class SecondChild extends Parent {}

And I'd like to create DTO objects from each child:

class abstract ParentDTO {}

class FirstChildDTO extends ParentDTO{}

class SecondChildDTO extends ParentDTO{}

I think I need a factory method something like this:

ParentDTO createFrom(Parent source); 

Is there any nice way to do this in Java without instanceof checks and if/else statements?

EDIT: This factory method does not work:

public ParentDTO create(Parent source)
{
    return _create(source);
}

private FirstChildDTO _create(FirstChild source)
{
    return new FirstDTO();
}

private SecondChildDTO _create(SecondChild source)
{
    return new SecondDTO();
}

private ParentDTO _create(Parent source)
{
    return new ParentDTO();
}

It only generates ParentDTOs and here is why:

Parent p = new FirstChild();
System.out.println(factory.create(p));  //ParentDTO

FirstChild f = new FirstChild();
System.out.println(factory.create(f));  //FirstChildDTO

Solution

  • If you insist on using a factory for DTO creation you can use simple method overloading. Example follows:

    public class Factory {
    
        public ParentDTO createDTO(Parent parent) {
            return new ParentDTO();
        }
        public FirstChildDTO createDTO(FirstChild firstChild) {
            return new FirstChildDTO();
        }
        public SecondChildDTO createDTO(SecondChild SecondChild) {
            return new SecondChildDTO();
        }
    }
    
    public class Parent {
    }
    
    public class FirstChild extends Parent {
    }
    
    public class SecondChild extends Parent {
    }
    
    public class ParentDTO {
    
        @Override
        public String toString() {
            return this.getClass().getSimpleName();
        }
    }
    
    public class FirstChildDTO extends ParentDTO {
    
        @Override
        public String toString() {
            return this.getClass().getSimpleName();
        }
    }
    
    public class SecondChildDTO extends ParentDTO {
    
        @Override
        public String toString() {
            return this.getClass().getSimpleName();
        }
    }
    
    public class App {
    
        public static void main(String[] args) {
            Factory factory = new Factory();
            ParentDTO parentDTO = factory.createDTO(new Parent());
            System.out.println(parentDTO);
            FirstChildDTO firstChildDTO = factory.createDTO(new FirstChild());
            System.out.println(firstChildDTO);
            SecondChildDTO secondChildDTO = factory.createDTO(new SecondChild());
            System.out.println(secondChildDTO);
        }
    }
    

    Running the App as Java application in my IDE outputs:

    ParentDTO
    FirstChildDTO
    SecondChildDTO