c# - How to avoid convoluted logic for custom log messages in code? -


i know title little broad, i'd know how avoid (if possible) piece of code i've coded on solution of ours.

the problem started when code resulted in not enough log information:

... var users = [someremotingproxy].getusers([somecriteria]); try {     var user = users.single(); } catch (invalidoperationexception) {     logger.warnformat("either there no users corresponding search or there multiple users matching same criteria.");     return; } ... 

we have business logic in module of ours needs there single 'user' matches criteria. turned out that, when problems started showing up, little 'inconclusive' information not enough know happened, coded method:

private user getmappeduser([searchcriteria]) {     var users = [remotingproxy]            .getusers([searchcriteria])            .tolist();      switch (users.count())     {         case 0:             log.warn("no user exists [searchcriteria]");             return null;          case 1:             return users.single();          default:             log.warnformat("{0} users [{1}] have been found"                           users.count(),                            string.join(", ", users);             return null;     } 

and called main code this:

... var user = getmappeduser([searchcriteria]); if (user == null) return; ... 

the first odd thing see there switch statement on .count() on list. seems strange @ first, somehow ended being cleaner solution. tried avoid exceptions here because these conditions quite normal, , i've heard bad try , use exceptions control program flow instead of reporting actual errors. code throwing invalidoperationexception single before, more of refactor on end.

is there approach seemingly simple problem? seems kind of single responsibility principle violation, logs in between code , that, fail see decent or elegant way out of it. it's worse in our case because same steps repeated twice, once 'user' , 'device', this:

  1. get unique user
  2. get unique device of unique user

for both operations, important know happened, users/devices returned in case not unique, things that.

@antp hit upon answer best. think reason struggling have 2 problems here. first code seems have responsibility. apply simple test: give method simple name describes does. if name includes word "and", it's doing much. when apply test, might name "getusersbycriteriaandvalidateonlyoneusermatches()." doing 2 things. split lookup function doesn't care how many users returned, , separate function evaluates business rule regarding "i can handle 1 user returned".

you still have original problem, though, , switch statement seems awkward here. strategy pattern comes mind when looking @ switch statement, although pragmatically i'd consider overkill in case.

if want explore it, though, think creating base "usersearchresponsehandler" class, , 3 sub classes: nousersreturned; multipleusersreturned; , oneuserreturned. have factory method accept list of users , return usersearchresponsehandler based on count of users (encapsulating logic of switch inside factory.) each handler method right thing: log appropriate return null, or return single user.

the main advantage of strategy pattern comes when have multiple needs data identifies. if had switch statements buried on code depended on count of users found search, appropriate. factory can encapsulate substantially more complex rules, such "user.count must = 1 , user[0].level must = 42 , must tuesday in september". can fancy factory , use registry, allowing dynamic changes logic. finally, factory nicely separates "interpreting" of business rule "handling" of rule.

but in case, not much. i'm guessing have 1 occurrence of rule, seems pretty static, , it's appropriately located near point acquired information it's validating. while i'd still recommend splitting out search response parser, i'd use switch.

a different way consider goldilocks tests. if it's error condition, throw:

if (users.count() < 1) {     throw toofewusersreturnederror; }  if (users.count() > 1) {     throw toomanyusersreturnederror; }  return users[0];  // right 

Comments

Popular posts from this blog

html - How to style widget with post count different than without post count -

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

javascript - storing input from prompt in array and displaying the array -