深入浅出设计模式-011:组合模式(Composite Pattern)

    技术2025-01-14  10

    深入浅出设计模式-011:组合模式(Composite Pattern)

    一:针对迭代器模式,当添加新菜单时不方便    class Waitress{        Menu pancakeHouseMenu;        Menu dinnerMenu;

            public Waitress(Menu pancakeHouseMenu, Menu dinnerMenu){            this.pancakeHouseMenu = pancakeHouseMenu;            this.dinnerMenu = dinnerMenu;        }

            public string PrintMenu(){            StringBuilder sb = new StringBuilder();

                Iterator pancakeIterator = pancakeHouseMenu.createIterator();            Iterator dinnerIterator = dinnerMenu.createIterator();

                //不符合接口封闭原则            sb.Append("MENU/n----/nBREAKFAST/n");            sb.Append(PrintMenu(pancakeIterator));            sb.Append("/nLUNCH/n");            sb.Append(PrintMenu(dinnerIterator));

                return sb.ToString();        }

            public string PrintMenu(Iterator iterator){            StringBuilder sb = new StringBuilder();            while (iterator.hasNext()){                MenuItem menuItem = (MenuItem)iterator.next();

                    sb.Append(menuItem.getName + ", ");                sb.Append(menuItem.getPrice + " -- ");                sb.Append(menuItem.getDescription + "/n");            }            return sb.ToString();        }    }

        static void Main(string[] args){        PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();        DinerMenu dinerMenu = new DinerMenu();        CafeMenu cafeMenu = new CafeMenu();

            Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu, cafeMenu);        Console.WriteLine(waitress.PrintMenu());    }

    二:组合模式:允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象及对象组合。    为了保持透明性,组合内所有的对象必须实现相同的接口,否则客户就必须操心哪个对象调用哪个接口,这就失去了组合模式的意图。这也意味着有些对象具备一些没有意义的方法调用。    //菜单项不用分什么,作为统一的叶子节点    //需要维护菜单列表,列表项及菜单项

        //将菜单和菜的选项全部放进来    public abstract class MenuComponent{  string name;  string description;  bool vegetarian;  double price;  public virtual string Name{   get {return name;}   set {name = value;}  }  public virtual string Description{   get { return description; }   set { description = value; }  }  public virtual bool IsVegetarian{   get { return vegetarian; }   set { vegetarian = value; }  }  public virtual double Price{   get { return price; }   set { price = value; }  }  public virtual void Add(MenuComponent menuComponent){   throw new UnsupportedOperationException();  }  public virtual void Remove(MenuComponent menuComponent){   throw new UnsupportedOperationException();  }  public virtual MenuComponent GetChild(int i) {   throw new UnsupportedOperationException();  }  public virtual string Print(){   throw new UnsupportedOperationException();  }  public virtual ArrayList GetMenu(){   throw new UnsupportedOperationException();  }  public virtual int Count(){   throw new UnsupportedOperationException();  } }

     public class MenuItem : MenuComponent{  string name;  string description;  bool vegetarian;  double price;

      public MenuItem(string name, string description, bool vegetarian, double price){   this.name = name;   this.description = description;   this.vegetarian = vegetarian;   this.price = price;  }  public override string Name{   get {return name;}   set {this.name = value;}  }  public override string Description{   get{return description;}   set{this.description = value;}  }  public override double Price{   get{return price;}   set{price = value;}  }  public override bool IsVegetarian{   get{return vegetarian;}   set{this.vegetarian = value;}  }  public override string Print(){   StringBuilder printOutPut = new StringBuilder();   printOutPut.Append("/t" + Name);   if(IsVegetarian){    printOutPut.Append(" (v) ");   }   printOutPut.Append(", $" + Price + "/n");   printOutPut.Append("/t/t--" + Description +"/n");

       return printOutPut.ToString();  } }

     public class Menu : MenuComponent{        //关键  ArrayList menuComponents = new ArrayList();  string name;  string description;

      public Menu(string name, string description){   this.name = name;   this.description = description;  }  public override string Name{   get {return name;}   set {this.name = value;}  }  public override string Description{   get{return description;}   set{this.description = value;}  }        //菜单中可以增加菜单项,但也可以增加菜单,所以要同一个父节点  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 (MenuComponent)menuComponents[i];  }  public override ArrayList GetMenu(){   return menuComponents;  }  public override int Count(){   return menuComponents.Count;  }  public override string Print(){   StringBuilder printOutPut = new StringBuilder();   printOutPut.Append("/n" + name);   printOutPut.Append(", " + description + "/n");   printOutPut.Append("-------------------------/n");      foreach(MenuComponent menuComponent in menuComponents){    printOutPut.Append(menuComponent.Print());   }

       return printOutPut.ToString();  } }

     public class Waitress{  MenuComponent allMenus;  public Waitress(MenuComponent allMenus){   this.allMenus = allMenus;  }  public string PrintMenu(){   return allMenus.Print();  }  public string PrintVegetarianMenu(){   StringBuilder printOutPut = new StringBuilder();   printOutPut.Append("/nVEGETARIAN MENU/n");   printOutPut.Append("-------------------------/n");   printOutPut.Append(GetChildMenuOutPutDown2Levels(allMenus.GetMenu()));   return printOutPut.ToString();  }  private string GetChildMenuOutPutDown2Levels(ArrayList menus){   StringBuilder printChildMenuOutPut = new StringBuilder();

       foreach(MenuComponent menuComponent in menus){    for(int i = 0; i < menuComponent.Count(); i++){     if(menuComponent.GetChild(i).IsVegetarian){      printChildMenuOutPut.Append(menuComponent.GetChild(i).Print());     }

         if(menuComponent.GetChild(i).GetType().Name == "Menu"){      for(int j = 0; j < menuComponent.GetChild(i).Count(); j++){       printChildMenuOutPut.Append(menuComponent.GetChild(i).GetChild(j).Print());      }     }    }   }   return printChildMenuOutPut.ToString();  } }    //这样加菜单就非常方便了,    static void Main(string[] args){  MenuComponent pancakeHouseMenu;        pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU","Breakfast");     pancakeHouseMenu.Add(new MenuItem("1", "1", true, 2.99));

      MenuComponent dinnerMenu;  dinnerMenu = new Menu("DINNER MENU","Lunch");        dinnerMenu.Add(new MenuItem("2", "2", true, 2.99));

      MenuComponent allMenus;        allMenus.Add(pancakeHouseMenu);        allMenus.Add(dinnerMenu);

      Waitress waitress;        waitress = new Waitress(allMenus);        waitress.PrintMenu();    }    //菜单中可以增加菜单项,但也可以增加菜单,所以要同一个父节点    public class MenuItem : MenuComponent    public class Menu : MenuComponent

    三:表明上看起来,上面MenuComponent多余    public class MenuItem{        string name;        string description;        bool vegetarian;        double price;

            public MenuItem(string name, string description, bool vegetarian, double price){            this.name = name;            this.description = description;            this.vegetarian = vegetarian;            this.price = price;        }        public string Name{            get { return name; }            set { this.name = value; }        }        public string Description{            get { return description; }            set { this.description = value; }        }        public double Price{            get { return price; }            set { price = value; }        }        public bool IsVegetarian{            get { return vegetarian; }            set { this.vegetarian = value; }        }    }    public class Menu{        ArrayList menuComponents = new ArrayList();        string name;        string description;

            public Menu(string name, string description){            this.name = name;            this.description = description;        }        public string Name{            get { return name; }            set { this.name = value; }        }        public string Description{            get { return description; }            set { this.description = value; }        }

            public void Add(MenuItem menuComponent){            menuComponents.Add(menuComponent);        }

            public void Remove(MenuItem menuComponent){            menuComponents.Remove(menuComponent);        }

            public MenuItem GetChild(int i){            return (MenuItem)menuComponents[i];        }

            public ArrayList GetMenu(){            return menuComponents;        }        public int Count(){            return menuComponents.Count;        }    }    class Waitress{        Menu allMenus;        public Waitress(Menu allMenus){            this.allMenus = allMenus;        }    }    static void Main(string[] args)    {        Menu pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU", "Breakfast");        pancakeHouseMenu.Add(new MenuItem("1", "1", true, 2.99));

            Menu dinnerMenu = new Menu("DINNER MENU", "Lunch");        dinnerMenu.Add(new MenuItem("2", "2", true, 2.99));

            Menu allMenus;        //如下代码,就通不过        //菜单作为节点,包含了很多菜单项        //但同时,菜单之间也可以作为父子节点,        //所以才存在public class Menu : MenuComponent        allMenus.Add(pancakeHouseMenu);        allMenus.Add(dinnerMenu);

            Waitress waitress;        waitress = new Waitress(allMenus);    }

    最新回复(0)