容器的主要职责有两个:存放元素和浏览元素。根据单一职责原则(SRP)要将二者分开,于是将浏览功能打包封装就有了迭代器。
用迭代器封装对动态数组的遍历:
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
1![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
{《HeadFirst设计模式》之迭代器模式 }
3
{ 容器中的元素类 }
4
{ 编译工具:Delphi7.0 }
5
{ E-Mail :guzh-0417@163.com }
6![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
7
unit uItem;
8![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
9
interface
10![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
11
type
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![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
28
implementation
29![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
30
{ TMenuItem }
31![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
32
constructor TMenuItem.Create(aName, aDescription: String;
33
aVegetarian: Boolean;
34
aPrice: Double);
35
begin
36
FName := aName;
37
FDescription := aDescription;
38
FVegetarian := aVegetarian;
39
FPrice := aPrice;
40
end;
41![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
42
function TMenuItem.GetDescription: String;
43
begin
44
Result := FDescription;
45
end;
46![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
47
function TMenuItem.GetName: String;
48
begin
49
Result := FName;
50
end;
51![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
52
function TMenuItem.GetPrice: Double;
53
begin
54
Result := FPrice;
55
end;
56![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
57
function TMenuItem.IsVegetarian: Boolean;
58
begin
59
Result := FVegetarian;
60
end;
61![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
62
end.
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
1![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
{《HeadFirst设计模式》之迭代器模式 }
3
{ 迭代器:封装对容器的遍历 }
4
{ 编译工具:Delphi7.0 }
5
{ E-Mail :guzh-0417@163.com }
6![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
7
unit uIterator;
8![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
9
interface
10![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
11
uses
12
uItem;
13![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
14
type
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![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
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![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
34
implementation
35![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
36
{ TDinerMenuIterator }
37![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
38
constructor TDinerMenuIterator.Create(MenuItems: TMenuItems);
39
begin
40
FMenuItems := MenuItems;
41
end;
42![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
43
function TDinerMenuIterator.HasNext: Boolean;
44
begin
45
if (FPosition < Length(FMenuItems)) and (FMenuItems[FPosition] <> nil) then
46
Result := True
47
else
48
Result := False;
49
end;
50![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
51
function TDinerMenuIterator.Next: TObject;
52
begin
53
FMenuItem := FMenuItems[FPosition];
54
FPosition := FPosition + 1 ;
55
Result := FMenuItem;
56
end;
57![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
58
end.
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
1![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
{《HeadFirst设计模式》之迭代器模式 }
3
{ 容器类及其用户: Waitress }
4
{ 编译工具:Delphi7.0 }
5
{ E-Mail :guzh-0417@163.com }
6![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
7
unit uAggregate;
8![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
9
interface
10![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
11
uses
12
SysUtils, uItem, uIterator;
13![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
14
type
15
TMenu = class(TObject)
16
public
17
function CreateIterator: TIterator; virtual; abstract;
18
end;
19![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
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![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
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
44
implementation
45![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
46
const
47
MAX_TIMES = 6;
48![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
49
{ TDinerMenu }
50![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
51
procedure TDinerMenu.AddItem(aName, aDescription: String; aVegetarian: Boolean;
52
aPrice: Double);
53
begin
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;
62
end;
63![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
64
constructor TDinerMenu.Create;
65
begin
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);
82
end;
83![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
84
destructor TDinerMenu.Destroy;
85
begin
86
FreeAndNil(FMenuItem);
87
inherited;
88
end;
89![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
90
function TDinerMenu.CreateIterator: TIterator;
91
begin
92
Result := TDinerMenuIterator.Create(FMenuItems);
93
end;
94![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
95
{ TWaitress }
96![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
97
constructor TWaitress.Create(aDinerMenu: TDinerMenu);
98
begin
99
FDinerMenu := aDinerMenu;
100
end;
101![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
102
procedure TWaitress.PrintMenu;
103
begin
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;
114
end;
115![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
116
procedure TWaitress.PrintMenu(aIterator: TIterator);
117
begin
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;
125
end;
126![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
127
end.
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
1![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
{《HeadFirst设计模式》之迭代器模式 }
3
{ 客户端 }
4
{ 编译工具:Delphi7.0 }
5
{ E-Mail :guzh-0417@163.com }
6![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
7
program pMenuTestDrive;
8![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
9
{$APPTYPE CONSOLE}
10![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
11
uses
12
SysUtils,
13
uItem in 'uItem.pas',
14
uAggregate in 'uAggregate.pas',
15
uIterator in 'uIterator.pas';
16![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
17
var
18
DinerMenu: TDinerMenu;
19
Waitress : TWaitress;
20![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
21
begin
22
DinerMenu := TDinerMenu.Create;
23
Waitress := TWaitress.Create(DinerMenu);
24
Waitress.PrintMenu;
25![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
26
FreeAndNil(DinerMenu);
27
FreeAndNil(Waitress);
28
Readln;
29
end.
运行结果:
![](https://images.cnblogs.com/cnblogs_com/delphidesignpatterns/picDinerMenuIterator.JPG)
特别感谢:在实现上面示例时,遇到动态数组做参数的问题。感谢盒子论坛里的ZuoBaoQuan兄出手相助!