lundi 6 mai 2019

Design pattern for extracting possibly interdependent fields from raw data

I have a blob of incoming data (let's say it's a JSON object), and I need to extract some fields using this raw data. For example, in pseudocode:

int user_id_field = data['user_id'] as int;
string user_name_field = data['user_name'] as string;

However, some fields are more complicated and actually depend on other fields. For example, following the code snippet above:

// async operation
UserProfile user_profile = await db.get_user_profile(user_id_field);

string user_locale_field = user_profile.get_locale();
int user_age_field = user_profile.get_age();

I tried to modularize the design by putting the extraction logic for each field into its own class, so that I can do something like:

interface Extractor<T> {
    public static async T extract(JSON data);
}

class UserIdExtractor extends Extractor<int> { ... }
...

fields = await all (
    UserIdExtractor::extract(data),
    UserNameExtractor::extract(data),
    UserLocaleExtractor::extract(data),
    UserAgeExtractor::extract(data),
);

However, this will lead to repeated computation of the user profile in both UserLocaleExtractor and UserAgeExtractor. Even if I add an extra UserProfileExtractor, I can't think of a clean way to feed the result of one extractor to the input for other extractors.

Is there a common pattern for this kind of situation?

Aucun commentaire:

Enregistrer un commentaire