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兄出手相助!
Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---迭代器模式之DinerMenu[转]的更多相关文章
- .NET设计模式(18):迭代器模式(Iterator Pattern)(转)
概述 在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据. ...
- 设计模式之第6章-迭代器模式(Java实现)
设计模式之第6章-迭代器模式(Java实现) “我已经过时了,就不要讲了吧,现在java自带有迭代器,还有什么好讲的呢?”“虽然已经有了,但是具体细节呢?知道实现机理岂不美哉?”“好吧好吧.”(迭代器 ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---工厂模式之简单工厂
简单工厂:工厂依据传进的参数创建相应的产品. http://www.cnblogs.com/DelphiDesignPatterns/archive/2009/07/24/1530536.html { ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---模板方法模式之CoffeineBeverageWithHook[转]
模板方法模式定义了一个算法骨架,允许子类对算法的某个或某些步骤进行重写(override). 1 2{<HeadFirst设计模式>之模板方法模式 } 3{ 编译工具: Del ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---策略模式之MiniDuckSimulator[转]
1 2{<HeadFirst设计模式>之策略模式 } 3{ 本单元中的类为策略类 } 4{ 编译工具: Delphi7.0 } 5{ E- ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---命令模式之RemoteControlTest[转]
1 2{<HeadFirst设计模式>之命令模式 } 3{ 本单元中的类为命令的接收者 } 4{ 编译工具 :Delphi7.0 } 5{ 联 ...
- 【java设计模式】(6)---迭代器模式(案例解析)
设计模式之迭代器模式 一.java迭代器介绍 1.迭代器接口 在jdk中,与迭代器相关的接口有两个:Iterator 与 Iterable. Iterator:迭代器,Iterator及其子类通常是迭 ...
- 《JavaScript设计模式与开发实践》-- 迭代器模式
详情个人博客:https://shengchangwei.github.io/js-shejimoshi-diedaiqi/ 迭代器模式 1.定义 迭代器模式: 是指提供一种方法顺序访问一个聚合对象中 ...
- C#设计模式学习笔记:(15)迭代器模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7903617.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第三个模式--迭 ...
随机推荐
- duilib教程之duilib入门简明教程17.事件处理和消息响应
界面的显示方面就都讲完啦,下面来介绍下控件的响应. 前面的教程只讲了按钮和Tab的响应,即在Notify函数里处理.其实duilib还提供了另外一种响应的方法,即消息映射DUI_BEGIN_ME ...
- spring中使用RabbitMQ
常见的消息中间件产品: (1)ActiveMQ ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS P ...
- redis 本地连接可以 远程连接不上问题
1.所连主机防火墙关一下. 1:查看防火状态 systemctl status firewalld service status iptables 2:暂时关闭防火墙 systemctl stop ...
- ArrayList 扩容
处理容量是0, 第一次add的时候扩充到10 int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容50% 变成 1.5倍 第二 ...
- truncate和delete的区别
TRUNCATE 命令用法 语法 TRUNCATE TABLE name 参数 name 是要截断的表的名称或要删除其全部行的表的名称. 注释 TRUNCATE TABLE 在功能上与不带 W ...
- joda 获取每个月第一天第一秒和最后一天最后一秒
/** * 获取每个月第一天的第一秒 * @return */ public static final Date getMouthOfFirst(){ DateTimeFormatter format ...
- 第二十二篇:Spring简单定时任务
背景:有些操作,不适合放在页面上让用户手动触发去执行,比如一些需要不断更新的数据(如统计数据)有些需要同步的数据,不需要非常实时,可以在固定的时间或者固定的频率执行同步 第一步:配置xml第二步:编写 ...
- [CF587-F]WI-FI
显然DP题... f[i][0]表示这个点不装路由器,f[i][1]表示装路由器 转移也很简单,在前面一段区间找最小值就好了 但是直接转移是$O(n*k)$的,会T掉 大佬说这个东西有单调性,但是菜鸡 ...
- Apache下更改.htaccess文件名称
有时候我们需要更改.htaccess的名称以解决一些问题 比如:Eclipse下是不显示点开头的文件的 所以我们可以使用 Apache的AccessFileName来更改此配置文件的名称 Acces ...
- vue中使用动画vue-particles实现背景粒子酷炫效果
先来看我做的效果 我这个是用的背景色加上这个粒子效果实现的demo 平时我们做项目的话会添加背景图片这些,可能更加好看 看我的实现步骤 cnpm install -g vue-cli vue init ...