iOS开发-迭代器模式

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。开发过程中,我们可能需要针对不同的需求,可能需要以不同的方式来遍历整个整合对象,但是我们不希望遍历的对象内部存储结构被外部知道,那么可以将对象包装成一个迭代器,迭代器中定义中遍历对象的方法下一个,是否存在下一个对象,删除等遍历需要的统一接口,迭代器在Java和.NET使用的比较多,自定义实现叶非常简单,可以简单的看一下迭代器模式的UML类图。

 

迭代器定义基本的遍历操作方法,容器定义公共的创建迭代器的方法,子类负责实现具体需要引用的迭代器,我们可以假设图书馆是一个抽象容器,图书馆下面分为国家图书馆和个人图书馆,个人图书馆存储书籍的方式是可变数组存储书籍,国家图书馆数据存储书籍,分别创建不同的迭代器;

BookLibrary容器接口:

@protocol BoolLibraryProtocol<NSObject>

@optional
-(Iterator *)createIterator;

@end

@interface BookLibrary : NSObject<BoolLibraryProtocol>

@end

 

CountryBookLibrary国家图书馆:

@interface CountryBookLibrary()

@property  (strong,nonatomic)  NSArray  *bookArr;

@end

@implementation CountryBookLibrary

- (instancetype)init
{
    self = [super init];
    if (self) {
       Book  *one=[self addBook:@"CountryBookLibrary" price:10];
       Book *next=[self addBook:@"博客园-FlyElephant" price:20];
        self.bookArr=@[one,next];
    }
    return self;
}

-(Iterator *)createIterator{
    return [[CountryIterator alloc]initWithData:self.bookArr];
}

-(Book *)addBook:(NSString *)bookName  price:(float)price{
    Book *book=[[Book alloc]init];
    book.bookName=bookName;
    book.price=price;
    return  book;
}

@end

PersonLibraryBook个人图书馆:

@interface PersonBookLibray()

@property  (strong,nonatomic)  NSMutableArray  *books;

@end

@implementation PersonBookLibray

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self addBook:@"PersonIterator" price:100];
        [self addBook:@"博客园-FlyElephant" price:200];
    }
    return self;
}

-(Iterator *)createIterator{
    return [[PersonIterator alloc]initWithData:self.books];
}

-(void)addBook:(NSString *)bookName  price:(float)price{
    Book *book=[[Book alloc]init];
    book.bookName=bookName;
    book.price=price;
    [self.books addObject:book];
}

#pragma mark - getter and  setter
-(NSMutableArray *)books{
    if (!_books) {
        _books=[[NSMutableArray alloc]init];
    }
    return _books;
}

@end

迭代器Iterator:

@protocol IteratorProtocol <NSObject>

@optional
-(Boolean)hasNext;

@optional
-(id)next;

@end

@interface Iterator : NSObject<IteratorProtocol>

@end

国家图书馆引用的迭代器:

@interface  CountryIterator()

@property  (strong,nonatomic)  NSArray  *arr;
@property  (assign,nonatomic)  NSInteger position;

@end

@implementation CountryIterator

-(instancetype)initWithData:(NSArray *)data{
    self=[super init];
    if (self) {
        self.arr=data;
    }
    return self;
}

-(Boolean)hasNext{
    if (self.position>=[self.arr count]||!self.arr[self.position]) {
        return false;
    }else{
        return true;
    }
}

-(id)next{
    Book *book=self.arr[self.position];
    self.position+=1;
    return book;
}

@end

个人图书馆引用的迭代器:

@interface PersonIterator()

@property (assign,nonatomic)  NSInteger            position;
@property (strong,nonatomic)  NSMutableArray       *mutableArr;

@end

@implementation PersonIterator

-(instancetype)initWithData:(NSMutableArray *)data{
    self=[super init];
    if (self) {
        self.mutableArr=data;
    }
    return self;
}

-(Boolean)hasNext{
    if (self.position>=[self.mutableArr count]||![self.mutableArr objectAtIndex:self.position]) {
        return false;
    }else{
        return true;
    }
}

-(id)next{
    Book *book=[self.mutableArr objectAtIndex:self.position];
    self.position+=1;
    return book;
}

@end

实际调用:

-(void)iteratorDesign{
    BookLibrary *personLibrary=[[PersonBookLibray alloc]init];
    Iterator    *personIterator=[personLibrary createIterator];
    [self logLibraryInfo:personIterator];
    
    BookLibrary *countryLibrary=[[CountryBookLibrary alloc]init];
    Iterator    *countryIterator=[countryLibrary createIterator];
    [self logLibraryInfo:countryIterator];
}

-(void)logLibraryInfo:(Iterator *)iterator{
    while ([iterator hasNext]) {
        Book *book=[iterator next];
        NSLog(@"书名:%@--价格:%ld",book.bookName,book.price);
    }
}

 测试结果:

迭代器模式的优点:支持以不同的方式遍历一个聚合对象(不同的聚合对象不同的遍历方式),迭代器简化了聚合类(统一接口),在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码(假设新增字典迭代器,直接添加就行,符合对扩展开放,对修改关闭的原则0)

缺点:  迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。不过集合类型总共就几种,基本上系统使用没有问题,个人使用的需注意一下;  

posted @ 2016-01-15 10:29  Fly_Elephant  阅读(614)  评论(0编辑  收藏  举报