容器的主要职责有两个:存放元素和浏览元素。根据单一职责原则(SRP)要将二者分开,于是将浏览功能打包封装就有了迭代器。

用迭代器封装对动态数组的遍历:

 1
 2{《HeadFirst设计模式》之迭代器模式 }
 3{ 容器中的元素类                  }
 4{ 编译工具:Delphi7.0             }
 5{ E-Mail :guzh-0417@163.com     }
 6
 7unit uItem;
 8
 9interface
10
11type
12  TMenuItem = class(TObject)
13  private
14    FName: String;
15    FDescription: String;
16    FVegetarian : Boolean;
17    FPrice: Double;
18  public
19    constructor Create(aName, aDescription: String;
20                       aVegetarian : Boolean;
21                       aPrice: Double);
22    function GetName: String;
23    function GetDescription: String;
24    function GetPrice: Double;
25    function IsVegetarian: Boolean;
26  end;
27
28implementation
29
30{ TMenuItem }
31
32constructor TMenuItem.Create(aName, aDescription: String;
33                             aVegetarian: Boolean;
34                             aPrice: Double);
35begin
36  FName  := aName;
37  FDescription := aDescription;
38  FVegetarian  := aVegetarian;
39  FPrice := aPrice;
40end;
41
42function TMenuItem.GetDescription: String;
43begin
44  Result := FDescription;
45end;
46
47function TMenuItem.GetName: String;
48begin
49  Result := FName;
50end;
51
52function TMenuItem.GetPrice: Double;
53begin
54  Result := FPrice;
55end;
56
57function TMenuItem.IsVegetarian: Boolean;
58begin
59  Result := FVegetarian;
60end;
61
62end.
 1
 2{《HeadFirst设计模式》之迭代器模式 }
 3{ 迭代器:封装对容器的遍历         }
 4{ 编译工具:Delphi7.0            }
 5{ E-Mail :guzh-0417@163.com    }
 6
 7unit uIterator;
 8
 9interface
10
11uses
12  uItem;
13
14type
15  TMenuItems = array of TMenuItem;
16  
17  TIterator = class(TObject)
18  public
19    function HasNext: Boolean; virtual; abstract;
20    function Next   : TObject; virtual; abstract;
21  end;
22
23  TDinerMenuIterator = class(TIterator)
24  private
25    FMenuItem : TMenuItem;
26    FMenuItems: TMenuItems;
27    FPosition : Integer;
28  public
29    constructor Create(MenuItems: TMenuItems);
30    function HasNext: Boolean; override;
31    function Next   : TObject; override;
32  end;
33
34implementation
35
36{ TDinerMenuIterator }
37
38constructor TDinerMenuIterator.Create(MenuItems: TMenuItems);
39begin
40  FMenuItems := MenuItems;
41end;
42
43function TDinerMenuIterator.HasNext: Boolean;
44begin
45  if (FPosition < Length(FMenuItems)) and (FMenuItems[FPosition] <> nil) then
46    Result := True
47  else
48    Result := False;
49end;
50
51function TDinerMenuIterator.Next: TObject;
52begin
53  FMenuItem := FMenuItems[FPosition];
54  FPosition := FPosition + 1 ;
55  Result := FMenuItem;
56end;
57
58end.
  1
  2{《HeadFirst设计模式》之迭代器模式 }
  3{ 容器类及其用户: Waitress       }
  4{ 编译工具:Delphi7.0            }
  5{ E-Mail :guzh-0417@163.com    } 
  6
  7unit uAggregate;
  8
  9interface
 10
 11uses
 12  SysUtils, uItem, uIterator;
 13
 14type
 15  TMenu = class(TObject)
 16  public
 17    function CreateIterator: TIterator; virtual; abstract;
 18  end;
 19
 20  TDinerMenu = class(TMenu)
 21  private
 22    FMenuItem : TMenuItem;
 23    FMenuItems: TMenuItems;
 24    FNumberOfItems: Integer;
 25  public
 26    constructor Create;
 27    destructor Destroy; override;
 28    procedure AddItem(aName, aDescription: String; aVegetarian: Boolean;
 29                      aPrice: Double);
 30    function CreateIterator: TIterator; override;
 31  end;
 32
 33  TWaitress = class(TObject)
 34  private
 35    FMenuItem : TMenuItem;
 36    FDinerMenu: TDinerMenu;
 37    DinerIterator: TIterator;
 38  public
 39    constructor Create(aDinerMenu: TDinerMenu);
 40    procedure PrintMenu; overload;
 41    procedure PrintMenu(aIterator: TIterator); overload;
 42  end;
 43  
 44implementation
 45
 46const
 47  MAX_TIMES = 6;
 48
 49{ TDinerMenu }
 50
 51procedure TDinerMenu.AddItem(aName, aDescription: String; aVegetarian: Boolean;
 52                             aPrice: Double);
 53begin
 54  FMenuItem := TMenuItem.Create(aName, aDescription, aVegetarian, aPrice);
 55  if FNumberOfItems >= MAX_TIMES then
 56    Writeln('Sorry, menu is full! Can''t add item to menu')
 57  else
 58  begin
 59    FMenuItems[FNumberOfItems] := FMenuItem;
 60    FNumberOfItems := FNumberOfItems + 1;
 61  end;
 62end;
 63
 64constructor TDinerMenu.Create;
 65begin
 66  SetLength(FMenuItems, MAX_TIMES);
 67  
 68  AddItem('Vegetarian BLT',
 69          'Fakin Bacon with lettuce & tomato on whole Wheat', True, 2.99);
 70  AddItem('BLT',
 71          'Bacon with lettuce & tomato on whole Wheat', False, 2.99);
 72  AddItem('Soup of the day',
 73          'Soup of the day, with a side of potato salad', False, 3.29);
 74  AddItem('Hotdog',
 75          'A hot dog, with saurkraut, relish, onions, topped with cheese',
 76          False, 3.05);
 77  AddItem('Steamed Veggies and Brown Rice',
 78          'Steamed vegetables over brown rice', True, 3.99);
 79  AddItem('Pasta',
 80          'Spaghetti with Marinara Sauce, and a slice of sourdough bread', True,
 81           3.89);
 82end;
 83
 84destructor TDinerMenu.Destroy;
 85begin
 86  FreeAndNil(FMenuItem);
 87  inherited;
 88end;
 89
 90function TDinerMenu.CreateIterator: TIterator;
 91begin
 92  Result := TDinerMenuIterator.Create(FMenuItems);
 93end;
 94
 95{ TWaitress }
 96
 97constructor TWaitress.Create(aDinerMenu: TDinerMenu);
 98begin
 99  FDinerMenu := aDinerMenu;
100end;
101
102procedure TWaitress.PrintMenu;
103begin
104  try
105    DinerIterator := FDinerMenu.CreateIterator;
106    Writeln('MENU');
107    Writeln('----');
108    Writeln('BREAKFAST');
109    Writeln;
110    PrintMenu(DinerIterator);
111  finally
112    FreeAndNil(DinerIterator);
113  end;
114end;
115
116procedure TWaitress.PrintMenu(aIterator: TIterator);
117begin
118  while (aIterator.HasNext) do
119  begin
120    FMenuItem := (aIterator.Next) as TMenuItem;
121    Writeln(FMenuItem.GetName + ',');
122    Writeln(FMenuItem.GetPrice, ' -- ');
123    Writeln(FMenuItem.GetDescription);
124  end;
125end;
126
127end.
 1
 2{《HeadFirst设计模式》之迭代器模式 }
 3{ 客户端                         }
 4{ 编译工具:Delphi7.0            }
 5{ E-Mail :guzh-0417@163.com    }
 6
 7program pMenuTestDrive;
 8
 9{$APPTYPE CONSOLE}
10
11uses
12  SysUtils,
13  uItem in 'uItem.pas',
14  uAggregate in 'uAggregate.pas',
15  uIterator in 'uIterator.pas';
16
17var
18  DinerMenu: TDinerMenu;
19  Waitress : TWaitress;
20
21begin
22  DinerMenu := TDinerMenu.Create;
23  Waitress  := TWaitress.Create(DinerMenu);
24  Waitress.PrintMenu;
25
26  FreeAndNil(DinerMenu);
27  FreeAndNil(Waitress);
28  Readln;
29end.

运行结果:

特别感谢:在实现上面示例时,遇到动态数组做参数的问题。感谢盒子论坛里的ZuoBaoQuan兄出手相助!

 
 

Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---迭代器模式之DinerMenu[转]的更多相关文章

  1. .NET设计模式(18):迭代器模式(Iterator Pattern)(转)

    概述 在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据. ...

  2. 设计模式之第6章-迭代器模式(Java实现)

    设计模式之第6章-迭代器模式(Java实现) “我已经过时了,就不要讲了吧,现在java自带有迭代器,还有什么好讲的呢?”“虽然已经有了,但是具体细节呢?知道实现机理岂不美哉?”“好吧好吧.”(迭代器 ...

  3. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---工厂模式之简单工厂

    简单工厂:工厂依据传进的参数创建相应的产品. http://www.cnblogs.com/DelphiDesignPatterns/archive/2009/07/24/1530536.html { ...

  4. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---模板方法模式之CoffeineBeverageWithHook[转]

    模板方法模式定义了一个算法骨架,允许子类对算法的某个或某些步骤进行重写(override).   1   2{<HeadFirst设计模式>之模板方法模式 }   3{ 编译工具: Del ...

  5. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---策略模式之MiniDuckSimulator[转]

     1  2{<HeadFirst设计模式>之策略模式 }  3{ 本单元中的类为策略类           }  4{ 编译工具: Delphi7.0           }  5{ E- ...

  6. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---命令模式之RemoteControlTest[转]

      1   2{<HeadFirst设计模式>之命令模式 }   3{ 本单元中的类为命令的接收者      }   4{ 编译工具 :Delphi7.0         }   5{ 联 ...

  7. 【java设计模式】(6)---迭代器模式(案例解析)

    设计模式之迭代器模式 一.java迭代器介绍 1.迭代器接口 在jdk中,与迭代器相关的接口有两个:Iterator 与 Iterable. Iterator:迭代器,Iterator及其子类通常是迭 ...

  8. 《JavaScript设计模式与开发实践》-- 迭代器模式

    详情个人博客:https://shengchangwei.github.io/js-shejimoshi-diedaiqi/ 迭代器模式 1.定义 迭代器模式: 是指提供一种方法顺序访问一个聚合对象中 ...

  9. C#设计模式学习笔记:(15)迭代器模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7903617.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第三个模式--迭 ...

随机推荐

  1. [JZOJ 5788] 餐馆

    思路: 考虑树形dp. 我们设\(dp[i][j][0/1]\)表示在\(i\)为根的子树中花费\(j\)单位时间,最终回到/不必回到\(i\)的最大收益. 转移三种: \(dp[x][j][0] = ...

  2. vue.js+web storm安装及第一个vue.js

    小白还是自己写一遍吧 1.下载node.js https://nodejs.org/en/download/ 2.安装淘宝镜像(类似于阿里云的maven中央仓库镜像) 安装时间有点长 安装命令:npm ...

  3. redis服务后台运行

    文章目录 进入redis的安装目录 查看目录结构 进入src目录,普通启动效果 编辑redis服务目录下的redis.conf 进入src目录,执行后台运行的命令 检查服务是否开启 进入redis的安 ...

  4. idae for mac部分背景色修改收集

    文章目录 所有字体默认颜色 终端背景色 行数line number背景色 line number颜色 编码区背景色 光标所在行背景色 未被使用的变量.方法或者类 控制台相关 选中文字的背景色 选中和未 ...

  5. Android基础知识—Context理解及使用

    Context是Android中一个非常重要的概念,用于访问全局信息,几乎所有的基础组件都继承自 Context,理解 Context 对于学习 Android 四大基本组件非常有帮助. 1. Con ...

  6. 17.splash_case06_ScrapySplashTest-master

    taobao.py # -*- coding: utf-8 -*- from scrapy import Spider, Request from urllib.parse import quote ...

  7. 关于tomcat配置了虚拟路径,但是在Idea中无法生效的问题

    1. 确认 tomcat 的server.xml 文件中配置的虚拟路径是否正确 其中,path表示访问的虚拟路径,docBase表示真实路径 2. Idea 服务器配置中是否勾选 “Deploy ap ...

  8. JavaScript特效源码(7、页面特效二)

    7.将站点加入频道栏 将站点加入频道栏[看详细说明] ====1.加入channel的方法:使用如下连接指向你的频道文件*.cdf. <a href="javascript:windo ...

  9. SDOI2018Round1 && 九省联考 爆炸记

    Day 0 做了一上午火车,大概中午十二点左右到了烟台核电培训中心宾馆,宾馆蛮不错的,跟我在北京参加英才论坛时住的宾馆舒适程度上差不多. 下午花式颓颓颓,吃了晚饭(体验一般)去试机,听说用Lemon评 ...

  10. Python全栈开发:socket代码实例

    客户端与服务端交互的基本流程 服务端server #!/usr/bin/env python # -*- coding;utf-8 -*- import socket sk = socket.sock ...