I have two methods in my objective-c class that do similar but different things. (they both retrieve a set of core-data records containing JSON, unpack and examine the JSON documents and do some stuff depending upon the structure of the JSON).
The first method looks like this:
+(NSDictionary*)getListOfResponsesWithForm:(NSString*)formId
{
NSError* requestError = nil;
// NSIndexSets don't allow easy targetted access into the set, so use arrays instead.
NSMutableArray* indexSetOfAllEntries = [[NSMutableArray alloc] init];
NSMutableArray* indexSetOfEntriesForLoggedOnUser = [[NSMutableArray alloc] init];
NSString* activeUserEmail = getActiveUser().email;
NSFetchRequest* fetchRequest = [ [NSFetchRequest alloc] init];
NSEntityDescription* entityDesc = [NSEntityDescription entityForName:@"Response" inManagedObjectContext:getApp().managedObjectContext];
[fetchRequest setEntity:entityDesc];
// Sort by lastmodifieddatelocal
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"lastmodifieddatelocal" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSArray* instances = [getApp().managedObjectContext executeFetchRequest:fetchRequest error:&requestError];
NSMutableArray* responses = [[NSMutableArray alloc] init];
for (Response* response in instances) {
NSData *jsonData = [response.json dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* dictionary = [HPSJSON getDictionaryFromDataWithoutSuccessTest:jsonData];
NSString* userEmailFromResponse = [HPSJSON getStringForKey: @"_useremail" inDictionary:dictionary];
NSString* formIdFromResponse = [HPSJSON getNestedIdForKey: @"_formid" inDictionary: dictionary];
if ([formId caseInsensitiveCompare:formIdFromResponse]==NSOrderedSame)
{
[responses addObject: response];
[indexSetOfAllEntries addObject:[NSNumber numberWithInt:responses.count-1]];
if ([activeUserEmail caseInsensitiveCompare:userEmailFromResponse]==NSOrderedSame)
{
[indexSetOfEntriesForLoggedOnUser addObject:[NSNumber numberWithInt:responses.count-1]];
}
}
}
NSMutableDictionary* results = [[NSMutableDictionary alloc] init];
[results setObject:responses forKey:@"responses"];
[results setObject:indexSetOfAllEntries forKey:@"allindexes"];
[results setObject:indexSetOfEntriesForLoggedOnUser forKey:@"indexesforactiveuser"];
return results;
}
The second method looks like this:
+(NSInteger)getCountOfResponsesWithForm:(NSString*)formId
{
NSError* requestError = nil;
NSString* activeUserEmail = getActiveUser().email;
NSFetchRequest* fetchRequest = [ [NSFetchRequest alloc] init];
NSEntityDescription* entityDesc = [NSEntityDescription entityForName:@"Response" inManagedObjectContext:getApp().managedObjectContext];
[fetchRequest setEntity:entityDesc];
NSArray* instances = [getApp().managedObjectContext executeFetchRequest:fetchRequest error:&requestError];
NSInteger countOfResponses=0;
for (Response* response in instances) {
NSData *jsonData = [response.json dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* dictionary = [HPSJSON getDictionaryFromDataWithoutSuccessTest:jsonData];
NSString* userEmailFromResponse = [HPSJSON getStringForKey: @"_useremail" inDictionary:dictionary];
NSString* formIdFromResponse = [HPSJSON getNestedIdForKey: @"_formid" inDictionary: dictionary];
if ([formId caseInsensitiveCompare:formIdFromResponse]==NSOrderedSame)
{
if ([activeUserEmail caseInsensitiveCompare:userEmailFromResponse]==NSOrderedSame)
{
countOfResponses++;
}
}
}
return countOfResponses;
}
There is quite a lot of duplicate code here, and I feel I am abusing DRY to some extent. However, attempting to combine the methods into one method will introduce some complication that will somewhat obfuscate what each individual method does.
Can anyone offer advice on the most elegant way to implement the functionality that is encompassed on both methods? Stay with the two methods? Create one more complex method sprinkled with conditions? Break out into a different class?
Is their a relevant design pattern for this scenario? Thanks.