設計模式
定義:物件以樹狀結構組合,做為表現出整體-部分的階層關係。
目的:用樹狀階層的方式來管理物件節點。
Component:節點介面,定義每個節點操作方法。
Composite:組合節點,衍生自Component,可包含其他節點。
Leaf:末端節點,衍生自Component,但不包含其他節點。
精神:物件樹。
優點:分層管理。
缺點:需要用其他的方法來分辨節點真正的類型。
使用時機:當物件很多,需要階層管理的時候或是出現出合成物件的樹狀結構,就可以使用。
舉例:早餐店的火腿起司蛋吐司,每個火腿起司蛋吐司有火腿、起司、煎蛋、沙拉、吐司,
這些都算是材料,透過這些材料組合成火腿起司蛋吐司。
class Program
{
private static void Main(string[] args)
{
Composite root = new Composite("root");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf B"));
Composite comp = new Composite("Composite X");
comp.Add(new Leaf("Leaf XA"));
comp.Add(new Leaf("Leaf XB"));
root.Add(comp);
root.Add(new Leaf("Leaf C"));
Leaf leaf = new Leaf("Leaf D");
root.Add(leaf);
root.Remove(leaf);
root.Display(1);
Console.ReadKey();
}
}
abstract class Component
{
protected string _name;
protected Component(string name)
{
_name = name;
}
public abstract void Add(Component c);
public abstract void Remove(Component c);
public abstract void Display(int depth);
}
class Composite : Component
{
private List<Component> children = new List<Component>();
public Composite(string name) : base(name)
{
}
public override void Add(Component c)
{
children.Add(c);
}
public override void Remove(Component c)
{
children.Remove(c);
}
public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + _name);
foreach (Component component in children)
{
component.Display(depth + 2);
}
}
}
class Leaf : Component
{
public Leaf(string name) : base(name)
{
}
public override void Add(Component c)
{
Console.WriteLine("Cannot add to a leaf");
}
public override void Remove(Component c)
{
Console.WriteLine("Cannot remove from a leaf");
}
public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + _name);
}
}
來個中式餐點菜單案例,我麵有牛肉麵與乾麵、飯有咖哩飯、滷肉飯,這時候我就可以用組合模式如下:
class Program
{
private static void Main(string[] args)
{
Composite hostMenu = new Composite("主菜單");
Composite noodlesMenu = new Composite("麵類");
noodlesMenu.Add(new LeafNoodles("牛肉麵"));
noodlesMenu.Add(new LeafNoodles("乾麵"));
hostMenu.Add(noodlesMenu);
Composite riceMenu = new Composite("飯類");
riceMenu.Add(new LeafRice("滷肉飯"));
riceMenu.Add(new LeafRice("咖哩飯"));
hostMenu.Add(riceMenu);
hostMenu.Display(0);
}
}
abstract class MenuComponent
{
protected string _name;
protected MenuComponent(string name)
{
_name = name;
}
public abstract void Add(MenuComponent c);
public abstract void Remove(MenuComponent c);
public abstract void Display(int depth);
}
class Composite : MenuComponent
{
private List<MenuComponent> children = new List<MenuComponent>();
public Composite(string name) : base(name)
{
}
public override void Add(MenuComponent c)
{
children.Add(c);
}
public override void Remove(MenuComponent c)
{
children.Remove(c);
}
public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + _name);
foreach (MenuComponent component in children)
{
component.Display(depth + 2);
}
}
}
class LeafNoodles : MenuComponent
{
public LeafNoodles(string name) : base(name)
{
}
public override void Add(MenuComponent c)
{
}
public override void Remove(MenuComponent c)
{
}
public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + _name);
}
}
class LeafRice : MenuComponent
{
public LeafRice(string name) : base(name)
{
}
public override void Add(MenuComponent c)
{
}
public override void Remove(MenuComponent c)
{
}
public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + _name);
}
}
元哥的筆記