容器的主要职责有两个:存放元素和浏览元素。根据单一职责原则(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. fatal error U1087: cannot have : and :: dependents for same target Stop.

    转自VC错误:http://www.vcerror.com/?p=72 问题描述: 完成后编译,发现有错误  D:\WinDDK\7600.16385.1\bin\makefile.new(7117) ...

  2. OpenLayers的view与layer:控制显示内容

    view与layer都可以进行显示内容的控制.这两者负责的功能是由区别的. view即显示的地图容器,有以下几个属性: center:[经度,纬度] ,对应的设置函数为view.setCenter() ...

  3. Linux 中执行Shell 脚本的方式(三种方法)

    Shell 脚本的执行方式通常有如下三种: (1)bash script-name 或者 sh script-name:(2)path/script-name或者./script-name:(3)so ...

  4. HTML5 新模块元素兼容问题

    新增块元素默认样式 下列HTML5新模块元素在IE8.9版本浏览器中没有被定义默认样式.为解决该问题,给下列元素添加“block”显示属性. 代码: article, aside, details, ...

  5. 分享一份Java架构师学习资料,2019年最新整理!

    分享一套不错的架构师学习参考资料,免费领取的,无任何套路! 关注Java大后端公众号,在后台回复关键字:大大,即可免费领取,觉得资料不错,转发给其他朋友呗- 长按关注Java大后端公众号领取.

  6. linux xargs命令一(与find ls等命令组合)(转)

    -p 操作具有可交互性,每次执行comand都交互式提示用户选择 -i -i 选项告诉 xargs 可以使用{}代替传递过来的参数, 建议使用-I,其符合POSIX标准 -I 格式: xargs  - ...

  7. 2_2.springboot2.x配置之自动配置原理

    前言 SpringBoot 自动配置原理: 本文主要分为三大部分: SpringBoot 源码常用注解 SpringBoot 启动过程 SpringBoot 自动配置原理 1. SpringBoot ...

  8. js 实现加载百分比效果

    效果: html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

  9. 五. Arrow Function 箭头函数

    箭头函数三大好处: 1. 简明的语法 举例: 如果只有一个参数,可以不加(),多个参数用 "," 隔开 2. 隐式返回 首先说下什么是显示返回,显示返回就是 return 加上你要 ...

  10. CF148D Bag of mice (期望dp)

    传送门 # 解题思路 ​    ~~这怕是本蒟蒻第一个独立做出来的期望$dp$的题,发篇题解庆祝一下~~.首先,应该是能比较自然的想出状态设计$f[i][j][0/1]$ 表示当前还剩 $i$个白老鼠 ...