-2

There can be two types of groups- private and public. Each group can have members in it. I have three parameters id, includePrivate, includePublic to be passed into a method to return the groups as per the rules below. For eg.

public List<Group> getListofGroups(String id, Boolean isPrivate, Boolean   isPublic){}
  1. All groups {}
  2. all private groups {"includePrivate": true}
  3. all public groups {"includePublic": true}
  4. all private groups with membership {"id":"id1", "includePrivate": true }
  5. all private groups with membership + all public groups {"id":"id1", "includePrivate": true, "includePublic": true }

What is the best way to implement this complex if/else logic? Is it a good option to create a rules engine just for this api?

 For eg. if(isPrivate && isPublic && id=!null) {
    return publicAndPrivateWIthMembership();
} else if(isPrivate && id=!null ) {
    return privateGroupsWithMembership();
} else if((isPublic && !isPrivate) ||(isPublic && isPrivate == null) ) {
    return allPublicGroups();
} else if((isPrivate && !isPublic) ||(isPrivate && isPublic == null) ) {
    return allPrivateGroups();
}........

2 Answers2

1

Something like this, not really that complex, assuming null means false:

public List list(String id, Boolean includePrivate, Boolean includePublic) {
    boolean inclPrivate = (includePrivate != null && includePrivate);
    boolean inclPublic = (includePublic != null && includePublic);
    List result = new ArrayList();
    if (inclPublic || ! inclPrivate)
        result.addAll(getAllPublic());
    if (inclPrivate && id != null)
        result.addAll(getPrivateMembers(id));
    else if (inclPrivate || ! inclPublic)
        result.addAll(getAllPrivate());
    return result;
}

Of course, if you're actually querying a database, you could dynamically build the WHERE clause, but since you don't say....

Andreas
  • 154,647
  • 11
  • 152
  • 247
0

You could use the "null means don't care" paradigm. Something like:

private List<Group> groups;

public List<Group> getGroups(String id, Boolean includePrivate, Boolean includePublic) {
    return groups.stream()
        .filter(g -> id == null || g.getId().equals(id))
        .filter(g -> includePrivate == null || g.isPrivate() == includePrivate)
        .filter(g -> includePublic== null || g.isPublic() == includePublic)
        .collect(Collectors.toList());
}

The above does AND logic. If you want OR logic, do it in one filter:

public List<Group> getGroups(String id, Boolean includePrivate, Boolean includePublic) {
    return groups.stream()
        .filter(g -> (id == null || g.getId().equals(id))) || 
           (includePrivate == null || g.isPrivate() == includePrivate)) ||
           (includePublic== null || g.isPublic() == includePublic)))
        .collect(Collectors.toList());
}

or defer the predicate to the caller for a totally flexible API:

public List<Group> getGroups(Predicate<Group> predicate) {
     return groups.stream().filter(predicate).collect(Collectors.toList());
}
Bohemian
  • 412,405
  • 93
  • 575
  • 722