忙しい最近、デザインパターンの進捗状況を更新する時間がありませんでした。今日はデザインパターンの組み合わせを学ぶことを続けています。
メニュー例「ヘッドファーストデザインパターンのIteratorモード」、最初のイテレータと複合モードの問題、彼らは2つの異なるモードですしないで - 複合モードの例としては、我々は、パートIを拡張し続けています。しかし、このメニューでは、当社の内部ポートフォリオ・モデルは、イテレータの例を使用します。
イテレータモードには2軒のレストランをマージして、統一されたトリートメントメニューを印刷するイテレータを使用していますが、今、新たな需要がある元大メニューのとき、私たちは、このようなデザートとして、サブメニューに参加することを願っています。さて、今回このようなモデルの需要が、それは以下の通りです
メニューは、メニュー項目があり、メニュー項目は、サブメニューを持っていること、私たちは今メニューを印刷したいです。それは、彼らが組織され、ラショナル統一プロセスされているか、それぞれのメニューとメニュー項目を処理していますか?この問題を解決するために、モードの組み合わせは、この要求を実現しています。
コンバインモードの定義
を組み合わせモード:あなたが「全体/部分」階層を表すためにツリー構造にオブジェクトを組み合わせることができます。組み合わせは、一貫性のある方法で、顧客は個々のオブジェクトとそれらの組み合わせで対処することができます。
私たちは、メニュー項目を持つ可能性がメニューツリー構造、サブメニューとサブメニューを持っている場合は、このモードでは、ツリー構造を作成することができ、その後、任意のメニューはの一種である「組み合わせ。」それは他のメニューを含めることができるため、メニュー項目を含めることもできます。個々のメニュー項目をオブジェクトが、他のオブジェクトを保持していません。
メニューデザインの組み合わせ使用して
統一されたアプローチとメニューとメニュー項目に対処する私たちができることを、我々はメニューとメニュー項目に共通のインターフェースとしてコンポーネントのインタフェースを作成する必要があるが、他の言葉で、私たちはこの方法のために同じメニューまたはメニュー項目を呼び出すことができます。
私たちは、クラス図のメニューのデザインを描きます:
MenuComponentは:そう、共通のメニュー項目やメニューを使用して、インターフェイスを提供します。私たちは、抽象クラスを使用することができるように、我々は、いくつかのデフォルトの方法が実現します提供することができます。
MenuItem:有意義な方法(追加、削除、および休暇)でそれを覆う、メニューコンポーネントから継承されました。
メニュー:有意義な方法でそれをカバーし、MenuComponentをから継承されました。
組み合わせモードとして実装
実装メニューコンポーネント
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public abstract class MenuComponent
{
public virtual void Add(MenuComponent menuComponent) {
throw new NotSupportedException();
}
public virtual void Remove(MenuComponent menuComponent)
{
throw new NotSupportedException();
}
public virtual MenuComponent GetChild(int i)
{
throw new NotSupportedException();
}
public virtual void GetName()
{
throw new NotSupportedException();
}
public virtual string GetDescription()
{
throw new NotSupportedException();
}
public virtual double GetPrice()
{
throw new NotSupportedException();
}
public virtual bool IsVegetarian()
{
throw new NotSupportedException();
}
public virtual void Print()
{
throw new NotSupportedException();
}
}
实现菜单项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class MenuItme : MenuComponent
{
string name;
string decription;
bool vegetarian;
double price;
public MenuItme(string name, string decription, bool vegetarian, double price)
{
this.name = name;
this.decription = decription;
this.vegetarian = vegetarian;
this.price = price;
}
public override string GetName()
{
return name;
}
public override string GetDescription()
{
return decription;
}
public override double GetPrice()
{
return price;
}
public override bool IsVegetarian()
{
return vegetarian;
}
public override void Print()
{
Console.Write(" " + GetName());
if (IsVegetarian())
{
Console.Write("V" + GetName());
}
Console.WriteLine("," + GetPrice());
Console.WriteLine(" --" + GetPrice());
}
}
实现组合菜单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class Menu:MenuComponent
{
List<MenuComponent> menuComponents = new List<MenuComponent>();
string name;
string description;
public Menu(string name, string description)
{
this.name = name;
this.description = description;
}
public override void Add(MenuComponent menuComponent)
{
menuComponents.Add(menuComponent);
}
public override void Remove(MenuComponent menuComponent)
{
menuComponents.Remove(menuComponent);
}
public override MenuComponent GetChild(int i)
{
return menuComponents[i];
}
public override string GetName()
{
return name;
}
public override string GetDescription()
{
return description;
}
public override void Print()
{
Console.Write("\n" + GetName());
Console.WriteLine("," + GetDescription());
Console.WriteLine("---------------------");
foreach (var item in menuComponents)
{
item.Print();
}
}
}
这里菜单打印直接用foreach 循环打印菜单组件,如果遇到另外一个菜单对象则进入子菜单打印。此处就是使用迭代器模式,只不过我偷了个懒直接用了foreach,因为list C#已经实现了迭代器,使用foreach语法即可。《C# Foreach循环本质与枚举器》
测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MenuComponent breakfastMenu = new Menu("早餐菜单", "早餐供应");
MenuComponent dinnerMenu = new Menu("晚餐菜单", "晚餐供应");
MenuComponent dessertMenu = new Menu("甜点菜单", "晚餐甜点");
=メニューコンポーネントの新新メニューallMenus( "メニューALL"は、 "すべてのメニューをcombaind");
//メニュー追加
allMenus.Add(breakfastMenuを);
allMenus.Add(dinnerMenu);
//メニュー項目の追加
breakfastMenu.Add(新MenuItme(「パンを""新鮮なミートソース"偽、2));
dinnerMenu.Add(新新MenuItme("牛肉麺""牛肉と麺、「偽、15));
dinnerMenu.Add(dessertMenu);
dessertMenu.Add(新しいMenuItme( "竜巻の夢"、 "切断片"、偽、16));
allMenus.Print();