использовать фабричный шаблон проектирования с подклассом, который имеет дополнительные аргументы конструктора

предположим, у меня есть следующий родительский класс и два дочерних класса, каждый дочерний элемент добавляет новый параметр к параметрам, унаследованным от родителя. Пример

public class Parent {

private int x;

public Parent(int x) {this.x = x;}

public int getX() {return x;}

public void setX(int x) {this.x = x;}
}

Первый ребенок

public class FirstChild extends Parent {

private int y;

public FirstChild(int x, int y) {
    super(x);
    this.y = y;
}

public int getY() {
    return y;
}

public void setY(int y) {
    this.y = y;
}
}

Второй ребенок

public class SecondChild extends Parent{
private int z;

public SecondChild(int x, int z) {
    super(x);
    this.z = z;
}

public int getZ() {
    return z;
}

public void setZ(int z) {
    this.z = z;
}
}

так как я могу использовать фабричный метод здесь?,


person Karim Harazin    schedule 09.01.2013    source источник


Ответы (3)


Здесь нельзя использовать «чистые» шаблоны фабрики или фабричного метода. Эти шаблоны хороши, когда вы хотите создать экземпляры разных подклассов одного и того же базового класса (или интерфейса), если механизм создания экземпляров аналогичен. Например, у всех классов есть конструктор или фабричный метод с одним и тем же прототипом.

В этом случае вы можете использовать отражение или многоточие:

class MyFactory {
    Parent createInstance(Class clazz, int ... args) {
        if (FirstChild.class.equals(clazz)) {
            return new FirstChild(args[0]);
        }
        if (SecondChild.class.equals(clazz)) {
            return new SecondChild(args[0], args[1]);
        }
        throw new IllegalArgumentException(clazz.getName());
    }
}
person AlexR    schedule 09.01.2013

interface Factory {
    Parent newParent();
} 

class FirstFactory implements Factory {
    Parent newParent() { return new FirstChild(); }
}

class SecondFactory implements Factory {
    Parent newParent() { return new SecondChild(); }
}


class Client {
    public void doSomething() {
        Factory f = ...; // get the factory you need 
        Parent p = f.newParent();
        use(p)
    } 

    // or more appropriately
    public void doSomethingElse(Factory f) {
        Parent p = f.newParent();
        use(p)
    }

}

// Or...

abstract class Client {
    public void doSomething() {
        Factory f = getFactory();
        Parent p = f.newParent();
        use(p)
    } 
    abstract Factory getFactory(); 
}

class FirstClient extends Client {
    Factory getFactory() {
        return new FirstFactory();
    } 
}

class SecondClient extends Client {
    Factory getFactory() {
        return new SecondFactory();
    } 
}

Или (возможно, лучше подходит то, что вам нужно):

public class ChildrenFactory {
    FirstChild newFistChild() { return new FirstChild(); } 
    SecondChild newSecondChild() { return new SecondChild(); } 
    // or
    Parent newFistChild() { return new FirstChild(); } 
    Parent newSecondChild() { return new SecondChild(); } 
}

Вероятно, вам не нужно использовать интерфейс Parent.

person Luigi R. Viggiano    schedule 09.01.2013

У вас может быть фабричный класс, который генерирует либо первого дочернего элемента, либо второго дочернего элемента, как показано ниже.

class Factory{
   Parent createChild(String child) {
      if(child.equals("first"))
         return new FirstChild();
      if(child.equals("second"))
         return new SecondChild();


   }
}

Также эта ссылка ниже поможет вам лучше понять фабричный шаблон http://www.hiteshagrawal.com/java/factory-design-pattern-in-java

person hmatar    schedule 09.01.2013