笔记:Gof设计模式--Iterator

1、意图

  Provide a way to access the elements of an aggregate objectsequentially without exposing its underlying representation.

2、适应性

  Use the Iterator pattern
  •  to access an aggregate object's contents without exposing its internalrepresentation.
  •  to support multiple traversals of aggregate objects.
  •  to provide a uniform interface for traversing different aggregatestructures (that is, to support polymorphic iteration).

3、结构

4、示例代码

  The part of the List, The List class provides a reasonably efficient way to support iteration through its public interface.

template <class Item> 
class List { 
public: 
    List(long size = DEFAULT_LIST_CAPACITY); 
    long Count() const; 
    Item& Get(long index) const; 
    // ... 
}; 

  To enabletransparent use of the different traversals we define an abstractIterator class, which defines the iterator interface.

template <class Item> 
class Iterator { 
public: 
    virtual void First() = 0; 
    virtual void Next() = 0; 
    virtual bool IsDone() const = 0; 
    virtual Item CurrentItem() const = 0; 
protected: 
    Iterator(); 
}; 

  Iterator subclass implementations.ListIterator is a subclass of Iterator.

template <class Item> 
class ListIterator : public Iterator<Item> { 
public: 
    ListIterator(const List<Item>* aList); 
    virtual void First(); 
    virtual void Next(); 
    virtual bool IsDone() const; 
    virtual Item CurrentItem() const; 
private: 
    const List<Item>* _list; 
    long _current; 
}; 

template <class Item> 
ListIterator<Item>::ListIterator ( const List<Item>* aList ) 
 : _list(aList), _current(0) {    } 

template <class Item> 
void ListIterator<Item>::First () 
{        
    _current = 0;    
}
 

// Next advances the current element: 
template <class Item> 
void ListIterator<Item>::Next ()  
{
    _current++;    
} 

template <class Item> 
bool ListIterator<Item>::IsDone () const  
{        
    return _current >= _list->Count();    
} 

template <class Item> 
Item ListIterator<Item>::CurrentItem () const { 
    if (IsDone()) { 
       throw IteratorOutOfBounds; 
    } 
    return _list->Get(_current); 
} 


   Using the iterators. 

void PrintEmployees (Iterator<Employee*>& i) { 
    for (i.First(); !i.IsDone(); i.Next()){ 
       i.CurrentItem()->Print(); 
    } 
} 

List<Employee*>* employees; 
// ... 
ListIterator<Employee*> forward(employees); 
ReverseListIterator<Employee*> backward(employees); 
PrintEmployees(forward); 
PrintEmployees(backward); 

// SkipList ...
SkipList<Employee*>* employees; 
// ... 
SkipListIterator<Employee*> iterator(employees); 
PrintEmployees(iterator); 

  Although this approach works, it would be better if we didn't have to committo a specific List implementation, namely SkipList. We can introduce an AbstractListclass to standardize the list interface for different list implementations. List and SkipList becomesubclasses of AbstractList.

template <class Item> 
class AbstractList { 
public: 
    virtual Iterator<Item>* CreateIterator() const = 0; 
    // ...  
}; 


 

  List overrides CreateIterator(Factory method) to return aListIterator object: 

template <class Item> 
Iterator<Item>* List<Item>::CreateIterator () const { 
return new ListIterator<Item>(this);  

// Now we're in a position to write the code for printingthe employees 
// independent of a concrete representation. 
// we know only that we have an AbstractList 
AbstractList<Employee*>* employees; 
// ... 
Iterator<Employee*>* iterator = employees->CreateIterator(); 
PrintEmployees(*iterator); 
delete iterator; 


 

  Making sure iterators get deleted. we'll provide an IteratorPtr that acts as a proxy for aniterator. It takes care of cleaning up the Iterator objectwhen it goes out of scope.

template <class Item> 
class IteratorPtr { 
public: 
    IteratorPtr(Iterator<Item>* i): _i(i) { } 
    ~IteratorPtr() { delete _i; } 
    Iterator<Item>* operator->() { return _i; } 
    Iterator<Item>& operator*() { return *_i; } 
private: 
    // disallow copy and assignment to avoid 
    // multiple deletions of _i: 
    IteratorPtr(const IteratorPtr&); 
    IteratorPtr& operator=(const IteratorPtr&); 
private: 
    Iterator<Item>* _i; 
}; 

// IteratorPtr lets us simplify our printing code: 
AbstractList<Employee*>* employees; 
// ... 
IteratorPtr<Employee*> iterator(employees->CreateIterator()); 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值