lundi 8 août 2016

Avoiding constant checking to ensure json object contains elements

I'm writing some code and I have that feeling of urgh that I get when it feels ugly and inelegant but I can't see an immediate way to avoid it.

I have a json object that I'm getting from a third party. I know what to expect but I can't be sure that each element will definitely be there so I need to check that it exists like this:

if (object.has(ELEMENT)) {
  JsonObject element = object.get(ELEMENT);
}

The problem is that I sometimes have to go pretty deep into the object and it begins to feel ugly when I get so many nested ifs. Here is an example:

private boolean lineExists(JsonArray orders, Line lineItem) {
    final String LINE_ITEMS = "lineItems";
    final String ELEMENTS = "elements";
    final String NOTE = "note";
    boolean exists = false;

    log.debug("Checking if line item already exists in order...");

    // if there is no order payload then the order hasn't already been posted so there can't be a duplicate line item
    if (orders != null) {
        for (int i = 0; i < orders.size(); i++) {
            JsonObject order = orders.get(i).getAsJsonObject();
            if (order.has(LINE_ITEMS)) {
                JsonObject lineItems = order.get(LINE_ITEMS).getAsJsonObject();
                if (lineItems.has(ELEMENTS)) {
                    JsonArray elements = lineItems.get(ELEMENTS).getAsJsonArray();
                    for (int j = 0; j < elements.size(); j++) {
                        JsonObject existingLine = elements.get(j).getAsJsonObject();
                        if (existingLine.has(NOTE)) {
                            String note = existingLine.get(NOTE).getAsString();
                            // the note may change after this comparison so just check if the ID is contained in the
                            // note
                            if (note.contains(lineItem.getNote())) {
                                exists = true;

                                log.warn("Line item with note containing '{}' already exists in order.",
                                        lineItem.getNote());
                            }
                        }
                    }
                }
            }
        }
    }

    return exists;
}

I know I can split some of the tests out into their own method like this:

private boolean lineExistCheck(JsonObject order) {
    final String LINE_ITEMS = "lineItems";
    final String ELEMENTS = "elements";

    return order.has(LINE_ITEMS) && order.get(LINE_ITEMS).getAsJsonObject().has(ELEMENTS);
}

I'm just wondering if there is a design pattern or a way of thinking that would help me write better code in this circumstance.

Aucun commentaire:

Enregistrer un commentaire