C++设计模式之迭代器模式

这篇具有很好参考价值的文章主要介绍了C++设计模式之迭代器模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【声明】本题目来源于卡码网(https://kamacoder.com/)

【提示:如果不想看文字介绍,可以直接跳转到C++编码部分


【设计模式大纲】

【简介】

        --什么是迭代器模式(第19种设计模式)

        迭代器模式是⼀种行为设计模式,是⼀种使⽤频率⾮常⾼的设计模式,在各个语⾔中都有应用,其主要⽬的是提供⼀种统⼀的⽅式来访问⼀个聚合对象中的各个元素,而不需要暴露该对象的内部表示。通过迭代器,客户端可以顺序访问聚合对象的元素,而无需了解底层数据结构。

迭代器模式应⽤⼴泛,但是⼤多数语⾔都已经内置了迭代器接⼝,不需要⾃⼰实现。


【基本结构】

        迭代器模式包括以下⼏个重要角色

  • 迭代器接口Iterator :定义访问和遍历元素的接⼝, 通常会包括hasNext() ⽅法⽤于检查是否还有下⼀个元素,以及next() ⽅法⽤于获取下⼀个元素。有的还会实现获取第⼀个元素以及获取当前元素的⽅法。
  • 具体迭代器ConcreateIterator :实现迭代器接⼝,实现遍历逻辑对聚合对象进⾏遍历。
  • 抽象聚合类:定义了创建迭代器的接⼝,包括⼀个createIterator ⽅法⽤于创建⼀个迭代器对象。
  • 具体聚合类:实现在抽象聚合类中声明的createIterator() ⽅法,返回⼀个与具体聚合对应的具体迭代器

C++设计模式之迭代器模式,c++,设计模式,迭代器模式,java,python


【简易实现--Java】

        下面以Java代码作以说明:

1. 定义迭代器接口:通常会有检查是否还有下⼀个元素以及获取下⼀个元素的⽅法。

// 迭代器接⼝
public interface Iterator{
    // 检查是否还会有下⼀个元素
    boolean hasNext();
    // 获取下⼀个元素
    Object next();
}

2. 定义具体迭代器:实现迭代器接口,遍历集合。

public class ConcreteIterator implements Iterator {
    private int index;
    private List<Object> elements;
    // 构造函数初始化迭代器
    public ConcreteIterator(List<Object> elements) {
        this.elements = elements;
        this.index = 0;
    }
    @Override
    public boolean hasNext() {
        return index < elements.size();
    }
    @Override
    public Object next() {
        if (hasNext()) {
            return elements.get(index++);
        }
        return null;
    }
}

3. 定义聚合接口:通常包括createIterator() ⽅法,⽤于创建迭代器

public interface Iterable {
    Iterator createIterator();
}

4. 实现具体聚合:创建具体的迭代器

// 具体聚合
public class ConcreteIterable implements Iterable {
    private List<Object> elements;
    // 构造函数初始化可迭代对象
    public ConcreteIterable(List<Object> elements) {
        this.elements = elements;
    }
    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(elements);
    }
}

5. 客户端使用

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file TemplateMethodMode.hpp
* @brief 模板方法模式
* @autor 写代码的小恐龙er
* @date 2024/01/23
*/
import java.util.ArrayList;
import java.util.List;
public class IteratorPatternExample {
    public static void main(String[] args) {
        List<Object> elements = new ArrayList<>();
        elements.add("Element 1");
        elements.add("Element 2");
        elements.add("Element 3");

        Iterable iterable = new ConcreteIterable(elements);
        Iterator iterator = iterable.createIterator();

        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

【使用场景】

        迭代器模式是⼀种通用的设计模式,其封装性强,简化了客户端代码,客户端不需要知道集合的内部结构,只需要关心迭代器和迭代接口就可以完成元素的访问。但是引⼊迭代器模式会增加额外的类,每增加⼀个集合类,都需要增加该集合对应的迭代器,这也会使得代码结构变得更加复杂。
        许多编程语⾔和框架都使用了这个模式提供⼀致的遍历和访问集合元素的机制。下⾯是几种常见语⾔迭代器模式的实现。

1. Java语言

        集合类(如ArrayList、LinkedList), 通过Iterator 接⼝,可以遍历集合中的元素。

List<String> list = new ArrayList<>();
list.add("Item 1");
list.add("Item 2");
list.add("Item 3");

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

2. Python语言

        使用迭代器和⽣成器来实现迭代模式, iter() 和next() 函数可以⽤于创建和访问迭代器。

elements = ["Element 1", "Element 2", "Element 3"]
iterator = iter(elements)

while True:
    try:
        element = next(iterator)
        print(element)
    except StopIteration:
        break

3. C++语言

        C++中的STL提供了迭代器的⽀持, begin() 和end() 函数可以⽤于获取容器的起始和结束迭代器。

#include <iostream>
#include <vector>
int main() {
    std::vector<std::string> elements = {"Element 1", "Element 2", "Element 3"};
    for (auto it = elements.begin(); it != elements.end(); ++it) {
        std::cout << *it << std::endl;
    }
    return 0;
}

4. JavaScript语言

        ES6中新增了迭代器协议,使得遍历和访问集合元素变得更加方便。

// 可迭代对象实现可迭代协议
class IterableObject {
    constructor() {
        this.elements = [];
    }
    addElement(element) {
        this.elements.push(element);
    }
    [Symbol.iterator]() {
        let index = 0;
        // 迭代器对象实现迭代器协议
        return {
            next: () => {
                if (index < this.elements.length) {
                    return { value: this.elements[index++], done: false };
                } else {
                    return { done: true };
                }
            }
        };
    }
}
// 使⽤迭代器遍历可迭代对象
const iterableObject = new IterableObject();
iterableObject.addElement("Element 1");
iterableObject.addElement("Element 2");
iterableObject.addElement("Element 3");

for (const element of iterableObject) {
    console.log(element);
}

【编码部分】

1. 题目描述

        小明是一位老师,在进行班级点名时,希望有一个学生名单系统,请你实现迭代器模式提供一个迭代器使得可以按顺序遍历学生列表。

2. 输入描述

        第一行是一个整数 N (1 <= N <= 100), 表示学生的数量。接下来的 N 行,每行包含一个学生的信息,格式为 姓名 学号;

3. 输出描述

        输出班级点名的结果,即按顺序遍历学生列表,输出学生的姓名和学号;

4. C++编程实例

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file IteratorMode.hpp
* @brief 迭代器模式
* @autor 写代码的小恐龙er
* @date 2024/01/23
*/

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>

using namespace std;

// 前置声明

// 聚合元素类 -- 学生
class Student;

// 迭代器接口 -- 提前声明模板
template<class T>
class Iterator;

// 具体迭代器 -- 学生遍历 迭代类
class ConcreteStudentIterator;

// 聚合接口 -- 学生全体类
class StudentCollection;

// 具体的聚合类 -- 创建全体学生
class ConcreteStudentCollection;

// 类的实现

// 聚合元素类 -- 学生
class Student{
// 成员数据
private:
    string _name;
    int _idNumber;
// 成员函数
public:
    // 构造函数
    Student(string name, int id){
        this->_name = name;
        this->_idNumber = id;
    }
    // 获取成员数据
    string GetName(){
        return this->_name;
    }
    int GetIdNumber(){
        return this->_idNumber;
    }
};

// 迭代器接口
// 类模板 
template<class T>
class Iterator{
// 迭代器接口
public:
    // 接口函数声明为 纯虚函数
    virtual bool isHavNext() = 0;
    virtual T* Next() = 0;
};

// 具体迭代器 -- 学生遍历 迭代类
class ConcreteStudentIterator : public Iterator<Student>
{
// 成员数据 
private:
    std::vector<Student *> _studentsVec;
    int _currentIndex = 0;
// 成员函数
public:
    // 构造函数
    ConcreteStudentIterator(std::vector<Student *> studentsVec){
        this->_studentsVec = studentsVec;
    }
    // 重载接口函数
    bool isHavNext() override{
        return _currentIndex < _studentsVec.size();
    }
    Student*  Next() override {
        if(isHavNext()){
            return _studentsVec[_currentIndex++];
        }
        return nullptr;
    }
};

// 聚合接口 -- 学生全体类
class StudentCollection
{
// 迭代器对象 接口函数
public:
    virtual Iterator<Student> * iterator() = 0;
};

// 具体的聚合类 -- 创建全体学生
class ConcreteStudentCollection : public StudentCollection
{
// 成员数据 
private:
    std::vector<Student *> _students;
// 成员函数
public:
    // 构造函数
    ConcreteStudentCollection(){}
    ConcreteStudentCollection(std::vector<Student *> students){
        this->_students = students;
    }
    // 添加学生对象
    void AddStudent(Student * student){
        _students.push_back(student);
    }
    // 迭代器接口函数重载  返回值为迭代器基类的指针 模板类型为Student
    Iterator<Student> * iterator() override{
        // 涉及到 隐式地 向上类型转换 派生类 转换为 基类 线程安全
        return new ConcreteStudentIterator(_students);
    }
};

int main()
{
    // 学生数量
    int studentNum = 0;
    // 输入
    std::cin >> studentNum;
    // 创建学生类
    Student *student = nullptr;
    // 创建具体可迭代对象
    ConcreteStudentCollection *concreteStudentCollection = new ConcreteStudentCollection();
    // 学生遍历
    for(int i = 0; i < studentNum; i++){
        // 学生姓名和学号
        string name = "";
        int numberId = 0;
        // 输入
        std::cin >> name >> numberId;
        // 构造学生类
        student = new Student(name, numberId);
        // 将学生放入 学生收集器类 中 
        concreteStudentCollection->AddStudent(student);
    }
    
    // 遍历结束后 再来通过迭代器模式 进行 信息打印
    // 调用具体聚合类中的 迭代器生成 接口!
    Iterator<Student> *iterator = concreteStudentCollection->iterator();
    while(iterator->isHavNext()){
        // 从迭代器中的学生集合获取学生类
        student = iterator->Next();
        // 打印学生信息
        if(student != nullptr){
            // 由于学生类中的成员数据为私有类型 记得调用接口函数去获取成员数据
            // 输出长度不足补0; 固定输出长度为3;
            std::cout << student->GetName() << " " << setw(3) << setfill('0') << student->GetIdNumber() << endl;
        }
        else std::cout << "Invalid input" << endl;
        
    }
    
    // 记得析构!!!
    // 记得析构!!!
    // 记得析构!!!
    if(student != nullptr){
        delete student;
        student = nullptr;
    }
    delete concreteStudentCollection;
    concreteStudentCollection = nullptr;
    
    return 0;
}




......

To be continued.文章来源地址https://www.toymoban.com/news/detail-821095.html

到了这里,关于C++设计模式之迭代器模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java 设计者模式以及与Spring关系(七) 命令和迭代器模式

    本文是个系列一次会出两个设计者模式作用,如果有关联就三个,除此外还会讲解在spring中作用。 23设计者模式以及重点模式 我们都知道 设计者模式 有 3 类 23 种设计模式,标红是特别重要的设计者模式建议都会,而且熟读于心,标蓝是指其次重要建议也要明白。 (1)创建

    2024年01月24日
    浏览(34)
  • 【设计模式——学习笔记】23种设计模式——迭代器模式Iterator(原理讲解+应用场景介绍+案例介绍+Java代码实现)

    编写程序展示一个学校院系结构: 需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系 【传统方式】 将学院看做是学校的子类,系是学院的子类,小的组织继承大的组织 分析: 在一个页面中展示出学校的院系组成,一个学校有多个

    2024年02月14日
    浏览(39)
  • C++设计模式_21_Iterator 迭代器(理解;面向对象的迭代器已过时;C++中使用泛型编程的方式实现)

    Iterator 迭代器也是属于“数据结构”模式。 GoF中面向对象的迭代器已经过时,C++中目前使用泛型编程的方式实现,其他语言还在使用面向对象的迭代器。 在软件构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以

    2024年02月07日
    浏览(54)
  • 设计模式——迭代器模式

    它提供一种方法访问一个容器对象中各个元素,而又不需要暴露该对象的内部细节。 迭代器是为容器服务的,能容纳元素的对象可以称为容器,例:List、Set、Map 迭代器模式(Iterator Pattern)已经是没落的设计模式,常用的容器基本都有成熟稳定的实现,基本不会再去单独写一

    2024年02月13日
    浏览(40)
  • 设计模式-迭代器模式

      迭代器模式(Iterator Design Pattern),也叫作游标模式(Cursor Design Pattern)。它用来遍历集合对象。这里说的“集合对象”也可以叫“容器”“聚合对象”,实际上就是包含一组对象的对象,比如数组、链表、树、图、跳表。迭代器模式将集合对象的遍历操作从集合类中拆

    2024年02月05日
    浏览(51)
  • 设计模式 ~ 迭代器模式

    迭代器是一种设计模式,提供了一种顺序访问集合或容器中元素的方法,无需暴露集合的内部结构,for 循环并不是迭代器模式 ,forEach 是最简易的迭代器。 以下函数实现了 next 方法,调用该方法返回集合中的下一个元素 value 表示当前迭代到的元素值 done 表示迭代是否已经结

    2024年02月16日
    浏览(35)
  • 设计模式:迭代器模式

    迭代器模式的示例可以涵盖各种数据结构的遍历,包括数组、列表、树、图等。下面是一些不同场景下迭代器模式的示例及其代码实现。 示例 1: 数组遍历 使用迭代器模式遍历数组。 示例 2: 二叉树的深度优先遍历 二叉树的深度优先遍历(使用栈实现)。 示例 3: 分页遍历 在

    2024年04月11日
    浏览(48)
  • 设计模式浅析(十) ·设计模式之迭代器&组合模式

    日常叨逼叨 java设计模式浅析,如果觉得对你有帮助,记得一键三连,谢谢各位观众老爷😁😁 案例 有两家门店,门店A呢只提供早餐,门店B呢只提供午餐,有一天这两家店铺想要进行合并,一起做大做强,再创辉煌。 合并后呢,对于菜单的定制存在了一定的问题: 门店A的

    2024年04月11日
    浏览(47)
  • 设计模式——迭代器模式15

    迭代器模式提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。 设计模式,一定要敲代码理解 迭代器模式将数据存储和数据遍历的职责进行分离。但针对不同结构的迭代对象,迭代方式需进行添加。 代码下载

    2024年04月15日
    浏览(46)
  • 行为型设计模式——迭代器模式

    迭代器模式也是非常的简单, 定义如下: 提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。 相信大家都使用过类似下面的迭代器: 如果在你的项目中需要对一个自定义的集合进行迭代遍历,那么迭代器模式是非常需要学习的。迭代器模式主

    2024年01月18日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包