赞
踩
组合模式允许你将对象组合成树形结构来表现部分-整体层次结构。组合让客户可以统一处理个别对象和对象的组合。
分析:这个模式感觉接触的很少,不过感觉也是挺有用的,从上一篇博客中学习了有关迭代器模式的东西,总结就是在看不到内部结构的基础上对其进行遍历。
如果从遍历的角度看,假设我们有两份菜单,要对菜单中的数据进行遍历,这个时候我就可以使用迭代器模式进行考虑遍历,两份菜单对应两个迭代器,同样也有两份菜单类,由于我用了java列表的迭代器,就不用自己再次封装迭代器了,如我给出以下示例:
Menu接口,就是定义了菜单有哪些方法:
- public interface Menu {
-
- Iterator<MenuItem> createIterator();
-
- }
两个具体的菜单如下:
- public class TeaMenu implements Menu {
-
- private List<MenuItem> teaList;
-
- public TeaMenu(List<MenuItem> teaList) {
- this.teaList = teaList;
- }
-
- @Override
- public Iterator<MenuItem> createIterator() {
- return teaList.iterator();
- }
- }
-
- public class MeatMeun implements Menu {
-
- private List<MenuItem> meatList;
-
- public MeatMeun(List<MenuItem> meatList) {
- this.meatList = meatList;
- }
-
- @Override
- public Iterator<MenuItem> createIterator() {
- return meatList.iterator();
- }
- }
菜单项类如下:
- public class MenuItem {
-
- private String name;
- private double price;
- private String description;
-
- public MenuItem(String name, double price, String description) {
- this.name = name;
- this.price = price;
- this.description = description;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public double getPrice() {
- return price;
- }
-
- public void setPrice(double price) {
- this.price = price;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- @Override
- public String toString() {
- return "MenuItem{" +
- "name='" + name + '\'' +
- ", price=" + price +
- ", description='" + description + '\'' +
- '}';
- }
- }
商店类,就是为了展示菜单:
- public class Shop {
-
- private Menu teaMenu;
- private Menu meatMeun;
-
- public Shop(Menu teaMenu, Menu meatMeun) {
- this.teaMenu = teaMenu;
- this.meatMeun = meatMeun;
- }
-
- public void printMenu(){
- Iterator<MenuItem> mIterator = this.meatMeun.createIterator();
- Iterator<MenuItem> tIterator = this.teaMenu.createIterator();
- while(mIterator.hasNext()){
- MenuItem next = mIterator.next();
- System.out.println(next);
- }
- while(tIterator.hasNext()){
- MenuItem next = tIterator.next();
- System.out.println(next);
- }
- }
-
- public static void main(String[] args) {
- List<MenuItem> meatList = new ArrayList<>();
- meatList.add(new MenuItem("猪肉",10,"10块一斤"));
- meatList.add(new MenuItem("牛肉",50,"50块一斤"));
- meatList.add(new MenuItem("羊肉",60,"60块一斤"));
- Menu meatMenu = new MeatMeun(meatList);
- List<MenuItem> teaList = new ArrayList<>();
- teaList.add(new MenuItem("红豆奶茶",10,"10块一杯"));
- teaList.add(new MenuItem("珍珠奶茶",11,"11块一杯"));
- teaList.add(new MenuItem("椰果奶茶",12,"12块一杯"));
- Menu teaMenu = new MeatMeun(teaList);
- Shop shop = new Shop(teaMenu, meatMenu);
- shop.printMenu();
- }
-
- }
上述使用迭代器模式对商店里的菜单内容进行了遍历,但是会发现一个问题,就是如果商店里的肉类菜单下有子类呢,比如分为生肉和熟肉,生肉下分别是生猪肉,生牛肉,生羊肉,而茶菜单又分为奶茶和果茶,奶茶分别为红豆奶茶,珍珠奶茶,椰果奶茶,果茶分为,草莓果茶,百香果果茶,芒果果茶。
如果按照上述情况,就会出现问题,本来的,茶菜单和肉菜单无法表示这种分类关系,而且上述出现了二级菜单,对于原来的菜单也无法表示这种层级关系,所以这种菜单的设计结构将无法进行扩展,对于商店去处理的时候,代码也无法重构,而且也不应该让代码进行经常性的重构,所以这个时候我们就要考虑组合模式了。那么接下来我们看一看组合模式的类图。
从上面的类图我们要进行提炼几点内容:
在这里,我们让所有的类都继承自Component类,然后叶子节点将不包含任何内容,而Composite作为一种分支节点类。所以如果动用组合模式,我们就可以将上述内容衍化成下面这种模式。
所以包含肉菜单和茶菜单的类就是根节点,包含生肉和熟肉的肉菜单就是二级节点,其余都是叶子节点。那么这个改造就很清晰了。 我们用代码给出。
- //叶子节点
- public class MenuItem extends MenuComponent{
-
- private String name;
- private double price;
- private String description;
-
- public MenuItem(String name, double price, String description) {
- this.name = name;
- this.price = price;
- this.description = description;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public double getPrice() {
- return price;
- }
-
- public void setPrice(double price) {
- this.price = price;
- }
-
- public String getDescription() {
- return description;
- }
-
- @Override
- public void print() {
- System.out.println(toString());
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- @Override
- public String toString() {
- return "MenuItem{" +
- "name='" + name + '\'' +
- ", price=" + price +
- ", description='" + description + '\'' +
- '}';
- }
- }
-
- public abstract class MenuComponent {
-
- public void add(MenuComponent menuComponent){
-
- }
-
- public void remove(MenuComponent menuComponent){
-
- }
-
- public MenuComponent getChild(int i){
- return null;
- }
-
- abstract String getName();
-
- abstract String getDescription();
-
- abstract void print();
-
-
- }
-
-
- //分支节点
- public class Menu extends MenuComponent {
-
- private List<MenuComponent> list = new ArrayList<>();
- String name;
- String description;
-
- public Menu(String name, String description) {
- this.name = name;
- this.description = description;
- }
-
- @Override
- public void add(MenuComponent menuComponent) {
- list.add(menuComponent);
- }
-
- @Override
- public void remove(MenuComponent menuComponent) {
- list.remove(menuComponent);
- }
-
- @Override
- public MenuComponent getChild(int i) {
- return list.get(i);
- }
-
- @Override
- String getName() {
- return name;
- }
-
- @Override
- String getDescription() {
- return description;
- }
-
- @Override
- void print() {
- System.out.println("\n" + getName());
- System.out.println("," + getDescription());
- System.out.println("-------------------");
- for (MenuComponent m: list) {
- m.print();
- }
- }
-
- }
-
-
- public class Client {
-
- public static void main(String[] args) {
- MenuComponent root = new Menu("菜单","我是菜单");
- MenuComponent meat = new Menu("肉类菜单","我是肉类菜单");
- MenuComponent ripeMeat = new Menu("熟肉类菜单","我是熟肉类菜单");
- ripeMeat.add(new MenuItem("熟羊肉",100,"熟羊肉100元一斤"));
- ripeMeat.add(new MenuItem("熟猪肉",30,"熟猪肉30元一斤"));
- ripeMeat.add(new MenuItem("熟牛肉",90,"熟牛肉90元一斤"));
- MenuComponent rawMeat = new Menu("生肉类菜单","我是生肉类菜单");
- rawMeat.add(new MenuItem("生羊肉",50,"生羊肉50元一斤"));
- rawMeat.add(new MenuItem("生猪肉",15,"生猪肉15元一斤"));
- rawMeat.add(new MenuItem("生牛肉",45,"生牛肉45元一斤"));
- meat.add(rawMeat);
- meat.add(ripeMeat);
- MenuComponent tea = new Menu("茶菜单","我是茶菜单");
- MenuComponent milkTea = new Menu("奶茶菜单","我是奶茶菜单");
- milkTea.add(new MenuItem("珍珠奶茶",10,"珍珠奶茶10一杯"));
- milkTea.add(new MenuItem("红豆奶茶",11,"红豆奶茶11一杯"));
- milkTea.add(new MenuItem("椰果奶茶",12,"椰果奶茶12一杯"));
- MenuComponent fruitTea = new Menu("果茶菜单","我是果茶菜单");
- fruitTea.add(new MenuItem("草莓果茶",15,"草莓果茶15一杯"));
- fruitTea.add(new MenuItem("百香果果茶",15,"百香果茶15一杯"));
- fruitTea.add(new MenuItem("芒果果茶",15,"芒果果茶15一杯"));
- tea.add(milkTea);
- tea.add(fruitTea);
- root.add(meat);
- root.add(tea);
- root.print();
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。