跟着老侯玩编程 跟着老侯玩编程
首页
  • 基础语法
  • 设计模式
  • 基础语法
  • 课程目录
  • 码农宝典
网盘 (opens new window)
留言
首页
  • 基础语法
  • 设计模式
  • 基础语法
  • 课程目录
  • 码农宝典
网盘 (opens new window)
留言
  • 基础语法

    • 单元文件
    • 变量和常量
    • 内联变量
    • 基本数据类型
    • 复合数据类型
    • 语句(选择语句)
    • 语句(循环语句)
    • 数组
    • 初识例程
    • 初识面向对象
    • 属性Property
    • 面向对象的方法
    • 指针
    • 接口
    • 匿名函数和委托实现
    • 多态
    • 字符串详解
    • 异常处理
    • 反射机制
    • 泛型容器
    • JSON
    • 文件操作
    • Dll创建并调用
    • DLL初始化和退出处理
    • Package
    • 理解消息循环
    • VCL与Windows消息
    • 钩子原理
    • 进程通讯-内存映像
    • 多线程开篇
    • 线程控制
    • 线程同步
  • 设计模式

    • 单例模式
    • 单例模式二
    • 策略模式
    • 简单工厂模式
    • 建造者模式
    • 原型模式
    • 模板方法模式
    • 状态模式
    • 迭代器模式
      • 角色构成
      • 应用场景
      • 代码实现
      • 小结一下
    • 解释器模式
    • 责任链模式
    • 中介者模式
    • 备忘录模式
    • 命令模式
    • 观察者模式
    • 访问者模式
    • 适配器模式
    • 桥接模式
  • Delphi
  • 设计模式
舞动的代码
2022-04-29

迭代器模式

今天聊的是行为设计模式中的迭代器模式,如果是做 Java 的对于迭代器肯定不陌生。因为迭代器模式是Java和.Net编程环境中非常常用的设计模式。它的定义如下

迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

不知道为什么在 Delphi 的泛型容器中并没有提供这一类的东西。当然也可能是因为我的无知。。。。

# 角色构成

其实所谓的角色构成就是指由那些类组成,同时说明这些类都是什么关系。因为想不出合适的名字,又看到别人是这么称呼的,所以我也跟着叫了

迭代器角色(Iterator):一般来说会有这么三个方法:next()、hasNext()和remove()

具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代。

容器角色(Aggregate):一般是一个接口,提供一个iterator()方法,此处我们以数组为例,其实以什么容器类都可以

具体容器角色(ConcreteAggregate):实现抽象容器的抽象方法

类图如下(引子菜鸟教程):

# 应用场景

说完基础构成之后我们还要了解一下它的应用场景

  • 访问一个聚合对象的内容而无须暴露它的内部表示。

  • 需要为聚合对象提供多种遍历方式。

  • 为遍历不同的聚合结构提供一个统一的接口。

和其他设计模式它也有自己的缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加

# 代码实现

代码在DelphiXE10.4.2环境下编译通过

unit uIterator;

interface

type
    TNames = array [0 .. 1] of String;

    // 迭代器接口
    ITerator = Interface
        ['{BF2BE685-0193-4F92-9C77-1AF0B3D1D4DA}']
        function HasNext(): boolean;

        function Next(): string;
    End;

    // 抽象容器类
    TContainer = class abstract
    private
        FNames: TNames;

    public
        property Names: TNames read FNames write FNames;
        function GetIterator(): ITerator; virtual; abstract;
    End;

    // 容器实现类
    TNameRepository = class(TContainer)

    public
        constructor Create();
        function GetIterator(): ITerator; override;

    end;

    // 迭代器实现类
    TNameIterator = class(TInterfacedObject, ITerator)
    private
        FIndex: Integer;
        Container: TContainer;
    public
        function HasNext(): boolean;
        function Next(): string;
        constructor Create(Container: TContainer);
    end;

implementation

{ TNameRepository }

constructor TNameRepository.Create;
begin
    self.FNames[0] := '小黑';
    self.FNames[1] := '小白';

end;

function TNameRepository.GetIterator: ITerator;
begin
    Result := TNameIterator.Create(self);
end;

{ TNameRepository.TNameIterator }

constructor TNameIterator.Create(Container: TContainer);
begin
    self.FIndex := 0;
    self.Container := Container;
end;

function TNameIterator.HasNext: boolean;
begin

    Result := false;
    if (self.FIndex < length(self.Container.Names)) then begin

        Result := true;
    end;
end;

function TNameIterator.Next: string;
begin
    Result := '';
    if (self.HasNext) then begin

        Result := self.Container.Names[self.FIndex];

        inc(self.FIndex);
    end;
end;

end.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

调用

program ProjectIterator;

{$APPTYPE CONSOLE}
{$R *.res}

uses
    System.SysUtils,
    uIterator in 'uIterator.pas';

begin
    try
        // 创建容器类对象
        var
        Repository := TNameRepository.Create();
        // 获取迭代器对象
        var
        Iterator := Repository.GetIterator();

        // 通过迭代器获取元素
        while Iterator.hasNext do writeln(Iterator.Next);

    except
        on E: Exception do writeln(E.ClassName, ': ', E.Message);
    end;

    Readln;

end.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 小结一下

至此迭代器模式完成。我自己在学习设计模式的时候更多的是结合类图和代码。当看懂这两部分之后基本上就明白设计模式大概思路了。最后结合一下优缺点和适用场景。

最近重感冒了,调休在家实在没精神写文章和更新视频。今天终于感觉好点了

上次更新: 2022/05/05, 14:24:28
状态模式
解释器模式

← 状态模式 解释器模式→

Theme by Vdoing | Copyright © 2013-2022 冀ICP备16006233号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×