对于我在对象构造中的具体用例,我有一个主要的设计问题。
我正在根据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
对象例如YourMessage
,SomeOtherMessage
等
拥有许多(静态)ObjectMapper实例的问题是我将拥有大量不同的Message
类,每个类有很多实例。所以这将是非常低效的内存。
问题
我最接近单身ObjectMapper
和静态工厂方法的最接近的是什么?或者你可能会建议一些其他的设计理念(我不知道建筑师模式是否能以某种方式提供帮助),以适合我的用例?
答案 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);
}
}