Let's say I have a set of objects,

foo f;
bar br;
baz bz;

I also have a string of JSON data,

string JSONstring;

Depending on the object type of the JSON string, I need to transform it into either foo, bar, or baz. Ok, cool, I'll have a method for that.

public object parseJSONToFooBarBaz(string jsonString);

What I want to avoid is writing something like:

map<string, object> topLevelJSON = deserialized json string;

if(map[foo] != null) return new foo(jsonString);
else if(map[bar] != null) return new bar(jsonString);
...
// And the list balloons up and is difficult to maintain

I feel like this is either a good condidate or almost a good candidate for a factory pattern, but something doesn't feel quite right. Is there a simple solution that I'm overlooking, or is a set of conditionals or a switch/case really an OK way to solve this?

有帮助吗?

解决方案

The simplest thing to do is to make a map<string, string -> object) where string -> object just means a function taking a string and producing an object. If the language you are using doesn't support first-class functions you can use the Strategy pattern. The Factory pattern is essentially just a special case of the Strategy pattern and thus just a round-about way of doing first-class functions (though the term "Factory" communicates intent.)

You could then do something like:

foreach(key in factories.keys()) {
    if(topLevelJSON[key] != null) {
        return factories[key](jsonString);
    }
}

I assume these keys are mutually exclusive (as suggested by your if statements), though you could easily adapt the code to return all the choices or have a list of the factories in priority order.

许可以下: CC-BY-SA归因
scroll top