1

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

4

1 回答 1

1

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

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

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

首先,您创建 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()和子类SimpleNumberFactoryand ComplexNumberFactory,它们必须实现此方法,它们在其中返回各自的 NumberObject:SimpleNumberFactoryaSimpleNumberObjectComplexNumberFactorya ComplexNumberObject
(我将跳过这里的实现,如果你需要它来理解让我知道,那么我也可以把它。)

然后,你设计你的主类,如果它要使用SimpleNumberObject或者ComplexNumberObject.

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 构造函数需要的整数,或者一些迭代数字。事实上,主类不需要关心,你将它解耦了一点。

关于推迟决定创建什么对象:它不一定是命令行参数,但可以是不同的类、一些上下文信息或其他东西。基本上,如果您想在其他地方做出决定,当然如果您想将对象的创建委托给工厂,则可以使用此模式。

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

于 2013-03-17T14:17:58.427 回答