Skip to content

Instantly share code, notes, and snippets.

@fbiville
Last active December 12, 2015 05:48
Show Gist options
  • Save fbiville/4723796 to your computer and use it in GitHub Desktop.
Save fbiville/4723796 to your computer and use it in GitHub Desktop.
Refactoring puzzler: how to remove duplication here?
StringBuilder whereConstraints = new StringBuilder();
if (!isEmpty(typesActu)) {
whereConstraints.append(" AND a.type_id IN (?) ");
}
if (!isEmpty(newsletters)) {
whereConstraints.append(" AND (ap.profils_id IN (?) OR ap.profils_id IS NULL)");
}
if (!isNullOrEmpty(term)) {
whereConstraints.append(" AND (titre LIKE (?) OR texte_complet LIKE(?) ) ");
}
whereConstraints.append(" AND date_publication IS NOT NULL ");
if (beginDate != null) {
whereConstraints.append(" AND date_publication >= ?");
if (endDate != null) {
whereConstraints.append(" AND date_publication <= ?");
}
}
String limitClause = "";
if (limit != null) {
limitClause += " LIMIT ?";
}
final String sql = BASE_QUERY + whereConstraints.toString() + ORDER_BY_CLAUSE + limitClause;
return new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement statement = connection.prepareStatement(sql);
int position = 1;
if (!isEmpty(typesActu)) {
statement.setString(position++, concatActuTypes(typesActu));
}
if (!isEmpty(newsletters)) {
statement.setString(position++, concatNewsTypes(newsletters));
}
if (!isNullOrEmpty(term)) {
String likeTerm = "%" + term + "%";
statement.setString(position++, likeTerm);
statement.setString(position++, likeTerm);
}
if (beginDate != null) {
statement.setString(position++, beginDate.toString("yyyy-MM-dd"));
if (endDate != null) {
statement.setString(position++, endDate.toString("yyyy-MM-dd"));
}
}
statement.setInt(position, limit);
return statement;
}
};
@fsarradin
Copy link

Types de typesActu, newsletters, concatActuTypes, concatNewsTypes ? Ce sont / Ça traite des collections ? isEmpty et isNullOrEmpty ça vient de Guava ?

@fsarradin
Copy link

Une possibilité pour le premier bloc. On part avec trois méthodes :

public <T> String getWhenExists(Iterable<T> iterable, String value) {
    return isEmpty(iterable) ? "" : value;
}

public String getWhenExists(String string, String value) {
    return isNullOrEmpty(string) ? "" : value;
}

public String getWhen(boolean isTrue, String value) {
    return isTrue ? value : "";
}

Et on replace tout le premier bloc par :

    final String sql = new StringBuilder()
            .append(BASE_QUERY)
            .append(getWhenExists(typesActu, " AND a.type_id IN (?) "))
            .append(getWhenExists(newsletters, " AND (ap.profils_id IN (?) OR ap.profils_id IS NULL)"))
            .append(getWhenExists(term, " AND (titre LIKE (?) OR texte_complet LIKE(?) ) "))
            .append(" AND date_publication IS NOT NULL ")
            .append(getWhen(beginDate != null, " AND date_publication >= ?"))
            .append(getWhen(beginDate != null && endDate != null, " AND date_publication <= ?"))
            .append(ORDER_BY_CLAUSE)
            .append(getWhen(limit != null, " LIMIT ?")).toString();

Et je crois qu'à partir de Java 6, tu peux utiliser directement concaténations de chaînes à la place du StringBuilder. Il y a une conversion qui est faite directement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment