2013-01-08 23 views
2

我有兩個方法在我的objective-c類中做類似但不同的事情。 (它們都檢索一組包含JSON的核心數據記錄,解壓並檢查JSON文檔,並根據JSON的結構做一些事情)。處理類似方法的設計模式

第一種方法是這樣的:

+(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; 

} 

第二種方法是這樣的:

+(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; 

} 

有相當多的重複的代碼在這裏,我覺得我濫用幹在一定程度上。但是,嘗試將這些方法合併到一個方法中會引入一些複雜性,這會使某種方法的功能稍微混淆一些。

任何人都可以就執行該是在這兩種方法所包含的功能,最優雅的方式提供建議?留下兩種方法?創建一個更復雜的方法撒上條件?分成不同的班級?

是他們這個場景相關的設計模式?謝謝。

回答

0

使用設計模式,訪客或命令。這使您可以解耦讀取並迭代要採取的操作的響應。

你這裏有什麼兩樣東西:一個準備+環+編組步驟和處理步驟。一部分是相同的(前者),另一部分是不同的(後者)。所以你想排除後者,所以你可以避免前者的幾個副本。

您可以通過將處理步驟設置爲在子類中重載的虛擬方法,或者通過傳入可執行此步驟的「某些內容」來完成此操作。這個「東西」通常是一個Command或一個Visitor。

這一切都歸結爲是否要使用繼承或組合。我個人傾向於喜歡構圖。

1

我建議:

  1. 確定共同的塊(例如,NSFetchRequest * fetchRequest ...,NSEntityDescription * entityDesc);

  2. 對於每個公共塊,定義得到適當的參數和做什麼需要它們的方法;

  3. 調用這樣的方法來改善乾燥,例如:

    <getInstances> 
    <for each instance> 
        <extract data from instance> 
        <do your processing on data> 
    

我不認爲在設計模式方面,而在這種情況下,重構的條款。 你當然可以把它封裝在自己的類中,但是我不知道當前包含你的代碼的類所扮演的角色,所以我不能說更詳細的東西。我傾向於在更高的抽象層次上使用設計模式(這就是爲什麼他們被稱爲設計模式,儘管許多模塊在架構級別上最爲有用)。在這種情況下,我認爲一些重構的食譜(如你可能會發現它們使用谷歌搜索)更適合。

0

我不擅長和Xcode,所以讓我寫一些邏輯來代替。

在我看來,你的第二個方法可以簡化爲:

int getCountOfResponsesWithForm(String a) 
{ 
    Dictionary dic = getListOfResponsesWithForm(a); 
    return dic.length(); 
} 

您可能感興趣的閱讀Facade Design Pattern

+0

你是絕對正確的。我沒有像這樣實現它的原因是性能(計數可能相當高,而且在我看來,內存使用可能不必要地這樣做)。好點,謝謝。 – Journeyman