构造函数vs方法vs工厂

时间:2014-05-24 16:20:13

标签: java oop design-patterns coding-style

想象一下,您想要将某些文档导出到文件中(以某种格式......让我们说XML)。

为此我有类XmlExporter,问题是......将Document和File传递给这个类的最佳方法是什么?

选项1: 导出器是无状态的,所以如果我想导出不同的文档或不同的文件,我只需更改参数。缺点是我必须在每个方法中传递文件(或者更确切地说是OutputStream)(在复杂文档的情况下可能会非常多)

class XmlExporter {
    public function export(Document document, File file) {
        this.writeHeader(document.header, file);
        this.writeSomeOtherStuff(document.somethingElse, file);
        // and more ...
    }

    private function writeHeader(DocumentHeader header, File file) {
        writeName(header.name, file); // passing file over and over again
    }
}

选项2: 源和目标都存储在实例中。如果我想更改文件,我将不得不创建一个新对象,但现在我不必担心传递所有必要的数据。

class XmlExporter {
    private final Document document;
    private final File file;
    public XmlExporter(Document document, File file) {
        this.document = document;
        this.file = file;
    }
    public function export() {
        this.writeHeader(this.document.header);
    }
    private function writeHeader(DocumentHeader header) {
        this.writeName(header.name);
    }
    private function writeName(String name) {
        // ...
    }
}

选项3: 两者结合

class DocumentExporter {
    public static function exportToXml(Document document, File file) {
        XmlExporter exporter = new XmlExporter(document, file);
        exporter.export();
    }
    // the rest same as Option 2, probably with private constructor
}

基本上,从编写课程的角度来看,第二选择对我来说最有意义,因为我不需要传递目标文件/流;但是从实际使用它的角度来看,我觉得第一选择会更有意义。如果我想将其导出到标准输出而不是文件,或导出多个文档,该怎么办?

2 个答案:

答案 0 :(得分:1)

首先,我会选择选项2以支持稍后扩展导出过程(在实例中存储状态,进度等)。如果希望它们可以更改,可以为文件和文档添加公共属性。

  

如果我想将其导出到标准输出而不是文件,或者   导出多个文件?

尝试解耦XmlExporter类的功能。 XmlExporter应该是一个Director,其职责是解析Document并通知运行时附加的Handler(接口) - 一个Handler实现可以将数据写入File,另一个可以写入Console。

查看构建器设计模式:http://www.blackwasp.co.uk/Builder.aspx

答案 1 :(得分:0)

无。 Exporter(以及"经理","控制器"或任何其他" -er"已结束的名称)是不正确设计的指标。相反,您的Document应该知道如何将自己导出到File

document.exportTo(file);