简体   繁体   中英

Constructor vs method vs factory

Imagine you want to export certain Document into File (in some format... let's say XML).

For this purpose I have class XmlExporter and the question is... what is the best approach to passing both Document and File to this class?

Option 1: Exporter is stateless, so if I want to export different document or into different file I just change the parameter. Disadvantage is that I have to pass the file (or rather OutputStream) in every single method (which in case of complex document can be quite a lot)

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
    }
}

Option 2: Both source and target is stored within the instance. If I wanted to change the file I would have to create a new object, but now I don't need to worry about passing all necessary data.

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) {
        // ...
    }
}

Option 3: Combination of both

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
}

Basically the second choice makes most sense for me from the perspective of writing the class, since I don't need to pass the target file/stream around; however from the point of actually using it I feel that the first choice would make more sense. What if I wanted to export it into standard output instead of file, or export multiple documents?

First of all, I would choose Option 2 to support the extension of the export process later (storing status, progress, etc. in the instance). You can add public properties for the File and the Document if you want them to be changable.

What if I wanted to export it into standard output instead of file, or export multiple documents?

Try to decouple the functionalities of your XmlExporter class. XmlExporter should be a Director, which responsibility is to parse the Document and notify a Handler (interface) attached at runtime - one Handler implementaion can write data to File, another to the Console.

Check out the Builder Design Pattern: http://www.blackwasp.co.uk/Builder.aspx

None. Exporter (as well as "manager", "controller", or any other "-er" ended names) are indicators of incorrect design. Instead, your Document should know how to export itself to a File :

document.exportTo(file);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM