• Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---迭代器模式之DinerMenu[转]


         容器的主要职责有两个:存放元素和浏览元素。根据单一职责原则(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兄出手相助!

     
     
  • 相关阅读:
    ch_6802 車的放置
    ch_POJ2182 Lost Cows
    ch_4201 楼兰图腾
    luogu_P3368【模板】树状数组 2
    门面
    建造者
    模板方法
    状态
    抽象工厂
    工厂方法
  • 原文地址:https://www.cnblogs.com/0x2D-0x22/p/4076316.html
Copyright © 2020-2023  润新知