意图
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
适用性
- 你想表示对象的部分-整体层次结构
- 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
结构
实现
我们实现一个菜单结构,一个菜单可以包含子菜单或者菜单项
定义一个抽象类,菜单和菜单项都继承自这个类
public abstract class MenuComponet { public virtual void Add(MenuComponet menuComponet) { throw new Exception("不支持该方法"); } public virtual void Remove(MenuComponet menuComponet) { throw new Exception("不支持该方法"); } public virtual MenuComponet GetChild(int i) { throw new Exception("不支持该方法"); } public virtual void Print() { throw new Exception("不支持该方法"); } }
菜单包含一个子节点列表
public class Menu : MenuComponet { List<MenuComponet> _componets = new List<MenuComponet>(); private string _name; public Menu(string name) { _name = name; } public override void Add(MenuComponet menuComponet) { _componets.Add(menuComponet); } public override void Remove(MenuComponet menuComponet) { _componets.Remove(menuComponet); } public override MenuComponet GetChild(int i) { return _componets[i]; } public override void Print() { Console.WriteLine(_name+":"); foreach (var c in _componets) { Console.Write("--"); c.Print(); } } }
菜单项
public class MenuItem : MenuComponet { private string _name; private float _price; public MenuItem(string name, float price) { _name = name; _price = price; } public override void Print() { Console.WriteLine("--"+_name + ": " + _price + "$"); } }
客户使用
class Program { static void Main(string[] args) { MenuComponet allMenus = new Menu("Menu"); MenuComponet breakfast = new Menu("breakfast"); MenuComponet lunch = new Menu("lunch"); MenuComponet dinner = new Menu("dinner"); breakfast.Add(new MenuItem("Milk", 1.5f)); breakfast.Add(new MenuItem("Egg", .5f)); lunch.Add(new MenuItem("Hamburger", 3f)); lunch.Add(new MenuItem("Sausage", 3f)); lunch.Add(new MenuItem("French fries", 2f)); MenuComponet food = new Menu("Food"); MenuComponet drink = new Menu("Drink"); food.Add(new MenuItem("Steak", 6f)); food.Add(new MenuItem("Salad", 3f)); food.Add(new MenuItem("Hamburger", 3f)); drink.Add(new MenuItem("Beer", 1f)); drink.Add(new MenuItem("Wine", 3f)); dinner.Add(food); dinner.Add(drink); allMenus.Add(breakfast); allMenus.Add(lunch); allMenus.Add(dinner); allMenus.Print(); Console.WriteLine("\n I wanna a beer"); allMenus.GetChild(2).GetChild(1).GetChild(0).Print(); Console.ReadKey(); } }
运行结果
效果
- 定义了包含基本对象(不含子节点)和组合对象(含有子节点)的类层次结构
- 简化客户代码 客户不要关心使用的是组合对象和基本对象,因为使用方法是一致的
- 容易增加新组件
- 使设计跟加一般化
原标题:设计模式C#实现(十一)——组合模式
关键词:C#