![](/img/trans.png)
[英]How can I create different object types without using switch case?
[英]How to instantiate a set of different object from json list without switch case?
我想從 json 列表中實例化一組對象。
考慮json列表
[
{
...
"class":"object1",
"area":45
...
},
{
...
"class":"object2",
"colour":"red"
},
{
...
"class":"object3",
"height":90
...
}
]
肯定有定義每個對象的字段。 我為每個對象創建了一個記錄
public record object1 (String area, ...) {}
public record object2 (String colour, ...) {}
public record object3 (String height, ...) {}
一般來說,我可以創建一個 switch case 來檢查屬性類並選擇正確的記錄構造函數。 這在我看來是非常糟糕的風格。 過去,我使用了具有擬合超類的多態性。 並使用了創建對象的枚舉。 在這種情況下, record
類只有超級對象。
我想堅持使用記錄,因為我只在這個對象中保存簡單的數據。
在那里我想知道如何處理這個問題。 處理此類事情的最佳做法是什么? 什么模式可以用來解決這個問題?
我將對我的評論進行一些擴展,以展示“元工廠”方法可能是什么樣子的粗略示例。
首先,為實際的對象工廠定義一個接口。 我將為您留下實現,這些實現非常簡單(就像您在 switch 塊中的情況一樣)。
interface Factory<T> {
//I'll assume you're using a JSON library here which provided a JsonObject class
//Change the parameter as required to reflect your actual code
T createInstance(JsonObject record);
}
然后創建一個存儲庫。 這也只是一個粗略的概述:
class FactoryRepo {
//Mapping between name and type, this could also be maintained by the factories or some other piece of code
Map<String, Class<?>> typeMapping = ...;
//The actual repository, a simple map for starters
Map<Class<?>, Factory<?>> repository = ...;
//register a new factory, I'll add the name mapping too but you could move this into a separate method
public <T> void registerFactory(String name, Class<T> type, Factory<T> factory) {
typeMapping.put(name, type);
repository.put(type, factory);
}
//lookup factory by class
@SuppressWarnings({ "unchecked" })
public <T> Factory<T> lookupFactory(Class<T> type) {
//unfortunately this cast is necessary
return (Factory<T>)repository.get(type);
}
//lookup factory by name
public Factory<?> lookupFactory(String name) {
return lookupFactory(typeMapping.get(name));
}
}
當然,您需要注冊工廠。 這可以手動完成,也可以使用檢測實現的框架(例如 Spring、CDI 甚至 Java 的 SPI)來完成。 手動方法可能如下所示:
FactoryRepo repo = ...; //get if from somewhere
repo.registerFactory("object1", Object1Type.class, new Object1Factory());
repo.registerFactory("object2",ColoredObject.class, record -> {
//code to build an instance of ColoredObject from record and return it
});
最后,你使用它:
FactoryRepo repo = ...; //get if from somewhere
JsonObject record = ...; //assumes you have it handy
//Unfortunately, you only get "Object" since the record's class can be anything
//If you have an interfacy etc. you could limit the boundary to this
Factory<?> factory = repo.lookupFactory(record.get("class"));
Object instance = factory.createInstance(record);
//If you know the type, you can try like this:
ColoredObject co = repo.lookupFactory(ColoredObject.class).createInstance(record);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.