工厂方法:需要创建者层次结构

时间:2013-03-17 12:43:42

标签: design-patterns subclass factory-pattern

我是设计模式的新手。在浏览GOF时,实现工厂模式的一种方法是创建与每个产品相对应的创建者(工厂)的并行层次结构。为什么我们需要这种层次结构?它不会创建不必要的子类吗? 有人可以给我一个我们需要这种实现的例子。

1 个答案:

答案 0 :(得分:1)

如果您不希望在使用它们的上下文中决定要创建哪个对象,但想要推迟它,则需要此模式。您可以使用工厂模式将决策推迟到运行时。

这是一个例子(有点过于简单,但我希望你明白这一点):

您想要编写一个创建NumberObject的程序,并且您希望拥有一个简单的类型或复杂的类型。但是你不想硬编码决定在你的程序中使用哪种数字对象,但是想根据你编程的命令行参数来制作它。

首先,您创建了2个类SimpleNumberObjectComplexNumberObject,它们都实现了具有抽象方法NumberObject的类print(),并强制子类实现它。类似的东西:

public class NumberObject {
    protected int number;
    public NumberObject(int number) {
        this.number = number;
    }
    abstract void print();
}

public class SimpleNumberObject extends NumberObject {
    public SimpleNumberObject(int number) {
        super(number);
    }        
    public void print() {
        System.out.println("My number is " + number);
    }
}

public class ComplexNumberObject() extends NumberObject {
    public SimpleNumberObject(int number) {
        super(number);
    }        
    public void print() {
        System.out.println("My number is " + number 
            + " and I can do a lot more complex stuff");
    }
}

然后使用方法NumberFactory和子类createNumber()SimpleNumberFactory创建抽象类ComplexNumberFactory,它们必须实现此方法,然后返回相应的NumberObject:SimpleNumberFactory一个SimpleNumberObjectComplexNumberFactory一个ComplexNumberObject (我将跳过这里的实现,如果你需要它来理解让我知道,那么我也可以把它。)

然后,您设计主类,如果要使用SimpleNumberObjectComplexNumberObject,您可以在构造函数中进行设计。

public class MainClass {

    private NumberFactory numberFactory;

    public MainClass(String arg) {
        if (arg != null && arg.equals("complex") {
            numberFactory = new ComplexNumberFactory();
        } else {
            numberFactory = new SimpleNumberFactory();
        }
    }

    public void printSomeNumber() {
        NumberObject number = numberFactory.createNumber();
        number.print();
    }

    public static void main(String[] args) {
        MainClass mainClass = new MainClass(args[0]);
        mainClass.printSomeNumber();
    }
}

所以这里发生的是根据命令行参数,它将创建SimpleNumberObjects或ComplexNumberObjects。您没有在代码中指定它,因此编译器无法确定将使用哪个对象,只是它实现了NumberObject

使用工厂,您将从MainClass如何创建一个数字开始承担责任。他们可以使用随机生成器来生成NumberObject构造函数所需的整数,或者一些迭代数。事实上,主要课程不需要关心,而且你将它解耦了一点。

关于推迟决定创建什么对象:它不一定必须是命令行参数,而是可以是不同的类,某些上下文信息或其他内容。基本上,如果你想在其他地方做出决定,你可以使用这个模式,当然如果你想将对象的创建委托给工厂。

你是对的,有很多子类正在进行,这使得这个模式类很重。在实践中,你必须决定使用它是否有回报。如果您打算使用工厂进行对象创建,那么无论如何您都有不同的对象子类,并且您不必决定在程序中的某个点创建哪个子类,那么您可能会考虑使用它。

相关问题