2011-11-09 17 views
5

Tôi có một câu lệnh if khá dài. Câu lệnh if kiểm tra một chuỗi "type" để xác định loại đối tượng nào cần được khởi tạo. Đây là mẫu ...Các cách để thay thế câu lệnh if lớn với cấu trúc thay thế trong Mục tiêu-C

if ([type rangeOfString:@"coin-large"].location != NSNotFound) 
{ 
    ... create large coin ... 
    mgr = gameLayer.coinLargeMgr; 
} 
else if ([type rangeOfString:@"coin-small"].location != NSNotFound) 
{ 
    mgr = gameLayer.coinLargeMgr; 
} 

... more else statements ... 

myObject = [mgr getNewObject]; 

Câu lệnh "else-if" tiếp tục cho các loại đối tượng khác hiện có khoảng 20 và số đó có thể tăng lên. Điều này hoạt động khá tốt nhưng về mặt bảo trì và hiệu quả, tôi nghĩ rằng nó có thể được cải thiện. Ứng cử viên hàng đầu của tôi ngay bây giờ là tạo ra một khóa NSDictionary trên chuỗi loại đối tượng (đồng xu nhỏ, đồng xu lớn, v.v.) và với giá trị của đối tượng người quản lý cần được gắn với loại đó. Ý tưởng được rằng đây sẽ là một cái nhìn nhanh chóng cho các loại đối tượng tôi cần phải tạo ra. Bạn không chắc đây là cách tiếp cận tốt nhất, tiếp tục xem xét các tùy chọn khác nhưng tôi tò mò về những gì mà mọi người ở đây có thể đã làm cho một vấn đề tương tự. Bất kỳ trợ giúp/phản hồi nào được đánh giá cao.

+0

Sử dụng từ điển NSD cho việc này. –

+0

Tôi muốn ott thứ hai. Lặp lại thông qua một NSArray hoặc -Dictionary đầy NSStrings. Vì vậy, bạn làm một cái gì đó như '[type rangeOfString: [myArray objectAtIndex: i]] .location! = NSNotFound'. Ngoài ra, nếu bạn cần "người quản lý" khác nhau, hãy đặt người quản lý có trách nhiệm trong NSDictionary để có thể dễ dàng tra cứu. – Paul

+0

Tôi nghĩ về một cái gì đó đơn giản hơn như 'mgr = [dict valueForKey: coinString]; ' –

Trả lời

5

Cách tiếp cận từ điển sẽ dễ dàng thực hiện được. Giả sử các nhà quản lý khác nhau đã được luộc xuống đến trường hợp cụ thể khi bạn tạo từ điển, nó muốn được chỉ giống như hầu hết các hướng đối tượng ngôn ngữ:

NSDictionary *stringsToManagers = 
    [NSDictionary dictionaryWithObjectsAndKeys: 
     @"coin-large", gameLayer.coinLargeMgr, 
     @"coin-small", gameLayer.coinSmallMgr, 
     nil]; 

// this is assuming that type may contain multiple types; otherwise 
// just use [stringsToManagers objectForKey:string] 
for(NSString *string in [stringsToManagers allKeys]) 
{ 
    if([type rangeOfString:string].location != NSNotFound) 
    { 
     [[stringsToManagers objectForKey:string] addNewObject]; 
     // or get it and store it wherever it should go 
    } 
} 

Nếu tất cả các nhà quản lý làm là vend đối tượng thích hợp, cách tiếp cận hướng đối tượng hơn có thể là:

NSDictionary *stringsToClasses = 
    [NSDictionary dictionaryWithObjectsAndKeys: 
     @"coin-large", [LargeCoin class], 
     @"coin-small", [SmallCoin class], 
     nil]; 

// this is assuming that type may contain multiple types; otherwise 
// just use [stringsToManagers objectForKey:string] 
for(NSString *string in [stringsToManagers allKeys]) 
{ 
    if([type rangeOfString:string].location != NSNotFound) 
    { 
     id class = [stringsToManagers objectForKey:string]; 

     id newObject = [[class alloc] init]; 
     // this is exactly the same as if, for example, you'd 
     // called [[LargeCoin alloc] init] after detecting coin-large 
     // within the input string; you should obviously do something 
     // with newObject now 
    } 
} 

Điều đó có thể giúp bạn viết bất kỳ người quản lý nào nếu cấu trúc chương trình của bạn phù hợp.

+0

Cảm ơn phản hồi của Tommy. Tôi sẽ đi với cách tiếp cận này. –

6

Bạn có thể sử dụng NSDictionary chứa ObjC 'Blocks' để thực hiện lệnh chuyển đổi giống như thực thi mã mong muốn. Vì vậy, hãy một cuốn từ điển với các phím chuỗi của bạn ánh xạ tới một khối mã để thực thi khi từng được tìm thấy:

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: 
         ^{ NSLog(@"found key1"); }, @"key1", 
         ^{ NSLog(@"found key2"); }, @"key2", 
         nil]; 

Bạn có lẽ sẽ chuẩn bị từ điển này chỉ một lần tại một số giai đoạn đầu như thế nào trong một constructor hoặc một initializer tĩnh để rằng nó đã sẵn sàng khi mã sau của bạn thực hiện.

Sau đó, thay vì bạn if/else khối, cắt ra chìa khóa chuỗi từ bất cứ intput bạn nhận được (hoặc có thể bạn sẽ không cần phải cắt nó, bất cứ điều gì):

NSString *input = ... 
NSRange range = ... 
NSString *key = [input substringWithRange:range]; 

Và làm (nhanh) tra cứu từ điển để mã thực thi. Sau đó, thực hiện:

void (^myBlock)(void) = [dict objectForKey:key]; 
myBlock(); 
+0

Cách tiếp cận tốt đẹp bằng cách sử dụng các khối. Một cách tiếp cận khác mà sẽ duy trì logic instantiation một cách riêng biệt (có thể hoặc có thể không được mong muốn tùy thuộc vào kiến ​​trúc hiện có) sẽ lưu trữ tên phương thức thích hợp như một chuỗi trong từ điển. Sau đó, bạn có thể tạo động một bộ chọn từ chuỗi. Điều này kém hiệu quả hơn việc sử dụng các khối hoặc bộ chọn tĩnh, nhưng đó là một khả năng. – isaac

+1

Đảm bảo rằng nếu bạn không sử dụng ARC, bạn sao chép/tự động phát hành các khối theo cách thủ công, vì các khối được cấp phát trên ngăn xếp. – Wevah

+0

Tôi nhận xét thứ hai của Wevah ở trên. –

Các vấn đề liên quan