首页 > 解决方案 > JsonGenerator 可以在同一个调用中写入 OutputStream 和 Writer 吗?

问题描述

是否有一种优雅的解决方案或模式,以便 writeStartObject() 的一次调用可以同时应用于 Writer 和 OutputStream?

        try (
        JsonGenerator output = jfactory.createGenerator(outputWriter); // writer
        JsonGenerator cachingOutput = jfactory.createGenerator(cachingService.getCachingOutputStream(id));//outputstream
    ) {
        output.writeStartObject();
        cachingOutput.writeStartObject();
        ...

标签: javajava-io

解决方案


您可能需要考虑这两者是否真的应该绑定在一起,因为需要考虑内聚和耦合准则。例如,如果您需要将 thewriter或 theoutputStream广泛用于其他用途,那么您应该将它们分开,除非这种广泛使用在它们两者中得到同等反映。最好将这两者隐藏在两个独立的数据访问对象后面,在其中可以划分它们的使用,根据访问它们的目的以描述性方式公开它们的操作 - 更适合您的业务。

无论是有限使用还是广泛使用,为了在这对中平等使用,我可能会应用这样的外观

class SimultaneousFeed {
    private JFactory jFactory;
    private JsonGenerator out;
    private JsonGenerator writer;
    SimultaneousFeed(JFactory jFactory, OutputStream outputStream, Writer outputWriter) {
        this.jFactory = jFactory;
        this.out = jfactory.createGenerator(outputStream);
        this.writer = jfactory.createGenerator(outputWriter);
    }
    void writeStartObject() {
        out.writeStartObject();
        writer.writeStartObject();
    }
    ...
    // other operations common to the pair of these outputs
}

...

SimultaneousFeed feed = new SimultaneousFeed(jFactory, cachingService.getCachingOutputStream(id),
        outputWriter);
feed.writeStartObject();

请注意,我将 传递OutputStream给新SimultaneousFeed实例,而不是传递id. 传递id增加了新实例中的数据耦合id- 这是一条SimultaneousFeed应该一无所知的数据。这允许SimultaneousFeed只关注输出数据,从而提高可重用性和可维护性。

可以考虑的替代模式是装饰器模式,前提是您能够对jfactory实例的类和类进行子类化JsonGenerator。这将允许您创建一个自定义JsonGenerator,在该方法的重写实现中同时写入两个输出writeStartObject()。在这种情况下,您可以在jfactory类中提供一个方法:

public JsonGenerator createSimultaneousGenerator(OutputStream outputStream, Writer outputWriter) {
    return new SimulJsonGenerator(outputStream, outputWriter);
}

推荐阅读