标签:des blog http io ar os sp div on
容器的主要职责有两个:存放元素和浏览元素。根据单一职责原则(SRP)要将二者分开,于是将浏览功能打包封装就有了迭代器。
用迭代器封装对动态数组的遍历:

{《HeadFirst设计模式》之迭代器模式 }
{ 容器中的元素类 }
{ 编译工具:Delphi7.0 }
{ E-Mail :guzh-0417@163.com }
unit uItem;
interface
type
TMenuItem = class(TObject)
private
FName: String;
FDescription: String;
FVegetarian : Boolean;
FPrice: Double;
public
constructor Create(aName, aDescription: String;
aVegetarian : Boolean;
aPrice: Double);
function GetName: String;
function GetDescription: String;
function GetPrice: Double;
function IsVegetarian: Boolean;
end;
implementation
{ TMenuItem }
constructor TMenuItem.Create(aName, aDescription: String;
aVegetarian: Boolean;
aPrice: Double);
begin
FName := aName;
FDescription := aDescription;
FVegetarian := aVegetarian;
FPrice := aPrice;
end;
function TMenuItem.GetDescription: String;
begin
Result := FDescription;
end;
function TMenuItem.GetName: String;
begin
Result := FName;
end;
function TMenuItem.GetPrice: Double;
begin
Result := FPrice;
end;
function TMenuItem.IsVegetarian: Boolean;
begin
Result := FVegetarian;
end;
end.

{《HeadFirst设计模式》之迭代器模式 }
{ 迭代器:封装对容器的遍历 }
{ 编译工具:Delphi7.0 }
{ E-Mail :guzh-0417@163.com }
unit uIterator;
interface
uses
uItem;
type
TMenuItems = array of TMenuItem;
TIterator = class(TObject)
public
function HasNext: Boolean; virtual; abstract;
function Next : TObject; virtual; abstract;
end;
TDinerMenuIterator = class(TIterator)
private
FMenuItem : TMenuItem;
FMenuItems: TMenuItems;
FPosition : Integer;
public
constructor Create(MenuItems: TMenuItems);
function HasNext: Boolean; override;
function Next : TObject; override;
end;
implementation
{ TDinerMenuIterator }
constructor TDinerMenuIterator.Create(MenuItems: TMenuItems);
begin
FMenuItems := MenuItems;
end;
function TDinerMenuIterator.HasNext: Boolean;
begin
if (FPosition < Length(FMenuItems)) and (FMenuItems[FPosition] <> nil) then
Result := True
else
Result := False;
end;
function TDinerMenuIterator.Next: TObject;
begin
FMenuItem := FMenuItems[FPosition];
FPosition := FPosition + 1 ;
Result := FMenuItem;
end;
end.

{《HeadFirst设计模式》之迭代器模式 }
{ 容器类及其用户: Waitress }
{ 编译工具:Delphi7.0 }
{ E-Mail :guzh-0417@163.com } 
unit uAggregate;
interface
uses
SysUtils, uItem, uIterator;
type
TMenu = class(TObject)
public
function CreateIterator: TIterator; virtual; abstract;
end;
TDinerMenu = class(TMenu)
private
FMenuItem : TMenuItem;
FMenuItems: TMenuItems;
FNumberOfItems: Integer;
public
constructor Create;
destructor Destroy; override;
procedure AddItem(aName, aDescription: String; aVegetarian: Boolean;
aPrice: Double);
function CreateIterator: TIterator; override;
end;
TWaitress = class(TObject)
private
FMenuItem : TMenuItem;
FDinerMenu: TDinerMenu;
DinerIterator: TIterator;
public
constructor Create(aDinerMenu: TDinerMenu);
procedure PrintMenu; overload;
procedure PrintMenu(aIterator: TIterator); overload;
end;
implementation
const
MAX_TIMES = 6;
{ TDinerMenu }
procedure TDinerMenu.AddItem(aName, aDescription: String; aVegetarian: Boolean;
aPrice: Double);
begin
FMenuItem := TMenuItem.Create(aName, aDescription, aVegetarian, aPrice);
if FNumberOfItems >= MAX_TIMES then
Writeln(‘Sorry, menu is full! Can‘‘t add item to menu‘)
else
begin
FMenuItems[FNumberOfItems] := FMenuItem;
FNumberOfItems := FNumberOfItems + 1;
end;
end;
constructor TDinerMenu.Create;
begin
SetLength(FMenuItems, MAX_TIMES);
AddItem(‘Vegetarian BLT‘,
‘Fakin Bacon with lettuce & tomato on whole Wheat‘, True, 2.99);
AddItem(‘BLT‘,
‘Bacon with lettuce & tomato on whole Wheat‘, False, 2.99);
AddItem(‘Soup of the day‘,
‘Soup of the day, with a side of potato salad‘, False, 3.29);
AddItem(‘Hotdog‘,
‘A hot dog, with saurkraut, relish, onions, topped with cheese‘,
False, 3.05);
AddItem(‘Steamed Veggies and Brown Rice‘,
‘Steamed vegetables over brown rice‘, True, 3.99);
AddItem(‘Pasta‘,
‘Spaghetti with Marinara Sauce, and a slice of sourdough bread‘, True,
3.89);
end;
destructor TDinerMenu.Destroy;
begin
FreeAndNil(FMenuItem);
inherited;
end;
function TDinerMenu.CreateIterator: TIterator;
begin
Result := TDinerMenuIterator.Create(FMenuItems);
end;
{ TWaitress }
constructor TWaitress.Create(aDinerMenu: TDinerMenu);
begin
FDinerMenu := aDinerMenu;
end;
procedure TWaitress.PrintMenu;
begin
try
DinerIterator := FDinerMenu.CreateIterator;
Writeln(‘MENU‘);
Writeln(‘----‘);
Writeln(‘BREAKFAST‘);
Writeln;
PrintMenu(DinerIterator);
finally
FreeAndNil(DinerIterator);
end;
end;
procedure TWaitress.PrintMenu(aIterator: TIterator);
begin
while (aIterator.HasNext) do
begin
FMenuItem := (aIterator.Next) as TMenuItem;
Writeln(FMenuItem.GetName + ‘,‘);
Writeln(FMenuItem.GetPrice, ‘ -- ‘);
Writeln(FMenuItem.GetDescription);
end;
end;
end.

{《HeadFirst设计模式》之迭代器模式 }
{ 客户端 }
{ 编译工具:Delphi7.0 }
{ E-Mail :guzh-0417@163.com }
program pMenuTestDrive;
{$APPTYPE CONSOLE}
uses
SysUtils,
uItem in ‘uItem.pas‘,
uAggregate in ‘uAggregate.pas‘,
uIterator in ‘uIterator.pas‘;
var
DinerMenu: TDinerMenu;
Waitress : TWaitress;
begin
DinerMenu := TDinerMenu.Create;
Waitress := TWaitress.Create(DinerMenu);
Waitress.PrintMenu;
FreeAndNil(DinerMenu);
FreeAndNil(Waitress);
Readln;
end.
运行结果:

特别感谢:在实现上面示例时,遇到动态数组做参数的问题。感谢盒子论坛里的ZuoBaoQuan兄出手相助!
Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---迭代器模式之DinerMenu[转]
标签:des blog http io ar os sp div on
原文地址:http://www.cnblogs.com/0x2D-0x22/p/4076316.html