正确的设计来构造一个对象

时间:2017-12-07 17:20:23

标签: java oop dependency-injection constructor

对于我在对象构造中的具体用例,我有一个主要的设计问题。

我正在根据MyMessage对象的值构建一个对象com.fasterxml.jackson.databind.JsonNode。当然,为了这个目的,使用ObjectMapper,所以实际的构造片段看起来像下面这样:

JsonNode json = JsonLoader.fromResource("msg.json");           
MyMessage m = jsonMapper.treeToValue(json, MyMessage.class);

此处jsonMapper变量的类型为ObjectMapper

现在,我希望MyMessage只能从静态工厂方法构造,并将实际构造函数保持为私有(因为它有太多字段)。所以首选的结构是这样的:

MyMessage m = MyMessage.createFromJson(json);

此处json变量的类型为JsonNode

这就是问题开始的地方。显然,从JSON构造对象需要ObjectMapper实例,我会尽量避免它被客户端代码传入。

现在,让ObjectMapper成为MyMessage的私有(静态)字段,并且有类似的内容:

private static final ObjectMapper jsonMapper = new ObjectMapper();

private MyMessage(/* many fields */){/* ctor code */}

public MyMessage createFromJson(JsonNode json) {
    return jsonMapper.treeToValue(json, MyMessage.class)
}

但问题在于我希望ObjectMapper对象在我的整个应用程序中都是单例,并且不仅用于构造MyMessage对象,还用于不同类型的Message对象例如YourMessageSomeOtherMessage

拥有许多(静态)ObjectMapper实例的问题是我将拥有大量不同的Message类,每个类有很多实例。所以这将是非常低效的内存。

问题

我最接近单身ObjectMapper和静态工厂方法的最接近的是什么?或者你可能会建议一些其他的设计理念(我不知道建筑师模式是否能以某种方式提供帮助),以适合我的用例?

1 个答案:

答案 0 :(得分:0)

我建议您放弃静态工厂方法限制,并使用Factory创建您的消息,并使该类引用您的单例{{1 }}:

ObjectMapper

然后,无论您需要它,您都可以:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

final class MessagesFactory {

    private final ObjectMapper objectMapper;

    // This constructor is a great candidate for DI
    MessagesFactory(final ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    <T extends Message> T createFromJson(
         final JsonNode json, final Class<T> messageClass
    ) throws JsonProcessingException {
        return objectMapper.treeToValue(json, clazz);
    }
}