设计模式C#实现(十一)——组合模式

 

 

意图

将对象组合成树形结构以表示“部分-整体”的层次结构。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();
        }
    }

运行结果
运行结果

效果

  • 定义了包含基本对象(不含子节点)和组合对象(含有子节点)的类层次结构
  • 简化客户代码 客户不要关心使用的是组合对象和基本对象,因为使用方法是一致的
  • 容易增加新组件
  • 使设计跟加一般化
posted @ 2015-12-05 16:38  妖刀Dreamcast  阅读(...)  评论(... 编辑 收藏