zoukankan      html  css  js  c++  java
  • [设计模式] 设计模式课程(十八)--迭代器模式

    概述

    • 属于行为型模式
    • 将集合的遍历行为抽取为单独的迭代器对象
    • 所有迭代器实现相同的接口,只要有合适的迭代器,客户端代码就能兼容任何类型的集合或遍历算法,如需采用特殊方法遍历集合,创建一个新的迭代器即可,而无需对集合或客户端进行修改
    • 集合对象内部结构常常变化各异,但对于这些集合对象,我们希望在不暴露其内部结构的同时,也可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为“同一种算法在多种集合对象上进行操作”提供了可能
    • 使用面向对象技术将这种遍历机制抽象为“迭代器模式”为“因对变化中的集合对象”提供了一种优雅的方式
    • 提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露(稳定)该对象内部的表示
    • 通过迭代器接口,隔离算法和容器之间的变化
    • 面向对象(虚函数)实现迭代器,虚函数调用存在性能问题(运行时多态),在迭代器循环中会造成较大损失(绕虚函数表指针找函数地址的运算),故在c++在98年后改用STL泛型编程模板实现迭代器(编译时多态)
    • Java、C#类库中依然使用面向对象实现迭代器
    • 迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示
    • 迭代多样:为遍历不同的集合提供一个统一的接口,从而支持同样的算法在不同集合结构上进行操作
    • 健壮性:迭代的同时更改迭代器所在的集合结构,会导致问题
    • ConcreteAggregate是具体聚合类(容器,如列表(List)或集合(Set)等),ConcreteIterator是容器对应的迭代器类

    场景

    • 采用自由行,手机导航,跟团等方式游览一个城市,城市的景点是一个集合,每个游览方式是一个迭代器

    结构

    • 迭代器接口:声明了遍历集合所需的操作
    • 具体迭代器类:实现遍历集合的一种特定算法
    • 集合接口:声明一个或多个方法获取与集合兼容的迭代器,返回迭代器接口
    • 具体集合类:客户端请求迭代器时返回一个特定的具体迭代器类实体
    • 客户端类:通过集合和迭代器接口与两者进行交互

    示例1

    Iterator.cpp

     1 template<typename T>
     2 class Iterator
     3 {
     4 public:
     5     virtual void first() = 0;
     6     virtual void next() = 0;
     7     virtual bool isDone() const = 0;
     8     virtual T& current() = 0;
     9 };
    10 
    11 template<typename T>
    12 class MyCollection{
    13     
    14 public:
    15     
    16     Iterator<T> GetIterator(){
    17         //...
    18     }
    19     
    20 };
    21 
    22 template<typename T>
    23 class CollectionIterator : public Iterator<T>{
    24     MyCollection<T> mc;
    25 public:
    26     
    27     CollectionIterator(const MyCollection<T> & c): mc(c){ }
    28     
    29     void first() override {
    30         
    31     }
    32     void next() override {
    33         
    34     }
    35     bool isDone() const override{
    36         
    37     }
    38     T& current() override{
    39         
    40     }
    41 };
    42 
    43 void MyAlgorithm()
    44 {
    45     MyCollection<int> mc;
    46     
    47     Iterator<int> iter= mc.GetIterator();
    48     
    49     for (iter.first(); !iter.isDone(); iter.next()){
    50         cout << iter.current() << endl;
    51     }
    52     
    53 }
    View Code

    示例2

     1 #include <iostream>
     2 #include <string>
     3 #include <vector>
     4 using namespace std;
     5 
     6 template <typename T, typename U>
     7 class Iterator{
     8     public:
     9         typedef typename vector<T>::iterator iter_type;
    10         Iterator(U *p_data, bool reverse = false):m_p_data_(p_data){
    11             m_it_ = m_p_data_->m_data_.begin();
    12         }
    13         
    14         void First(){
    15             m_it_ = m_p_data_ -> m_data_.begin();
    16         }
    17         
    18         void Next(){
    19             m_it_++; 
    20         } 
    21         
    22         bool IsDone(){
    23             return(m_it_ == m_p_data_ -> m_data_.end());
    24         }
    25         
    26         iter_type Current(){
    27             return m_it_;
    28         }
    29         
    30     private:
    31         U *m_p_data_;
    32         iter_type m_it_;
    33 }; 
    34 
    35 template <class T>
    36 class Container{
    37     friend class Iterator<T, Container>;
    38     public:
    39         void Add(T a){
    40             m_data_.push_back(a);
    41         }
    42         
    43         Iterator<T,Container> *CreateIterator(){
    44             return new Iterator<T, Container>(this);
    45         }
    46         
    47         private:
    48             vector<T> m_data_; 
    49 };
    50 
    51 class Data{
    52     public:
    53         Data(int a = 0): m_data_(a){}
    54         
    55         void set_data(int a){
    56             m_data_ = a;
    57         }
    58         
    59         int data(){
    60             return m_data_;
    61         }
    62         
    63         private:
    64             int m_data_;
    65 };
    66 
    67 void ClientCode(){
    68     cout<<"________________Iterator with int______________________________________"<<endl; 
    69     Container<int> cont;
    70     
    71     for(int i = 0 ; i < 10 ; i ++){
    72         cont.Add(i);
    73     }
    74     
    75     Iterator<int, Container<int>> *it = cont.CreateIterator();
    76     for(it->First(); !it->IsDone(); it->Next()){
    77         cout << *it->Current() << endl;
    78     }
    79     
    80     Container<Data> cont2;
    81     Data a(100),b(1000),c(10000);
    82     cont2.Add(a);
    83     cont2.Add(b);
    84     cont2.Add(c);
    85     
    86     cout<< "________________Iterator with custom Class______________________________"<<endl;
    87     Iterator<Data, Container<Data>> *it2 = cont2.CreateIterator();
    88     for(it2->First();!it2->IsDone();it2->Next()){
    89         cout << it2->Current()->data() << endl;
    90     }
    91 }    
    92 
    93 int main(){
    94     ClientCode();
    95     return 0;
    96 }
    View Code
    ________________Iterator with int______________________________________
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ________________Iterator with custom Class______________________________
    100
    1000
    10000

     示例3

     1 public interface Iterator {
     2     public boolean hasNext();
     3     public Object next();
     4 }
     5 
     6 public interface Container {
     7     public Iterator getIterator();
     8 }
     9 
    10 public class NameRepository implements Container{
    11     public String names[] = {"Robert" , "John" ,"Julie" , "Lora"};
    12 
    13     @Override
    14     public Iterator getIterator() {
    15         return new NameIterator();
    16     }
    17     
    18     private class NameIterator implements Iterator{
    19         int index; 
    20         
    21         @Override
    22         public boolean hasNext() {
    23             if(index < names.length) {
    24                 return true;
    25             }
    26             return false;
    27         }
    28 
    29         @Override
    30         public Object next() {
    31             if(this.hasNext()) {
    32                 return names[index++];
    33             }
    34             return null;
    35         }
    36     }
    37 }
    38 
    39 public class IteratorPatternDemo {
    40     public static void main(String[] args) {
    41     NameRepository namesRepository = new NameRepository();
    42     
    43     for(Iterator iter = namesRepository.getIterator();iter.hasNext();) {
    44         String name = (String)iter.next();
    45         System.out.println("Name : " + name);
    46         }
    47     }
    48 }
    View Code

    Name : Robert
    Name : John
    Name : Julie
    Name : Lora

    参考

    迭代器模式c++实现

    https://blog.csdn.net/u012611878/article/details/78010435

    CSDN:MachineChen

  • 相关阅读:
    HTTP 无法注册 URL http://+:xxxxx/ServicesName/。进程不具有此命名空间的访问权限
    C语言中宏的一些特别用法
    static和const的比较和解释
    堆和栈的区别
    c++中const用法
    链表常见笔试题
    自绘实现半透明水晶按钮 .
    C++面试题
    C/C++面试题大汇总
    C++ 值传递、指针传递、引用传递详解
  • 原文地址:https://www.cnblogs.com/cxc1357/p/12320383.html
Copyright © 2011-2022 走看看